Runtime completion support for constructors, for loops, and function expressions.
R=brianwilkerson@google.com
Change-Id: I3d33841b9386b6c9fb0e0f74946ca6fe9449581a
Reviewed-on: https://dart-review.googlesource.com/55911
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
index 646f9b6..3ccff5e 100644
--- a/pkg/analysis_server/lib/src/domains/execution/completion.dart
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -160,10 +160,7 @@
break;
}
if (statement is VariableDeclarationStatement) {
- for (var variable in statement.variables.variables) {
- VariableElement element = variable.element;
- locals[element.name] ??= element;
- }
+ _appendVariables(statement.variables);
}
}
} else if (node is ClassDeclaration) {
@@ -171,8 +168,19 @@
return;
} else if (node is CompilationUnit) {
return;
+ } else if (node is ConstructorDeclaration) {
+ _appendParameters(node.parameters);
} else if (node is FunctionDeclaration) {
_appendParameters(node.functionExpression.parameters);
+ } else if (node is FunctionExpression) {
+ _appendParameters(node.parameters);
+ } else if (node is ForEachStatement) {
+ LocalVariableElement element = node.loopVariable?.element;
+ if (element != null) {
+ locals[element.name] ??= element;
+ }
+ } else if (node is ForStatement) {
+ _appendVariables(node.variables);
} else if (node is MethodDeclaration) {
_appendParameters(node.parameters);
}
@@ -187,4 +195,13 @@
}
}
}
+
+ void _appendVariables(VariableDeclarationList variables) {
+ if (variables != null) {
+ for (var variable in variables.variables) {
+ VariableElement element = variable.element;
+ locals[element.name] ??= element;
+ }
+ }
+ }
}
diff --git a/pkg/analysis_server/test/src/domains/execution/completion_test.dart b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
index 986dc65..cd48659 100644
--- a/pkg/analysis_server/test/src/domains/execution/completion_test.dart
+++ b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
@@ -126,7 +126,7 @@
assertSuggested('toUpperCase');
}
- test_locals_nested() async {
+ test_locals_block_nested() async {
addContextFile(r'''
void main() {
var a = 0;
@@ -146,6 +146,47 @@
assertNotSuggested('c');
}
+ test_locals_for() async {
+ addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+ for (var a = 0, b = 0.0; a < 5; a++) {
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_locals_forEach() async {
+ addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+ for (var a in intItems) {
+ for (var b in doubleItems) {
+ // context line
+ }
+ }
+}sosol
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_parameters_constructor() async {
+ addContextFile(r'''
+class C {
+ C(int a, double b) {
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
test_parameters_function() async {
addContextFile(r'''
void main(int a, double b) {
@@ -185,6 +226,21 @@
assertSuggested('c', returnType: 'bool');
}
+ test_parameters_functionExpression() async {
+ addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+ intItems.forEach((a) {
+ doubleItems.forEach((b) {
+ // context line
+ });
+ });
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
test_parameters_method() async {
addContextFile(r'''
class C {