Chromium Code Reviews| Index: pkg/analysis_services/lib/src/completion/local_computer.dart |
| diff --git a/pkg/analysis_services/lib/src/completion/local_computer.dart b/pkg/analysis_services/lib/src/completion/local_computer.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3e4f696fa52a980dbd2ced1be80d949a883c1441 |
| --- /dev/null |
| +++ b/pkg/analysis_services/lib/src/completion/local_computer.dart |
| @@ -0,0 +1,171 @@ |
| +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +library services.completion.computer.dart.local; |
| + |
| +import 'dart:async'; |
| + |
| +import 'package:analysis_services/completion/completion_computer.dart'; |
| +import 'package:analysis_services/completion/completion_suggestion.dart'; |
| +import 'package:analyzer/src/generated/ast.dart'; |
| + |
| +/** |
| + * A computer for calculating class and top level variable |
|
scheglov
2014/08/10 21:45:14
You probably want to update the comment.
danrubel
2014/08/11 03:04:38
Done.
|
| + * `completion.getSuggestions` request results |
| + */ |
| +class LocalComputer extends CompletionComputer { |
| + |
| + @override |
| + bool computeFast(CompilationUnit unit, |
| + List<CompletionSuggestion> suggestions) { |
| + |
| + // Find the specific child [AstNode] that contains the completion offset |
| + // and collect suggestions starting with that node |
| + AstNode node = new NodeLocator.con1(offset).searchWithin(unit); |
| + if (node != null) { |
| + node.accept(new _LocalVisitor(offset, suggestions)); |
| + } |
| + |
| + // If the unit is not a part and does not reference any parts |
| + // then work is complete |
| + return !unit.directives.any( |
| + (d) => d is PartOfDirective || d is PartDirective); |
| + } |
| + |
| + @override |
| + Future<bool> computeFull(CompilationUnit unit, |
| + List<CompletionSuggestion> suggestions) { |
| + // TODO: implement computeFull |
| + // include results from part files that are included in the library |
| + return new Future.value(false); |
| + } |
| +} |
| + |
| +/** |
| + * A visitor for collecting suggestions from the most specific child [AstNode] |
| + * that contains the completion offset to the [CompilationUnit]. |
| + */ |
| +class _LocalVisitor extends GeneralizingAstVisitor<dynamic> { |
| + final int offset; |
| + final List<CompletionSuggestion> suggestions; |
| + |
| + _LocalVisitor(this.offset, this.suggestions); |
| + |
| + void addSuggestion(SimpleIdentifier id, CompletionSuggestionKind kind) { |
| + if (id != null) { |
| + String completion = id.name; |
| + if (completion != null && completion.length > 0) { |
| + suggestions.add( |
| + new CompletionSuggestion( |
| + kind, |
| + CompletionRelevance.DEFAULT, |
| + completion, |
| + completion.length, |
| + 0, |
| + false, |
| + false)); |
| + } |
| + } |
| + } |
| + |
| + void addSuggestions(VariableDeclarationList variables, |
| + CompletionSuggestionKind kind) { |
| + variables.variables.forEach((VariableDeclaration v) { |
|
scheglov
2014/08/10 21:45:14
Could you use full words, not just single characte
danrubel
2014/08/11 03:04:38
Good point. I have cleaned several places in this
|
| + addSuggestion(v.name, kind); |
| + }); |
| + } |
| + |
| + visitBlock(Block node) { |
| + node.statements.forEach((Statement s) { |
| + if (s.offset < offset) { |
|
scheglov
2014/08/10 21:45:14
Not quite so easy.
This code is valid and would b
danrubel
2014/08/11 03:04:38
Good point. https://codereview.chromium.org/459743
|
| + if (s is LabeledStatement) { |
| + s.labels.forEach((l) { |
| + l.label; |
|
scheglov
2014/08/10 21:45:15
I don't think this statement is useful.
danrubel
2014/08/11 03:04:38
Removed and commented out following line as it is
|
| + addSuggestion(l.label, CompletionSuggestionKind.LABEL); |
| + }); |
| + } else if (s is VariableDeclarationStatement) { |
| + addSuggestions(s.variables, CompletionSuggestionKind.VARIABLE); |
| + } |
| + } |
| + }); |
| + visitNode(node); |
| + } |
| + |
| + visitCatchClause(CatchClause node) { |
| + addSuggestion(node.exceptionParameter, CompletionSuggestionKind.PARAMETER); |
| + addSuggestion(node.stackTraceParameter, CompletionSuggestionKind.PARAMETER); |
| + visitNode(node); |
| + } |
| + |
| + visitClassDeclaration(ClassDeclaration node) { |
| + node.members.forEach((ClassMember m) { |
| + if (m is FieldDeclaration) { |
| + addSuggestions(m.fields, CompletionSuggestionKind.FIELD); |
| + } else if (m is MethodDeclaration) { |
| + addSuggestion(m.name, CompletionSuggestionKind.METHOD_NAME); |
| + } |
| + }); |
| + visitNode(node); |
| + } |
| + |
| + visitCompilationUnit(CompilationUnit node) { |
| + node.directives.forEach((Directive d) { |
| + if (d is ImportDirective) { |
| + addSuggestion(d.prefix, CompletionSuggestionKind.LIBRARY_PREFIX); |
| + } |
| + }); |
| + node.declarations.forEach((Declaration d) { |
| + if (d is ClassDeclaration) { |
| + addSuggestion(d.name, CompletionSuggestionKind.CLASS); |
| + } else if (d is EnumDeclaration) { |
| + addSuggestion(d.name, CompletionSuggestionKind.ENUM); |
| + } else if (d is FunctionDeclaration) { |
| + addSuggestion(d.name, CompletionSuggestionKind.FUNCTION); |
| + } else if (d is TopLevelVariableDeclaration) { |
| + addSuggestions( |
| + d.variables, |
| + CompletionSuggestionKind.TOP_LEVEL_VARIABLE); |
| + } else if (d is ClassTypeAlias) { |
| + addSuggestion(d.name, CompletionSuggestionKind.CLASS_ALIAS); |
| + } else if (d is FunctionTypeAlias) { |
| + addSuggestion(d.name, CompletionSuggestionKind.FUNCTION_TYPE_ALIAS); |
| + } |
| + }); |
| + } |
| + |
| + visitForEachStatement(ForEachStatement node) { |
| + addSuggestion(node.identifier, CompletionSuggestionKind.VARIABLE); |
| + visitNode(node); |
| + } |
| + |
| + visitForStatement(ForStatement node) { |
| + addSuggestions(node.variables, CompletionSuggestionKind.VARIABLE); |
| + visitNode(node); |
| + } |
| + |
| + visitFunctionDeclaration(FunctionDeclaration node) { |
| + addSuggestion(node.name, CompletionSuggestionKind.FUNCTION); |
| + visitNode(node); |
| + } |
| + |
| + visitFunctionExpression(FunctionExpression node) { |
| + node.parameters.parameters.forEach((FormalParameter p) { |
| + addSuggestion(p.identifier, CompletionSuggestionKind.PARAMETER); |
| + }); |
| + visitNode(node); |
| + } |
| + |
| + visitMethodDeclaration(MethodDeclaration node) { |
| + node.parameters.parameters.forEach((FormalParameter p) { |
| + if (p.identifier != null) { |
| + addSuggestion(p.identifier, CompletionSuggestionKind.PARAMETER); |
| + } |
| + }); |
| + visitNode(node); |
| + } |
| + |
| + visitNode(AstNode node) { |
| + node.parent.accept(this); |
| + } |
| +} |