public static CompletionResult GetCompletions(ScopeStatement scope, Node statement, Node expression, CompletionContext context) { if (!(expression is ErrorExpression)) { return(CompletionResult.Empty); } if (statement is AssignmentStatement assign && expression == assign.Right) { return(CompletionResult.Empty); } var tokens = context.TokenSource.Tokens.Reverse().ToArray(); var es = new ExpressionSource(context.TokenSource); string code; SourceLocation location; var items = Enumerable.Empty <CompletionItem>(); SourceSpan? applicableSpan; Expression e; var lastToken = tokens.FirstOrDefault(); if (lastToken.Value == null) { return(CompletionResult.Empty); } var nextLast = tokens.ElementAtOrDefault(1).Value?.Kind ?? TokenKind.EndOfFile; switch (lastToken.Value.Kind) { case TokenKind.Dot: code = es.ReadExpression(tokens.Skip(1)); applicableSpan = new SourceSpan(context.Location, context.Location); e = GetExpressionFromText(code, context, out var s1, out _); items = ExpressionCompletion.GetCompletionsFromMembers(e, s1, context); break; case TokenKind.KeywordDef when lastToken.Key.End < context.Position && scope is FunctionDefinition fd: { applicableSpan = new SourceSpan(context.Location, context.Location); location = context.TokenSource.GetTokenSpan(lastToken.Key).Start; if (FunctionDefinitionCompletion.TryGetCompletionsForOverride(fd, context, location, out var result)) { items = result.Completions; } break; } case TokenKind.Name when nextLast == TokenKind.Dot: code = es.ReadExpression(tokens.Skip(2)); applicableSpan = new SourceSpan(context.TokenSource.GetTokenSpan(lastToken.Key).Start, context.Location); e = GetExpressionFromText(code, context, out var s2, out _); items = ExpressionCompletion.GetCompletionsFromMembers(e, s2, context); break; case TokenKind.Name when nextLast == TokenKind.KeywordDef && scope is FunctionDefinition fd: { applicableSpan = new SourceSpan(context.TokenSource.GetTokenSpan(lastToken.Key).Start, context.Location); location = context.TokenSource.GetTokenSpan(tokens.ElementAt(1).Key).Start; if (FunctionDefinitionCompletion.TryGetCompletionsForOverride(fd, context, location, out var result)) { items = result.Completions; } break; } case TokenKind.KeywordFor: case TokenKind.KeywordAs: return(lastToken.Key.Start <= context.Position && context.Position <= lastToken.Key.End ? null : CompletionResult.Empty); case TokenKind.Error: return(null); default: return(CompletionResult.Empty); } return(new CompletionResult(items, applicableSpan)); }
public CompletionResult GetCompletions(IDocumentAnalysis analysis, SourceLocation location) { var context = new CompletionContext(analysis, location, _itemSource); ExpressionLocator.FindExpression(analysis.Ast, location, FindExpressionOptions.Complete, out var expression, out var statement, out var scope); switch (expression) { case MemberExpression me when me.Target != null && me.DotIndex > me.StartIndex && context.Position > me.DotIndex: return(new CompletionResult(ExpressionCompletion.GetCompletionsFromMembers(me.Target, scope, context))); case ConstantExpression ce1 when ce1.Value is double || ce1.Value is float: // no completions on integer ., the user is typing a float return(CompletionResult.Empty); case ConstantExpression ce2 when ce2.Value is string: case ConstantExpression ce3 when ce3.Value is AsciiString: // no completions in strings case null when context.Ast.IsInsideComment(context.Location): case null when context.Ast.IsInsideString(context.Location): return(CompletionResult.Empty); } if (statement is ImportStatement import) { var result = ImportCompletion.TryGetCompletions(import, context); if (result != null) { return(result); } } if (statement is FromImportStatement fromImport) { var result = ImportCompletion.GetCompletionsInFromImport(fromImport, context); if (result != null) { return(result); } } switch (statement) { case FunctionDefinition fd when FunctionDefinitionCompletion.TryGetCompletionsForOverride(fd, context, null, out var result): return(result); case FunctionDefinition fd when FunctionDefinitionCompletion.NoCompletions(fd, context.Position, context.Ast): return(CompletionResult.Empty); case ClassDefinition cd: if (!ClassDefinitionCompletion.NoCompletions(cd, context, out var addMetadataArg)) { var result = TopLevelCompletion.GetCompletions(statement, scope, context); return(addMetadataArg ? new CompletionResult(result.Completions.Append(CompletionItemSource.MetadataArg), result.ApplicableSpan) : result); } return(CompletionResult.Empty); case ForStatement forStatement when ForCompletion.TryGetCompletions(forStatement, context, out var result): return(result); case WithStatement withStatement when WithCompletion.TryGetCompletions(withStatement, context, out var result): return(result); case RaiseStatement raiseStatement when RaiseCompletion.TryGetCompletions(raiseStatement, context, out var result): return(result); case TryStatementHandler tryStatement when ExceptCompletion.TryGetCompletions(tryStatement, context, out var result): return(result); default: { var result = ErrorExpressionCompletion.GetCompletions(scope, statement, expression, context); if (result == null) { return(CompletionResult.Empty); } return(result == CompletionResult.Empty ? TopLevelCompletion.GetCompletions(statement, scope, context) : result); } } }