Compute 'executableElement' and 'parameterElement' in CompletionTarget.
R=brianwilkerson@google.com
Change-Id: I58904548a034cf927d9205bdbba3be9014c49328
Reviewed-on: https://dart-review.googlesource.com/c/92539
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index b53b2d2..4c4b692 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -32,52 +32,6 @@
}
/**
- * If the containing [node] is an argument list
- * or named expression in an argument list
- * then return the simple identifier for the method, constructor, or annotation
- * to which the argument list is associated
- */
-SimpleIdentifier _getTargetId(AstNode node) {
- if (node is NamedExpression) {
- return _getTargetId(node.parent);
- }
- if (node is ArgumentList) {
- AstNode parent = node.parent;
- if (parent is MethodInvocation) {
- return parent.methodName;
- }
- if (parent is InstanceCreationExpression) {
- ConstructorName constructorName = parent.constructorName;
- if (constructorName != null) {
- if (constructorName.name != null) {
- return constructorName.name;
- }
- Identifier typeName = constructorName.type.name;
- if (typeName is SimpleIdentifier) {
- return typeName;
- }
- if (typeName is PrefixedIdentifier) {
- return typeName.identifier;
- }
- }
- }
- if (parent is Annotation) {
- SimpleIdentifier name = parent.constructorName;
- if (name == null) {
- Identifier parentName = parent.name;
- if (parentName is SimpleIdentifier) {
- return parentName;
- } else if (parentName is PrefixedIdentifier) {
- return parentName.identifier;
- }
- }
- return name;
- }
- }
- return null;
-}
-
-/**
* Determine if the completion target is at the end of the list of arguments.
*/
bool _isAppendingToArgList(DartCompletionRequest request) {
@@ -193,35 +147,13 @@
this.request = request;
this.suggestions = <CompletionSuggestion>[];
- // Determine if the target is in an argument list
- // for a method or a constructor or an annotation
- SimpleIdentifier targetId = _getTargetId(request.target.containingNode);
- if (targetId == null) {
- return const <CompletionSuggestion>[];
- }
- Element elem = targetId.staticElement;
- if (elem == null) {
+ var executable = request.target.executableElement;
+ if (executable == null) {
return const <CompletionSuggestion>[];
}
- // Generate argument list suggestion based upon the type of element
- if (elem is ClassElement) {
- _addSuggestions(elem.unnamedConstructor?.parameters);
- return suggestions;
- }
- if (elem is ConstructorElement) {
- _addSuggestions(elem.parameters);
- return suggestions;
- }
- if (elem is FunctionElement) {
- _addSuggestions(elem.parameters);
- return suggestions;
- }
- if (elem is MethodElement) {
- _addSuggestions(elem.parameters);
- return suggestions;
- }
- return const <CompletionSuggestion>[];
+ _addSuggestions(executable.parameters);
+ return suggestions;
}
void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters,
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index fa3edbe..2449bb7 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -123,6 +123,19 @@
final int argIndex;
/**
+ * If the target is an argument in an [ArgumentList], then this is the
+ * invoked [ExecutableElement], otherwise this is `null`.
+ */
+ ExecutableElement _executableElement;
+
+ /**
+ * If the target is an argument in an [ArgumentList], then this is the
+ * corresponding [ParameterElement] in the invoked [ExecutableElement],
+ * otherwise this is `null`.
+ */
+ ParameterElement _parameterElement;
+
+ /**
* Compute the appropriate [CompletionTarget] for the given [offset] within
* the [compilationUnit].
*
@@ -250,6 +263,38 @@
_computeDroppedToken(containingNode, entity, offset);
/**
+ * If the target is an argument in an argument list, and the invocation is
+ * resolved, return the invoked [ExecutableElement].
+ */
+ ExecutableElement get executableElement {
+ if (_executableElement == null) {
+ var argumentList = containingNode;
+ if (argumentList is NamedExpression) {
+ argumentList = argumentList.parent;
+ }
+ if (argumentList is! ArgumentList) {
+ return null;
+ }
+
+ var invocation = argumentList.parent;
+
+ Element executable;
+ if (invocation is Annotation) {
+ executable = invocation.element;
+ } else if (invocation is InstanceCreationExpression) {
+ executable = invocation.constructorName.staticElement;
+ } else if (invocation is MethodInvocation) {
+ executable = invocation.methodName.staticElement;
+ }
+
+ if (executable is ExecutableElement) {
+ _executableElement = executable;
+ }
+ }
+ return _executableElement;
+ }
+
+ /**
* Return `true` if the [containingNode] is a cascade
* and the completion insertion is not between the two dots.
* For example, `..d^` and `..^d` are considered a cascade
@@ -267,6 +312,21 @@
}
/**
+ * If the target is an argument in an argument list, and the invocation is
+ * resolved, return the corresponding [ParameterElement].
+ */
+ ParameterElement get parameterElement {
+ if (_parameterElement == null) {
+ var executable = executableElement;
+ if (executable != null) {
+ _parameterElement = _getParameterElement(
+ executable.parameters, containingNode, argIndex);
+ }
+ }
+ return _parameterElement;
+ }
+
+ /**
* Return a source range that represents the region of text that should be
* replaced when a suggestion based on this target is selected, given that the
* completion was requested at the given [requestOffset].
@@ -328,63 +388,9 @@
/**
* Return `true` if the target is a functional argument in an argument list.
* The target [AstNode] hierarchy *must* be resolved for this to work.
- * See [maybeFunctionalArgument].
*/
bool isFunctionalArgument() {
- if (!maybeFunctionalArgument()) {
- return false;
- }
- AstNode parent = containingNode.parent;
- if (parent is ArgumentList) {
- parent = parent.parent;
- }
- if (parent is InstanceCreationExpression) {
- DartType instType = parent.staticType;
- 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, containingNode);
- }
- }
- } else if (parent is MethodInvocation) {
- SimpleIdentifier methodName = parent.methodName;
- if (methodName != null) {
- Element methodElem = methodName.staticElement;
- if (methodElem is MethodElement) {
- return _isFunctionalParameter(
- methodElem.parameters, argIndex, containingNode);
- } else if (methodElem is FunctionElement) {
- return _isFunctionalParameter(
- methodElem.parameters, argIndex, containingNode);
- }
- }
- }
- return false;
- }
-
- /**
- * Return `true` if the target maybe a functional argument in an argument list.
- * This is used in determining whether the target [AstNode] hierarchy
- * needs to be resolved so that [isFunctionalArgument] will work.
- */
- bool maybeFunctionalArgument() {
- if (argIndex != null) {
- if (containingNode is ArgumentList) {
- return true;
- }
- if (containingNode is NamedExpression) {
- if (containingNode.parent is ArgumentList) {
- return true;
- }
- }
- }
- return false;
+ return parameterElement?.type is FunctionType;
}
static int _computeArgIndex(AstNode containingNode, Object entity) {
@@ -501,6 +507,32 @@
}
/**
+ * Return the [ParameterElement] that corresponds to the given [argumentNode]
+ * at the given [argumentIndex].
+ */
+ static ParameterElement _getParameterElement(
+ List<ParameterElement> parameters,
+ AstNode argumentNode,
+ int argumentIndex,
+ ) {
+ if (argumentNode is NamedExpression) {
+ var name = argumentNode.name?.label?.name;
+ for (var parameter in parameters) {
+ if (parameter.name == name) {
+ return parameter;
+ }
+ }
+ return null;
+ }
+
+ if (argumentIndex < parameters.length) {
+ return parameters[argumentIndex];
+ }
+
+ return null;
+ }
+
+ /**
* Determine whether [node] could possibly be the [entity] for a
* [CompletionTarget] associated with the given [offset].
*/
@@ -554,27 +586,4 @@
return false;
}
}
-
- /**
- * Return `true` if the parameter is a functional parameter.
- */
- static bool _isFunctionalParameter(List<ParameterElement> parameters,
- int paramIndex, AstNode containingNode) {
- DartType paramType;
- if (paramIndex < parameters.length) {
- ParameterElement param = parameters[paramIndex];
- if (param.isNamed) {
- if (containingNode is NamedExpression) {
- String name = containingNode.name?.label?.name;
- param = parameters.firstWhere(
- (ParameterElement param) => param.isNamed && param.name == name,
- orElse: () => null);
- paramType = param?.type;
- }
- } else {
- paramType = param.type;
- }
- }
- return paramType is FunctionType;
- }
}
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index be5c5f8..8d38adf 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -4,10 +4,10 @@
import 'dart:async';
-import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/parser.dart' as analyzer;
-import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -16,605 +16,977 @@
main() {
defineReflectiveSuite(() {
+ defineReflectiveTests(ArgumentListCompletionTargetTest);
defineReflectiveTests(CompletionTargetTest);
});
}
@reflectiveTest
-class CompletionTargetTest extends AbstractContextTest {
- Source testSource;
- int completionOffset;
- CompletionTarget target;
+class ArgumentListCompletionTargetTest extends _Base {
+ test_Annotation_named() async {
+ await createTarget('''
+class Foo {
+ const Foo({int a, String b});
+}
- bool get usingFastaParser => analyzer.Parser.useFasta;
-
- Future<void> addTestSource(String content) async {
- expect(completionOffset, isNull, reason: 'Call addTestSource exactly once');
- completionOffset = content.indexOf('^');
- expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
- int nextOffset = content.indexOf('^', completionOffset + 1);
- expect(nextOffset, equals(-1), reason: 'too many ^');
- content = content.substring(0, completionOffset) +
- content.substring(completionOffset + 1);
- testSource = addSource('/test.dart', content);
- ResolvedUnitResult result = await driver.getResult(testSource.fullName);
- target = new CompletionTarget.forOffset(result.unit, completionOffset);
+@Foo(b: ^)
+main() {}
+''');
+ assertTarget(
+ '',
+ 'b: ',
+ argIndex: 0,
+ expectedExecutable: 'Foo.<init>: ({a: int, b: String}) → Foo',
+ expectedParameter: 'b: String',
+ );
}
- Future<void> assertTarget(entityText, nodeText,
- {int argIndex: null,
- bool isFunctionalArgument: false,
- String droppedToken}) async {
- void assertCommon() {
- expect(target.entity.toString(), entityText, reason: 'entity');
- expect(target.containingNode.toString(), nodeText,
- reason: 'containingNode');
- expect(target.argIndex, argIndex, reason: 'argIndex');
- expect(target.droppedToken?.toString(), droppedToken ?? isNull,
- reason: 'droppedToken');
- }
+ test_Annotation_positional() async {
+ await createTarget('''
+class Foo {
+ const Foo(int a);
+}
- // Assert with parsed unit
- assertCommon();
- ResolvedUnitResult result = await driver.getResult(testSource.fullName);
- target = new CompletionTarget.forOffset(result.unit, completionOffset);
- // Assert more with resolved unit
- assertCommon();
- expect(target.isFunctionalArgument(), isFunctionalArgument);
+@Foo(^)
+main() {}
+''');
+ assertTarget(
+ ')',
+ '()',
+ argIndex: 0,
+ expectedExecutable: 'Foo.<init>: (int) → Foo',
+ expectedParameter: 'a: int',
+ );
}
- test_ArgumentList_InstanceCreationExpression() async {
- // ArgumentList InstanceCreationExpression Block
- await addTestSource('main() {new Foo(^)}');
- await assertTarget(')', '()', argIndex: 0);
+ test_InstanceCreationExpression_explicitNew_unresolved() async {
+ await createTarget('''
+main() {
+ new Foo(^)
+}
+''');
+ assertTarget(')', '()', argIndex: 0);
}
- test_ArgumentList_InstanceCreationExpression2() async {
- // ArgumentList InstanceCreationExpression Block
- await addTestSource('main() {new Foo(a,^)}');
- await assertTarget(')', '(a)', argIndex: 1);
+ test_InstanceCreationExpression_generic_explicitTypeArgument() async {
+ await createTarget('''
+class Foo<T> {
+ Foo(T a, T b);
+}
+
+main() {
+ Foo<int>(^)
+}
+''');
+ assertTarget(
+ ')',
+ '()',
+ argIndex: 0,
+ expectedExecutable: 'Foo.<init>: (int, int) → Foo<int>',
+ expectedParameter: 'a: int',
+ );
}
- test_ArgumentList_InstanceCreationExpression_functionArg2() async {
- // ArgumentList InstanceCreationExpression Block
- await addTestSource('main() {new B(^)} class B{B(f()){}}');
- await assertTarget(')', '()', argIndex: 0, isFunctionalArgument: true);
+ test_InstanceCreationExpression_generic_inferredTypeArgument() async {
+ await createTarget('''
+class Foo<T> {
+ Foo(T a, T b);
+}
+
+main() {
+ Foo(false, ^)
+}
+''');
+ assertTarget(
+ ')',
+ '(false)',
+ argIndex: 1,
+ expectedExecutable: 'Foo.<init>: (bool, bool) → Foo<bool>',
+ expectedParameter: 'b: bool',
+ );
}
- test_ArgumentList_InstanceCreationExpression_functionArg3() async {
- // ArgumentList InstanceCreationExpression Block
- await addTestSource('main() {new B(1, f: ^)} class B{B(int i, {f()}){}}');
- await assertTarget('', 'f: ', argIndex: 1, isFunctionalArgument: true);
+ test_InstanceCreationExpression_named() async {
+ await createTarget('''
+class Foo {
+ Foo({int a, String b, double c});
+}
+
+main() {
+ Foo(b: ^)
+}
+''');
+ assertTarget(
+ '',
+ 'b: ',
+ argIndex: 0,
+ expectedExecutable: 'Foo.<init>: ({a: int, b: String, c: double}) → Foo',
+ expectedParameter: 'b: String',
+ );
}
- test_ArgumentList_MethodInvocation() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {foo(^)}');
- await assertTarget(')', '()', argIndex: 0);
+ test_InstanceCreationExpression_named_unresolved() async {
+ await createTarget('''
+class Foo {
+ Foo({int a});
+}
+
+main() {
+ Foo(b: ^)
+}
+''');
+ assertTarget(
+ '',
+ 'b: ',
+ argIndex: 0,
+ expectedExecutable: 'Foo.<init>: ({a: int}) → Foo',
+ );
}
- test_ArgumentList_MethodInvocation2() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {foo(^n)}');
- await assertTarget('n', '(n)', argIndex: 0);
+ test_InstanceCreationExpression_namedConstructor() async {
+ await createTarget('''
+class Foo {
+ Foo.named(int a, String b, double c);
+}
+
+main() {
+ Foo.named(0, ^)
+}
+''');
+ assertTarget(
+ ')',
+ '(0)',
+ argIndex: 1,
+ expectedExecutable: 'Foo.named: (int, String, double) → Foo',
+ expectedParameter: 'b: String',
+ );
}
- test_ArgumentList_MethodInvocation3() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {foo(n^)}');
- await assertTarget('n', '(n)', argIndex: 0);
+ test_InstanceCreationExpression_positional() async {
+ await createTarget('''
+class Foo {
+ Foo(int a);
+}
+
+main() {
+ Foo(^)
+}
+''');
+ assertTarget(
+ ')',
+ '()',
+ argIndex: 0,
+ expectedExecutable: 'Foo.<init>: (int) → Foo',
+ expectedParameter: 'a: int',
+ );
}
- test_ArgumentList_MethodInvocation3a() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {foo((n)^)}');
- await assertTarget(')', '((n))', argIndex: 0);
+ test_InstanceCreationExpression_positional_isFunctional() async {
+ await createTarget('''
+class Foo {
+ Foo(int Function(String) f);
+}
+
+main() {
+ Foo(^)
+}
+''');
+ assertTarget(
+ ')',
+ '()',
+ argIndex: 0,
+ expectedExecutable: 'Foo.<init>: ((String) → int) → Foo',
+ expectedParameter: 'f: (String) → int',
+ isFunctionalArgument: true,
+ );
}
- test_ArgumentList_MethodInvocation4() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {foo(n,^)}');
- await assertTarget(')', '(n)', argIndex: 1);
+ test_InstanceCreationExpression_positional_noParameter0() async {
+ await createTarget('''
+class Foo {}
+
+main() {
+ Foo(^)
+}
+''');
+ assertTarget(
+ ')',
+ '()',
+ argIndex: 0,
+ expectedExecutable: 'Foo.<init>: () → Foo',
+ );
}
- test_ArgumentList_MethodInvocation_functionArg() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {foo(^)} foo(f()) {}');
- await assertTarget(')', '()', argIndex: 0, isFunctionalArgument: true);
+ test_InstanceCreationExpression_positional_noParameter1() async {
+ await createTarget('''
+class Foo {}
+
+main() {
+ Foo(a, ^)
+}
+''');
+ assertTarget(
+ ')',
+ '(a)',
+ argIndex: 1,
+ expectedExecutable: 'Foo.<init>: () → Foo',
+ );
}
- test_ArgumentList_MethodInvocation_functionArg2() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {new B().boo(^)} class B{boo(f()){}}');
- await assertTarget(')', '()', argIndex: 0, isFunctionalArgument: true);
+ test_MethodInvocation_named() async {
+ await createTarget('''
+int foo({int a, String b, double c}) {}
+
+main() {
+ foo(b: ^)
+}
+''');
+ assertTarget(
+ '',
+ 'b: ',
+ argIndex: 0,
+ expectedExecutable: 'foo: ({a: int, b: String, c: double}) → int',
+ expectedParameter: 'b: String',
+ );
}
- test_ArgumentList_MethodInvocation_functionArg3() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {foo(f: ^)} foo({f()}) {}');
- await assertTarget('', 'f: ', argIndex: 0, isFunctionalArgument: true);
+ test_MethodInvocation_named_isFunctional() async {
+ await createTarget('''
+int foo({int Function(String) f}) {}
+
+main() {
+ foo(f: ^)
+}
+''');
+ assertTarget(
+ '',
+ 'f: ',
+ argIndex: 0,
+ expectedExecutable: 'foo: ({f: (String) → int}) → int',
+ expectedParameter: 'f: (String) → int',
+ isFunctionalArgument: true,
+ );
}
- test_ArgumentList_MethodInvocation_functionArg4() async {
- // ArgumentList MethodInvocation Block
- await addTestSource('main() {new B().boo(f: ^)} class B{boo({f()}){}}');
- await assertTarget('', 'f: ', argIndex: 0, isFunctionalArgument: true);
+ test_MethodInvocation_named_unresolved() async {
+ await createTarget('''
+int foo({int a}) {}
+
+main() {
+ foo(b: ^)
+}
+''');
+ assertTarget(
+ '',
+ 'b: ',
+ argIndex: 0,
+ expectedExecutable: 'foo: ({a: int}) → int',
+ );
}
+ test_MethodInvocation_positional2() async {
+ await createTarget('''
+int foo(int a, String b) {}
+
+main() {
+ foo(0, ^)
+}
+''');
+ assertTarget(
+ ')',
+ '(0)',
+ argIndex: 1,
+ expectedExecutable: 'foo: (int, String) → int',
+ expectedParameter: 'b: String',
+ );
+ }
+
+ test_MethodInvocation_positional_isFunctional() async {
+ await createTarget('''
+int foo(int Function(String) f) {}
+
+main() {
+ foo(^)
+}
+''');
+ assertTarget(
+ ')',
+ '()',
+ argIndex: 0,
+ expectedExecutable: 'foo: ((String) → int) → int',
+ expectedParameter: 'f: (String) → int',
+ isFunctionalArgument: true,
+ );
+ }
+
+ test_MethodInvocation_positional_isFunctional2() async {
+ await createTarget('''
+class C {
+ int foo(int Function(String) f) {}
+}
+
+main(C c) {
+ c.foo(^)
+}
+''');
+ assertTarget(
+ ')',
+ '()',
+ argIndex: 0,
+ expectedExecutable: 'C.foo: ((String) → int) → int',
+ expectedParameter: 'f: (String) → int',
+ isFunctionalArgument: true,
+ );
+ }
+
+ test_MethodInvocation_positional_withPrefix() async {
+ await createTarget('''
+int foo(int a, String b) {}
+
+main() {
+ foo(n^)
+}
+''');
+ assertTarget(
+ 'n',
+ '(n)',
+ argIndex: 0,
+ expectedExecutable: 'foo: (int, String) → int',
+ expectedParameter: 'a: int',
+ );
+ }
+
+ test_MethodInvocation_positional_withPrefix2() async {
+ await createTarget('''
+int foo(int a, String b) {}
+
+main() {
+ foo((n)^)
+}
+''');
+ assertTarget(
+ ')',
+ '((n))',
+ argIndex: 0,
+ expectedExecutable: 'foo: (int, String) → int',
+ expectedParameter: 'a: int',
+ );
+ }
+
+ test_MethodInvocation_positional_withSuffix() async {
+ await createTarget('''
+int foo(int a, String b) {}
+
+main() {
+ foo(^n)
+}
+''');
+ assertTarget(
+ 'n',
+ '(n)',
+ argIndex: 0,
+ expectedExecutable: 'foo: (int, String) → int',
+ expectedParameter: 'a: int',
+ );
+ }
+
+ test_MethodInvocation_unresolved() async {
+ await createTarget('''
+main() {
+ foo(^)
+}
+''');
+ assertTarget(')', '()', argIndex: 0);
+ }
+
+ test_not_ListLiteral() async {
+ await createTarget('''
+main() {
+ print([^]);
+}
+''');
+ expect(target.argIndex, isNull);
+ expect(target.executableElement, isNull);
+ expect(target.parameterElement, isNull);
+ }
+}
+
+@reflectiveTest
+class CompletionTargetTest extends _Base {
test_AsExpression_identifier() async {
// SimpleIdentifier TypeName AsExpression
- await addTestSource(
+ await createTarget(
'class A {var b; X _c; foo() {var a; (a^ as String).foo();}');
- await assertTarget('a as String', '(a as String)');
+ assertTarget('a as String', '(a as String)');
}
test_AsExpression_keyword() async {
// SimpleIdentifier TypeName AsExpression
- await addTestSource(
+ await createTarget(
'class A {var b; X _c; foo() {var a; (a ^as String).foo();}');
- await assertTarget('as', 'a as String');
+ assertTarget('as', 'a as String');
}
test_AsExpression_keyword2() async {
// SimpleIdentifier TypeName AsExpression
- await addTestSource(
+ await createTarget(
'class A {var b; X _c; foo() {var a; (a a^s String).foo();}');
- await assertTarget('as', 'a as String');
+ assertTarget('as', 'a as String');
}
test_AsExpression_keyword3() async {
// SimpleIdentifier TypeName AsExpression
- await addTestSource(
+ await createTarget(
'class A {var b; X _c; foo() {var a; (a as^ String).foo();}');
- await assertTarget('as', 'a as String');
+ assertTarget('as', 'a as String');
}
test_AsExpression_type() async {
// SimpleIdentifier TypeName AsExpression
- await addTestSource(
+ await createTarget(
'class A {var b; X _c; foo() {var a; (a as ^String).foo();}');
- await assertTarget('String', 'a as String');
+ assertTarget('String', 'a as String');
}
test_Block() async {
// Block
- await addTestSource('main() {^}');
- await assertTarget('}', '{}');
+ await createTarget('main() {^}');
+ assertTarget('}', '{}');
}
test_Block_keyword() async {
- await addTestSource(
+ await createTarget(
'class C { static C get instance => null; } main() {C.in^}');
- await assertTarget('in', 'C.in');
+ assertTarget('in', 'C.in');
}
test_Block_keyword2() async {
- await addTestSource(
+ await createTarget(
'class C { static C get instance => null; } main() {C.i^n}');
- await assertTarget('in', 'C.in');
+ assertTarget('in', 'C.in');
}
test_FormalParameter_partialType() async {
// SimpleIdentifier PrefixedIdentifier TypeName
- await addTestSource('foo(b.^ f) { }');
- await assertTarget('f', 'b.f');
+ await createTarget('foo(b.^ f) { }');
+ assertTarget('f', 'b.f');
}
test_FormalParameter_partialType2() async {
// SimpleIdentifier PrefixedIdentifier TypeName
- await addTestSource('foo(b.z^ f) { }');
- await assertTarget('z', 'b.z');
+ await createTarget('foo(b.z^ f) { }');
+ assertTarget('z', 'b.z');
}
test_FormalParameter_partialType3() async {
// SimpleIdentifier PrefixedIdentifier TypeName
- await addTestSource('foo(b.^) { }');
- await assertTarget('', 'b.');
+ await createTarget('foo(b.^) { }');
+ assertTarget('', 'b.');
}
test_FormalParameterList() async {
// Token FormalParameterList FunctionExpression
- await addTestSource('foo(^) { }');
- await assertTarget(')', '()');
+ await createTarget('foo(^) { }');
+ assertTarget(')', '()');
}
test_FunctionDeclaration_inLineComment() async {
// Comment CompilationUnit
- await addTestSource('''
+ await createTarget('''
// normal comment ^
zoo(z) { } String name;''');
- await assertTarget('// normal comment ', 'zoo(z) {} String name;');
+ assertTarget('// normal comment ', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_inLineComment2() async {
// Comment CompilationUnit
- await addTestSource('''
+ await createTarget('''
// normal ^comment
zoo(z) { } String name;''');
- await assertTarget('// normal comment', 'zoo(z) {} String name;');
+ assertTarget('// normal comment', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_inLineComment3() async {
// Comment CompilationUnit
- await addTestSource('''
+ await createTarget('''
// normal comment ^
// normal comment 2
zoo(z) { } String name;''');
- await assertTarget('// normal comment ', 'zoo(z) {} String name;');
+ assertTarget('// normal comment ', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_inLineComment4() async {
// Comment CompilationUnit
- await addTestSource('''
+ await createTarget('''
// normal comment
// normal comment 2^
zoo(z) { } String name;''');
- await assertTarget('// normal comment 2', 'zoo(z) {} String name;');
+ assertTarget('// normal comment 2', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_inLineDocComment() async {
// Comment FunctionDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
/// some dartdoc ^
zoo(z) { } String name;''');
- await assertTarget('/// some dartdoc ', '');
+ assertTarget('/// some dartdoc ', '');
expect(target.containingNode is Comment, isTrue);
expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
}
test_FunctionDeclaration_inLineDocComment2() async {
// Comment FunctionDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
/// some ^dartdoc
zoo(z) { } String name;''');
- await assertTarget('/// some dartdoc', '');
+ assertTarget('/// some dartdoc', '');
expect(target.containingNode is Comment, isTrue);
expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
}
test_FunctionDeclaration_inStarComment() async {
// Comment CompilationUnit
- await addTestSource('/* ^ */ zoo(z) {} String name;');
- await assertTarget('/* */', 'zoo(z) {} String name;');
+ await createTarget('/* ^ */ zoo(z) {} String name;');
+ assertTarget('/* */', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_inStarComment2() async {
// Comment CompilationUnit
- await addTestSource('/* *^/ zoo(z) {} String name;');
- await assertTarget('/* */', 'zoo(z) {} String name;');
+ await createTarget('/* *^/ zoo(z) {} String name;');
+ assertTarget('/* */', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_inStarDocComment() async {
// Comment FunctionDeclaration CompilationUnit
- await addTestSource('/** ^ */ zoo(z) { } String name;');
- await assertTarget('/** */', '');
+ await createTarget('/** ^ */ zoo(z) { } String name;');
+ assertTarget('/** */', '');
expect(target.containingNode is Comment, isTrue);
expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
}
test_FunctionDeclaration_inStarDocComment2() async {
// Comment FunctionDeclaration CompilationUnit
- await addTestSource('/** *^/ zoo(z) { } String name;');
- await assertTarget('/** */', '');
+ await createTarget('/** *^/ zoo(z) { } String name;');
+ assertTarget('/** */', '');
expect(target.containingNode is Comment, isTrue);
expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
}
test_FunctionDeclaration_returnType() async {
// CompilationUnit
- await addTestSource('^ zoo(z) { } String name;');
- await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+ await createTarget('^ zoo(z) { } String name;');
+ assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_returnType_afterLineComment() async {
// FunctionDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
// normal comment
^ zoo(z) {} String name;''');
- await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+ assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_returnType_afterLineComment2() async {
// FunctionDeclaration CompilationUnit
// TOD(danrubel) left align all test source
- await addTestSource('''
+ await createTarget('''
// normal comment
^ zoo(z) {} String name;''');
- await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+ assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_returnType_afterLineDocComment() async {
// SimpleIdentifier FunctionDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
/// some dartdoc
^ zoo(z) { } String name; ''');
- await assertTarget('zoo', 'zoo(z) {}');
+ assertTarget('zoo', 'zoo(z) {}');
}
test_FunctionDeclaration_returnType_afterLineDocComment2() async {
// SimpleIdentifier FunctionDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
/// some dartdoc
^ zoo(z) { } String name;''');
- await assertTarget('zoo', 'zoo(z) {}');
+ assertTarget('zoo', 'zoo(z) {}');
}
test_FunctionDeclaration_returnType_afterStarComment() async {
// CompilationUnit
- await addTestSource('/* */ ^ zoo(z) { } String name;');
- await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+ await createTarget('/* */ ^ zoo(z) { } String name;');
+ assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_returnType_afterStarComment2() async {
// CompilationUnit
- await addTestSource('/* */^ zoo(z) { } String name;');
- await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+ await createTarget('/* */^ zoo(z) { } String name;');
+ assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
}
test_FunctionDeclaration_returnType_afterStarDocComment() async {
// FunctionDeclaration CompilationUnit
- await addTestSource('/** */ ^ zoo(z) { } String name;');
- await assertTarget('zoo', 'zoo(z) {}');
+ await createTarget('/** */ ^ zoo(z) { } String name;');
+ assertTarget('zoo', 'zoo(z) {}');
}
test_FunctionDeclaration_returnType_afterStarDocComment2() async {
// FunctionDeclaration CompilationUnit
- await addTestSource('/** */^ zoo(z) { } String name;');
- await assertTarget('zoo', 'zoo(z) {}');
+ await createTarget('/** */^ zoo(z) { } String name;');
+ assertTarget('zoo', 'zoo(z) {}');
}
test_IfStatement_droppedToken() async {
// Comment ClassDeclaration CompilationUnit
- await addTestSource('main() { if (v i^) }');
+ await createTarget('main() { if (v i^) }');
if (usingFastaParser) {
- await assertTarget(')', 'if (v) ;', droppedToken: 'i');
+ assertTarget(')', 'if (v) ;', droppedToken: 'i');
} else {
- await assertTarget('i;', 'if (v) i;');
+ assertTarget('i;', 'if (v) i;');
}
}
test_InstanceCreationExpression_identifier() async {
// InstanceCreationExpression ExpressionStatement Block
- await addTestSource('class C {foo(){var f; {var x;} new ^C();}}');
- await assertTarget('C', 'new C()');
+ await createTarget('class C {foo(){var f; {var x;} new ^C();}}');
+ assertTarget('C', 'new C()');
}
test_InstanceCreationExpression_keyword() async {
// InstanceCreationExpression ExpressionStatement Block
- await addTestSource('class C {foo(){var f; {var x;} new^ }}');
- await assertTarget('new ();', '{var f; {var x;} new ();}');
+ await createTarget('class C {foo(){var f; {var x;} new^ }}');
+ assertTarget('new ();', '{var f; {var x;} new ();}');
}
test_InstanceCreationExpression_keyword2() async {
// InstanceCreationExpression ExpressionStatement Block
- await addTestSource('class C {foo(){var f; {var x;} new^ C();}}');
- await assertTarget('new C();', '{var f; {var x;} new C();}');
+ await createTarget('class C {foo(){var f; {var x;} new^ C();}}');
+ assertTarget('new C();', '{var f; {var x;} new C();}');
}
test_MapLiteralEntry() async {
// MapLiteralEntry MapLiteral VariableDeclaration
- await addTestSource('foo = {^');
+ await createTarget('foo = {^');
// fasta scanner inserts synthetic closing '}'
- await assertTarget('}', '{}');
+ assertTarget('}', '{}');
}
@failingTest
test_MapLiteralEntry1() async {
// MapLiteralEntry MapLiteral VariableDeclaration
- await addTestSource('foo = {T^');
- await assertTarget('T : ', '{T : }');
+ await createTarget('foo = {T^');
+ assertTarget('T : ', '{T : }');
}
test_MapLiteralEntry2() async {
// SimpleIdentifier MapLiteralEntry MapLiteral VariableDeclaration
- await addTestSource('foo = {7:T^};');
- await assertTarget('T', '7 : T');
+ await createTarget('foo = {7:T^};');
+ assertTarget('T', '7 : T');
}
test_MethodDeclaration_inLineComment() async {
// Comment ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
// normal comment ^
zoo(z) { } String name; }''');
- await assertTarget(
- '// normal comment ', 'class C2 {zoo(z) {} String name;}');
+ assertTarget('// normal comment ', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_inLineComment2() async {
// Comment ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
// normal ^comment
zoo(z) { } String name; }''');
- await assertTarget(
- '// normal comment', 'class C2 {zoo(z) {} String name;}');
+ assertTarget('// normal comment', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_inLineComment3() async {
// Comment ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
// normal comment ^
// normal comment 2
zoo(z) { } String name; }''');
- await assertTarget(
- '// normal comment ', 'class C2 {zoo(z) {} String name;}');
+ assertTarget('// normal comment ', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_inLineComment4() async {
// Comment ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
// normal comment
// normal comment 2^
zoo(z) { } String name; }''');
- await assertTarget(
- '// normal comment 2', 'class C2 {zoo(z) {} String name;}');
+ assertTarget('// normal comment 2', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_inLineDocComment() async {
// Comment MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
/// some dartdoc ^
zoo(z) { } String name; }''');
- await assertTarget('/// some dartdoc ', '');
+ assertTarget('/// some dartdoc ', '');
expect(target.containingNode is Comment, isTrue);
expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
}
test_MethodDeclaration_inLineDocComment2() async {
// Comment MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
/// some ^dartdoc
zoo(z) { } String name; }''');
- await assertTarget('/// some dartdoc', '');
+ assertTarget('/// some dartdoc', '');
expect(target.containingNode is Comment, isTrue);
expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
}
test_MethodDeclaration_inStarComment() async {
// Comment ClassDeclaration CompilationUnit
- await addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
- await assertTarget('/* */', 'class C2 {zoo(z) {} String name;}');
+ await createTarget('class C2 {/* ^ */ zoo(z) {} String name;}');
+ assertTarget('/* */', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_inStarComment2() async {
// Comment ClassDeclaration CompilationUnit
- await addTestSource('class C2 {/* *^/ zoo(z) {} String name;}');
- await assertTarget('/* */', 'class C2 {zoo(z) {} String name;}');
+ await createTarget('class C2 {/* *^/ zoo(z) {} String name;}');
+ assertTarget('/* */', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_inStarDocComment() async {
// Comment MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
- await assertTarget('/** */', '');
+ await createTarget('class C2 {/** ^ */ zoo(z) { } String name; }');
+ assertTarget('/** */', '');
expect(target.containingNode is Comment, isTrue);
expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
}
test_MethodDeclaration_inStarDocComment2() async {
// Comment MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('class C2 {/** *^/ zoo(z) { } String name; }');
- await assertTarget('/** */', '');
+ await createTarget('class C2 {/** *^/ zoo(z) { } String name; }');
+ assertTarget('/** */', '');
expect(target.containingNode is Comment, isTrue);
expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
}
test_MethodDeclaration_returnType() async {
// ClassDeclaration CompilationUnit
- await addTestSource('class C2 {^ zoo(z) { } String name; }');
- await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+ await createTarget('class C2 {^ zoo(z) { } String name; }');
+ assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_returnType_afterLineComment() async {
// MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
// normal comment
^ zoo(z) {} String name;}''');
- await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+ assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_returnType_afterLineComment2() async {
// MethodDeclaration ClassDeclaration CompilationUnit
// TOD(danrubel) left align all test source
- await addTestSource('''
+ await createTarget('''
class C2 {
// normal comment
^ zoo(z) {} String name;}''');
- await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+ assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_returnType_afterLineDocComment() async {
// SimpleIdentifier MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
/// some dartdoc
^ zoo(z) { } String name; }''');
- await assertTarget('zoo', 'zoo(z) {}');
+ assertTarget('zoo', 'zoo(z) {}');
}
test_MethodDeclaration_returnType_afterLineDocComment2() async {
// SimpleIdentifier MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('''
+ await createTarget('''
class C2 {
/// some dartdoc
^ zoo(z) { } String name; }''');
- await assertTarget('zoo', 'zoo(z) {}');
+ assertTarget('zoo', 'zoo(z) {}');
}
test_MethodDeclaration_returnType_afterStarComment() async {
// ClassDeclaration CompilationUnit
- await addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
- await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+ await createTarget('class C2 {/* */ ^ zoo(z) { } String name; }');
+ assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_returnType_afterStarComment2() async {
// ClassDeclaration CompilationUnit
- await addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
- await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+ await createTarget('class C2 {/* */^ zoo(z) { } String name; }');
+ assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
}
test_MethodDeclaration_returnType_afterStarDocComment() async {
// MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
- await assertTarget('zoo', 'zoo(z) {}');
+ await createTarget('class C2 {/** */ ^ zoo(z) { } String name; }');
+ assertTarget('zoo', 'zoo(z) {}');
}
test_MethodDeclaration_returnType_afterStarDocComment2() async {
// MethodDeclaration ClassDeclaration CompilationUnit
- await addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
- await assertTarget('zoo', 'zoo(z) {}');
+ await createTarget('class C2 {/** */^ zoo(z) { } String name; }');
+ assertTarget('zoo', 'zoo(z) {}');
}
test_SwitchStatement_c() async {
// Token('c') SwitchStatement
- await addTestSource('main() { switch(x) {c^} }');
- await assertTarget('}', 'switch (x) {}', droppedToken: 'c');
+ await createTarget('main() { switch(x) {c^} }');
+ assertTarget('}', 'switch (x) {}', droppedToken: 'c');
}
test_SwitchStatement_c2() async {
// Token('c') SwitchStatement
- await addTestSource('main() { switch(x) { c^ } }');
- await assertTarget('}', 'switch (x) {}', droppedToken: 'c');
+ await createTarget('main() { switch(x) { c^ } }');
+ assertTarget('}', 'switch (x) {}', droppedToken: 'c');
}
test_SwitchStatement_empty() async {
// SwitchStatement
- await addTestSource('main() { switch(x) {^} }');
- await assertTarget('}', 'switch (x) {}');
+ await createTarget('main() { switch(x) {^} }');
+ assertTarget('}', 'switch (x) {}');
}
test_SwitchStatement_empty2() async {
// SwitchStatement
- await addTestSource('main() { switch(x) { ^ } }');
- await assertTarget('}', 'switch (x) {}');
+ await createTarget('main() { switch(x) { ^ } }');
+ assertTarget('}', 'switch (x) {}');
}
test_TypeArgumentList() async {
// TypeName TypeArgumentList TypeName
- await addTestSource('main() { C<^> c; }');
- await assertTarget('', '<>');
+ await createTarget('main() { C<^> c; }');
+ assertTarget('', '<>');
}
test_TypeArgumentList2() async {
// TypeName TypeArgumentList TypeName
- await addTestSource('main() { C<C^> c; }');
- await assertTarget('C', '<C>');
+ await createTarget('main() { C<C^> c; }');
+ assertTarget('C', '<C>');
}
test_VariableDeclaration_lhs_identifier_after() async {
// VariableDeclaration VariableDeclarationList
- await addTestSource('main() {int b^ = 1;}');
- await assertTarget('b = 1', 'int b = 1');
+ await createTarget('main() {int b^ = 1;}');
+ assertTarget('b = 1', 'int b = 1');
}
test_VariableDeclaration_lhs_identifier_before() async {
// VariableDeclaration VariableDeclarationList
- await addTestSource('main() {int ^b = 1;}');
- await assertTarget('b = 1', 'int b = 1');
+ await createTarget('main() {int ^b = 1;}');
+ assertTarget('b = 1', 'int b = 1');
+ }
+}
+
+class _Base extends AbstractContextTest {
+ int offset;
+ CompletionTarget target;
+ FindElement findElement;
+
+ bool get usingFastaParser => analyzer.Parser.useFasta;
+
+ void assertTarget(
+ String entityText,
+ String nodeText, {
+ int argIndex: null,
+ String droppedToken,
+ bool isFunctionalArgument: false,
+ String expectedExecutable,
+ String expectedParameter,
+ }) {
+ expect(
+ target.entity.toString(),
+ entityText,
+ reason: 'entity',
+ );
+
+ expect(
+ target.containingNode.toString(),
+ nodeText,
+ reason: 'containingNode',
+ );
+
+ expect(
+ target.argIndex,
+ argIndex,
+ reason: 'argIndex',
+ );
+
+ expect(
+ target.droppedToken?.toString(),
+ droppedToken ?? isNull,
+ reason: 'droppedToken',
+ );
+
+ var actualExecutable = target.executableElement;
+ if (expectedExecutable == null) {
+ expect(actualExecutable, isNull);
+ } else {
+ expect(_executableStr(actualExecutable), expectedExecutable);
+ }
+
+ var actualParameter = target.parameterElement;
+ if (expectedParameter == null) {
+ expect(actualParameter, isNull);
+ } else {
+ expect(_parameterStr(actualParameter), expectedParameter);
+ }
+
+ expect(target.isFunctionalArgument(), isFunctionalArgument);
+ }
+
+ Future<void> createTarget(String content) async {
+ expect(offset, isNull, reason: 'Call createTarget exactly once');
+
+ offset = content.indexOf('^');
+ expect(offset, isNot(equals(-1)), reason: 'missing ^');
+
+ int nextOffset = content.indexOf('^', offset + 1);
+ expect(nextOffset, equals(-1), reason: 'too many ^');
+
+ content = content.substring(0, offset) + content.substring(offset + 1);
+
+ var path = convertPath('/home/test/lib/test.dart');
+ newFile(path, content: content);
+
+ var result = await driver.getResult(path);
+ findElement = FindElement(result.unit);
+
+ target = new CompletionTarget.forOffset(result.unit, offset);
+ }
+
+ static String _executableNameStr(ExecutableElement executable) {
+ var executableEnclosing = executable.enclosingElement;
+ if (executableEnclosing is CompilationUnitElement) {
+ return executable.name;
+ } else if (executable is ConstructorElement) {
+ if (executable.name == '') {
+ return '${executableEnclosing.name}.<init>';
+ } else {
+ return '${executableEnclosing.name}.${executable.name}';
+ }
+ } else if (executable is MethodElement) {
+ return '${executableEnclosing.name}.${executable.name}';
+ }
+ fail('Unexpected element: $executable');
+ }
+
+ static String _executableStr(ExecutableElement element) {
+ var executableStr = _executableNameStr(element);
+
+ return '$executableStr: ${element.type}';
+ }
+
+ static String _parameterStr(ParameterElement element) {
+ return '${element.name}: ${element.type}';
}
}