* Provides autocomplete suggestions for a specific node in the AST.
(
ast: Expression,
node: AnyNode,
expr: string,
cursorOffset: number,
context: SymbolsTable
)
| 110 | * Provides autocomplete suggestions for a specific node in the AST. |
| 111 | */ |
| 112 | private getSuggestionsForNode( |
| 113 | ast: Expression, |
| 114 | node: AnyNode, |
| 115 | expr: string, |
| 116 | cursorOffset: number, |
| 117 | context: SymbolsTable |
| 118 | ): AutocompleteSuggestions { |
| 119 | // When the node is an identifier look up the parent to get more context for the suggestions. |
| 120 | let inferNode: AnyNode = node; |
| 121 | if (node.type === 'Identifier' || node.type === 'Literal') { |
| 122 | const parent = findParentNode(node, ast); |
| 123 | inferNode = |
| 124 | parent && |
| 125 | !['ExpressionStatement', 'LogicalExpression', 'ConditionalExpression'].includes( |
| 126 | parent.type |
| 127 | ) |
| 128 | ? parent |
| 129 | : node; |
| 130 | } |
| 131 | |
| 132 | switch (inferNode.type) { |
| 133 | case 'Identifier': |
| 134 | case 'MemberExpression': { |
| 135 | const pathParts = this.getSymbolsPathPartsForMemberExpressionNode( |
| 136 | inferNode, |
| 137 | cursorOffset |
| 138 | ); |
| 139 | |
| 140 | // Fetch suggestions from the symbol table |
| 141 | const candidatesKeys = context.getMatchingSymbolsKeys(pathParts); |
| 142 | |
| 143 | const suggestions: AutocompleteSymbolSuggestion[] = []; |
| 144 | for (const candidate of candidatesKeys) { |
| 145 | const symbolInfo = context.getSymbolInfo(candidate); |
| 146 | if (symbolInfo) { |
| 147 | suggestions.push({ type: 'symbol', symbol: symbolInfo }); |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | if (suggestions.length === 1) { |
| 152 | const lastPathSegment = pathParts.at(-1)?.replace(/\*$/, ''); |
| 153 | |
| 154 | // Return no suggestion when the only match is an exact match of the |
| 155 | // typed token. |
| 156 | return lastPathSegment !== suggestions[0]?.symbol.definition.name |
| 157 | ? suggestions |
| 158 | : []; |
| 159 | } |
| 160 | |
| 161 | return suggestions; |
| 162 | } |
| 163 | case 'AssignmentExpression': |
| 164 | case 'UnaryExpression': { |
| 165 | // Provide suggestions for binary or logical operators based on the parsed operator |
| 166 | // of the partial expression (e.g suggest "==" when typing "=" (parsed as AssignmentExpression)). |
| 167 | return this.getOperatorSuggestionsForNode(ast, inferNode, cursorOffset, context); |
| 168 | } |
| 169 | case 'BinaryExpression': { |
no test coverage detected