Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: pkg/analysis_server/lib/src/services/completion/local_computer.dart

Issue 580623002: add element to completion suggestions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/lib/src/services/completion/local_computer.dart
diff --git a/pkg/analysis_server/lib/src/services/completion/local_computer.dart b/pkg/analysis_server/lib/src/services/completion/local_computer.dart
index 06f299c8df2bf018d386e4b5ce4f992c0ffca60c..84edaef9862aab3891d3a38aaaa02ba2f4193bc7 100644
--- a/pkg/analysis_server/lib/src/services/completion/local_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/local_computer.dart
@@ -6,9 +6,11 @@ library services.completion.computer.dart.local;
import 'dart:async';
-import 'package:analysis_server/src/protocol.dart';
+import 'package:analysis_server/src/protocol.dart' as protocol show Element, ElementKind;
+import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind;
import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
/**
* A computer for calculating `completion.getSuggestions` request results
@@ -43,6 +45,16 @@ class LocalComputer extends DartCompletionComputer {
* that contains the completion offset to the [CompilationUnit].
*/
class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
+ static const DYNAMIC = 'dynamic';
+
+ static final TypeName NO_RETURN_TYPE = new TypeName(
+ new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)),
+ null);
+
+ static final TypeName STACKTRACE_TYPE = new TypeName(
+ new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, 'StackTrace', 0)),
+ null);
+
final DartCompletionRequest request;
_LocalVisitor(this.request);
@@ -56,15 +68,11 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
// _addSuggestion(label.label, CompletionSuggestionKind.LABEL);
});
} else if (stmt is VariableDeclarationStatement) {
- VariableDeclarationList varList = stmt.variables;
+ var varList = stmt.variables;
if (varList != null) {
varList.variables.forEach((VariableDeclaration varDecl) {
if (varDecl.end < request.offset) {
- _addSuggestion(
- varDecl.name,
- CompletionSuggestionKind.LOCAL_VARIABLE,
- varList.type,
- null);
+ _addLocalVarSuggestion(varDecl.name, varList.type);
}
});
}
@@ -76,17 +84,9 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
@override
visitCatchClause(CatchClause node) {
- _addSuggestion(
- node.exceptionParameter,
- CompletionSuggestionKind.PARAMETER,
- node.exceptionType,
- null);
- // TODO (danrubel) add stack trace types
- _addSuggestion(
- node.stackTraceParameter,
- CompletionSuggestionKind.PARAMETER,
- null,
- null);
+ _addParamSuggestion(node.exceptionParameter, node.exceptionType);
+ CompletionSuggestion suggestion =
+ _addParamSuggestion(node.stackTraceParameter, STACKTRACE_TYPE);
visitNode(node);
}
@@ -94,16 +94,9 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
visitClassDeclaration(ClassDeclaration node) {
node.members.forEach((ClassMember classMbr) {
if (classMbr is FieldDeclaration) {
- _addVarListSuggestions(
- classMbr.fields,
- CompletionSuggestionKind.FIELD,
- node);
+ _addFieldSuggestions(node, classMbr);
} else if (classMbr is MethodDeclaration) {
- _addSuggestion(
- classMbr.name,
- CompletionSuggestionKind.METHOD_NAME,
- classMbr.returnType,
- node);
+ _addMethodSuggestion(node, classMbr);
}
});
visitNode(node);
@@ -113,33 +106,18 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
visitCompilationUnit(CompilationUnit node) {
node.directives.forEach((Directive directive) {
if (directive is ImportDirective) {
- _addSuggestion(
- directive.prefix,
- CompletionSuggestionKind.LIBRARY_PREFIX,
- null,
- null);
+ _addLibraryPrefixSuggestion(directive);
}
});
node.declarations.forEach((Declaration declaration) {
if (declaration is ClassDeclaration) {
- _addSuggestion(
- declaration.name,
- CompletionSuggestionKind.CLASS,
- null,
- null);
+ _addClassSuggestion(declaration);
} else if (declaration is EnumDeclaration) {
// _addSuggestion(d.name, CompletionSuggestionKind.ENUM);
} else if (declaration is FunctionDeclaration) {
- _addSuggestion(
- declaration.name,
- CompletionSuggestionKind.FUNCTION,
- declaration.returnType,
- null);
+ _addFunctionSuggestion(declaration);
} else if (declaration is TopLevelVariableDeclaration) {
- _addVarListSuggestions(
- declaration.variables,
- CompletionSuggestionKind.TOP_LEVEL_VARIABLE,
- null);
+ _addTopLevelVarSuggestions(declaration.variables);
} else if (declaration is ClassTypeAlias) {
_addSuggestion(
declaration.name,
@@ -171,21 +149,28 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
@override
visitForEachStatement(ForEachStatement node) {
- // TODO (danrubel) supply type of local variable
- _addSuggestion(
- node.identifier,
- CompletionSuggestionKind.LOCAL_VARIABLE,
- null,
- null);
+ SimpleIdentifier id;
+ TypeName type;
+ DeclaredIdentifier loopVar = node.loopVariable;
+ if (loopVar != null) {
+ id = loopVar.identifier;
+ type = loopVar.type;
+ } else {
+ id = node.identifier;
+ type = null;
+ }
+ _addLocalVarSuggestion(id, type);
visitNode(node);
}
@override
visitForStatement(ForStatement node) {
- _addVarListSuggestions(
- node.variables,
- CompletionSuggestionKind.LOCAL_VARIABLE,
- null);
+ var varList = node.variables;
+ if (varList != null) {
+ varList.variables.forEach((VariableDeclaration varDecl) {
+ _addLocalVarSuggestion(varDecl.name, varList.type);
+ });
+ }
visitNode(node);
}
@@ -224,6 +209,106 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
}
}
+ void _addClassSuggestion(ClassDeclaration declaration) {
+ CompletionSuggestion suggestion =
+ _addSuggestion(declaration.name, CompletionSuggestionKind.CLASS, null, null);
+ if (suggestion != null) {
+ suggestion.element = _createElement(
+ protocol.ElementKind.CLASS,
+ declaration.name,
+ NO_RETURN_TYPE,
+ declaration.isAbstract,
+ _isDeprecated(declaration.metadata));
+ }
+ }
+
+ void _addFieldSuggestions(ClassDeclaration node, FieldDeclaration fieldDecl) {
+ bool isDeprecated = _isDeprecated(fieldDecl.metadata);
+ fieldDecl.fields.variables.forEach((VariableDeclaration varDecl) {
+ CompletionSuggestion suggestion = _addSuggestion(
+ varDecl.name,
+ CompletionSuggestionKind.GETTER,
+ fieldDecl.fields.type,
+ node);
+ if (suggestion != null) {
+ suggestion.element = _createElement(
+ protocol.ElementKind.GETTER,
+ varDecl.name,
+ fieldDecl.fields.type,
+ false,
+ isDeprecated || _isDeprecated(varDecl.metadata));
+ }
+ });
+ }
+
+ void _addFunctionSuggestion(FunctionDeclaration declaration) {
+ CompletionSuggestion suggestion = _addSuggestion(
+ declaration.name,
+ CompletionSuggestionKind.FUNCTION,
+ declaration.returnType,
+ null);
+ if (suggestion != null) {
+ suggestion.element = _createElement(
+ protocol.ElementKind.FUNCTION,
+ declaration.name,
+ declaration.returnType,
+ false,
+ _isDeprecated(declaration.metadata));
+ }
+ }
+
+ void _addLibraryPrefixSuggestion(ImportDirective directive) {
+ CompletionSuggestion suggestion = _addSuggestion(
+ directive.prefix,
+ CompletionSuggestionKind.LIBRARY_PREFIX,
+ null,
+ null);
+ if (suggestion != null) {
+ suggestion.element = _createElement(
+ protocol.ElementKind.LIBRARY,
+ directive.prefix,
+ NO_RETURN_TYPE,
+ false,
+ false);
+ }
+ }
+
+ void _addLocalVarSuggestion(SimpleIdentifier id, TypeName returnType) {
+ CompletionSuggestion suggestion =
+ _addSuggestion(id, CompletionSuggestionKind.LOCAL_VARIABLE, returnType, null);
+ if (suggestion != null) {
+ suggestion.element = _createElement(
+ protocol.ElementKind.LOCAL_VARIABLE,
+ id,
+ returnType,
+ false,
+ false);
+ }
+ }
+
+ void _addMethodSuggestion(ClassDeclaration node, MethodDeclaration classMbr) {
+ protocol.ElementKind kind;
+ CompletionSuggestionKind csKind;
+ if (classMbr.isGetter) {
+ kind = protocol.ElementKind.GETTER;
+ csKind = CompletionSuggestionKind.GETTER;
+ } else if (classMbr.isSetter) {
+ kind = protocol.ElementKind.SETTER;
+ csKind = CompletionSuggestionKind.SETTER;
+ } else {
+ kind = protocol.ElementKind.METHOD;
+ csKind = CompletionSuggestionKind.METHOD;
+ }
+ CompletionSuggestion suggestion =
+ _addSuggestion(classMbr.name, csKind, classMbr.returnType, node);
+ suggestion.element = _createElement(
+ kind,
+ classMbr.name,
+ classMbr.returnType,
+ classMbr.isAbstract,
+ _isDeprecated(classMbr.metadata));
+ }
+
void _addParamListSuggestions(FormalParameterList paramList) {
if (paramList != null) {
paramList.parameters.forEach((FormalParameter param) {
@@ -241,17 +326,24 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
} else if (normalParam is SimpleFormalParameter) {
type = normalParam.type;
}
- _addSuggestion(
- param.identifier,
- CompletionSuggestionKind.PARAMETER,
- type,
- null);
+ _addParamSuggestion(param.identifier, type);
});
}
}
- void _addSuggestion(SimpleIdentifier id, CompletionSuggestionKind kind,
- TypeName typeName, ClassDeclaration classDecl) {
+ CompletionSuggestion _addParamSuggestion(SimpleIdentifier identifier,
+ TypeName type) {
+ CompletionSuggestion suggestion =
+ _addSuggestion(identifier, CompletionSuggestionKind.PARAMETER, type, null);
+ if (suggestion != null) {
+ suggestion.element =
+ _createElement(protocol.ElementKind.PARAMETER, identifier, type, false, false);
+ }
+ return suggestion;
+ }
+
+ CompletionSuggestion _addSuggestion(SimpleIdentifier id,
+ CompletionSuggestionKind kind, TypeName typeName, ClassDeclaration classDecl) {
if (id != null) {
String completion = id.name;
if (completion != null && completion.length > 0) {
@@ -282,14 +374,80 @@ class _LocalVisitor extends GeneralizingAstVisitor<dynamic> {
}
}
request.suggestions.add(suggestion);
+ return suggestion;
}
}
+ return null;
}
- void _addVarListSuggestions(VariableDeclarationList variables,
- CompletionSuggestionKind kind, ClassDeclaration classDecl) {
- variables.variables.forEach((VariableDeclaration varDecl) {
- _addSuggestion(varDecl.name, kind, variables.type, classDecl);
- });
+ void _addTopLevelVarSuggestions(VariableDeclarationList varList) {
+ if (varList != null) {
+ bool isDeprecated = _isDeprecated(varList.metadata);
+ varList.variables.forEach((VariableDeclaration varDecl) {
+ CompletionSuggestion suggestion = _addSuggestion(
+ varDecl.name,
+ CompletionSuggestionKind.TOP_LEVEL_VARIABLE,
+ varList.type,
+ null);
+ if (suggestion != null) {
+ suggestion.element = _createElement(
+ protocol.ElementKind.TOP_LEVEL_VARIABLE,
+ varDecl.name,
+ varList.type,
+ false,
+ isDeprecated || _isDeprecated(varDecl.metadata));
+ }
+ });
+ }
+ }
+
+ /**
+ * Create a new protocol Element for inclusion in a completion suggestion.
+ */
+ protocol.Element _createElement(protocol.ElementKind kind,
+ SimpleIdentifier id, TypeName returnType, bool isAbstract, bool isDeprecated) {
+ String name = id.name;
+ int flags = protocol.Element.makeFlags(
+ isAbstract: isAbstract,
+ isDeprecated: isDeprecated,
+ isPrivate: Identifier.isPrivateName(name));
+ return new protocol.Element(
+ kind,
+ name,
+ flags,
+ returnType: _nameForType(returnType));
+ }
+
+ /**
+ * Return `true` if the @deprecated annotation is present
+ */
+ bool _isDeprecated(NodeList<Annotation> metadata) =>
+ metadata != null &&
+ metadata.any(
+ (Annotation a) => a.name is SimpleIdentifier && a.name.name == 'deprecated');
+
+ /**
+ * Return the name for the given type.
+ */
+ String _nameForType(TypeName type) {
+ if (type == NO_RETURN_TYPE) {
+ return null;
+ }
+ if (type == null) {
+ return DYNAMIC;
+ }
+ Identifier id = type.name;
+ if (id == null) {
+ return DYNAMIC;
+ }
+ String name = id.name;
+ if (name == null || name.length <= 0) {
+ return DYNAMIC;
+ }
+ TypeArgumentList typeArgs = type.typeArguments;
+ if (typeArgs != null) {
+ //TODO (danrubel) include type arguments
+ }
+ return name;
}
}

Powered by Google App Engine
This is Rietveld 408576698