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

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

Issue 977223003: When target requires a function, propose a function reference, not an invocation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge and remove unnecessary statement Created 5 years, 10 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/completion_target.dart
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_target.dart b/pkg/analysis_server/lib/src/services/completion/completion_target.dart
index 3ae98ba26d45eade0e3e4f17ca7191804e079cef..47b88638e53acacc874321dda76f6d23a58a3040 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_target.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_target.dart
@@ -1,5 +1,23 @@
import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+int _computeArgIndex(AstNode containingNode, Object entity) {
+ var argList = containingNode;
+ if (argList is ArgumentList) {
+ NodeList<Expression> args = argList.arguments;
+ for (int index = 0; index < args.length; ++index) {
+ if (entity == args[index]) {
+ return index;
+ }
+ }
+ if (args.isEmpty) {
+ return 0;
+ }
+ }
+ return null;
+}
/**
* A CompletionTarget represents an edge in the parse tree which connects an
@@ -79,6 +97,12 @@ class CompletionTarget {
final Object entity;
/**
+ * If the target is an argument in an [ArgumentList], then this is the index
+ * of the argument in the list, otherwise this is `null`.
+ */
+ final int argIndex;
+
+ /**
* Compute the appropriate [CompletionTarget] for the given [offset] within
* the [compilationUnit].
*/
@@ -164,7 +188,50 @@ class CompletionTarget {
* Create a [CompletionTarget] holding the given [containingNode] and
* [entity].
*/
- CompletionTarget._(this.containingNode, this.entity);
+ CompletionTarget._(AstNode containingNode, Object entity)
+ : this.containingNode = containingNode,
+ this.entity = entity,
+ this.argIndex = _computeArgIndex(containingNode, entity);
+
+ /**
+ * Return `true` if the target is a functional argument in an argument list.
+ * The target [AstNode] hierarchy *must* be resolved for this to work.
+ */
+ bool isFunctionalArgument() {
+ if (argIndex == null) {
+ return false;
+ }
+ AstNode argList = containingNode;
+ if (argList is! ArgumentList) {
+ return false;
+ }
+ AstNode parent = argList.parent;
+ if (parent is InstanceCreationExpression) {
+ DartType instType = parent.bestType;
+ if (instType != null) {
+ Element intTypeElem = instType.element;
+ if (intTypeElem is ClassElement) {
+ SimpleIdentifier constructorName = parent.constructorName.name;
+ ConstructorElement constructor = constructorName != null
+ ? intTypeElem.getNamedConstructor(constructorName.name)
+ : intTypeElem.unnamedConstructor;
+ return constructor != null &&
+ _isFunctionalParameter(constructor.parameters, argIndex);
+ }
+ }
+ } else if (parent is MethodInvocation) {
+ SimpleIdentifier methodName = parent.methodName;
+ if (methodName != null) {
+ Element methodElem = methodName.bestElement;
+ if (methodElem is MethodElement) {
+ return _isFunctionalParameter(methodElem.parameters, argIndex);
+ } else if (methodElem is FunctionElement) {
+ return _isFunctionalParameter(methodElem.parameters, argIndex);
+ }
+ }
+ }
+ return false;
+ }
/**
* Determine whether [node] could possibly be the [entity] for a
@@ -205,4 +272,22 @@ class CompletionTarget {
return false;
}
}
+
+ /**
+ * Return `true` if the parameter is a functional parameter.
+ */
+ static bool _isFunctionalParameter(
+ List<ParameterElement> parameters, int paramIndex) {
+ if (paramIndex < parameters.length) {
+ ParameterElement param = parameters[paramIndex];
+ DartType paramType = param.type;
+ if (param.parameterKind == ParameterKind.NAMED) {
+ // TODO(danrubel) handle named parameters
+ return false;
+ } else {
+ return paramType is FunctionType || paramType is FunctionTypeAlias;
+ }
+ }
+ return false;
+ }
}

Powered by Google App Engine
This is Rietveld 408576698