getCompletionContext method
Get the token boundaries at the cursor position for inline completion
Implementation
CompletionContext? getCompletionContext(String input, int cursorOffset) {
if (cursorOffset == -1) {
cursorOffset = input.length;
}
var result = parser.parsePrefix(input, typeChecker: typeChecker);
if (!result.success || result.value == null) {
return null;
}
final node = _findNodeAt(result.value!, cursorOffset);
if (node == null) {
return null;
}
// Determine what part of the node is being completed
int tokenStart;
int tokenEnd;
String tokenType;
if (node is MemberExpression) {
// Completing the property name after the dot
// e.g., "user.na|me" - we want token boundaries of "name"
tokenStart = node.property.start;
tokenEnd = node.property.end;
tokenType = "property";
}
else if (node is Variable) {
// Completing a variable name
// e.g., "us|er" - we want token boundaries of "user"
tokenStart = node.identifier.start;
tokenEnd = node.identifier.end;
tokenType = "variable";
}
else if (node is Identifier) {
// Direct identifier completion
tokenStart = node.start;
tokenEnd = node.end;
tokenType = "identifier";
}
else if (node is CallExpression) {
// Check if we're on the callee (function name)
if (cursorOffset >= node.callee.start && cursorOffset <= node.callee.end) {
// Recursively get context for the callee
final calleeContext = _getNodeContext(node.callee, cursorOffset);
if (calleeContext != null) return calleeContext;
}
// Otherwise we're in arguments
tokenStart = node.start;
tokenEnd = node.end;
tokenType = "call";
}
else {
// Fallback to the node boundaries
tokenStart = node.start;
tokenEnd = node.end;
tokenType = node.runtimeType.toString().toLowerCase();
}
return CompletionContext(
tokenStart: tokenStart,
tokenEnd: tokenEnd,
tokenType: tokenType,
node: node,
);
}