mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 21:21:32 +00:00
Tests for completion with nested blocks, functions, and methods.
R=brianwilkerson@google.com Change-Id: I050aaa2f80a3374fd92587a0b8461bc170078bd8 Reviewed-on: https://dart-review.googlesource.com/55903 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
353ddbaea1
commit
7a90ed9b88
|
@ -57,6 +57,7 @@ class RuntimeCompletionComputer {
|
|||
var contextDir = pathContext.dirname(contextFile);
|
||||
var targetPath = pathContext.join(contextDir, '_runtimeCompletion.dart');
|
||||
|
||||
// TODO(scheglov) Use variables.
|
||||
await _initContext();
|
||||
|
||||
String baseTargetCode = r'''
|
||||
|
@ -156,23 +157,15 @@ class _Context {
|
|||
}
|
||||
|
||||
void _appendLocals(AstNode node) {
|
||||
void appendParameters(FormalParameterList parameters) {
|
||||
if (parameters != null) {
|
||||
for (var parameter in parameters.parameters) {
|
||||
VariableElement element = parameter.element;
|
||||
locals[element.name] ??= element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node is Block) {
|
||||
for (var statement in node.statements) {
|
||||
if (statement.offset > contextOffset) {
|
||||
break;
|
||||
}
|
||||
if (statement is VariableDeclarationStatement) {
|
||||
for (var variable in statement.variables.variables) {
|
||||
VariableElement element = variable.element;
|
||||
if (element.nameOffset < contextOffset) {
|
||||
locals[element.name] ??= element;
|
||||
}
|
||||
locals[element.name] ??= element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -182,14 +175,19 @@ class _Context {
|
|||
} else if (node is CompilationUnit) {
|
||||
return;
|
||||
} else if (node is FunctionDeclaration) {
|
||||
// TODO(scheglov) test
|
||||
appendParameters(node.functionExpression.parameters);
|
||||
_appendParameters(node.functionExpression.parameters);
|
||||
} else if (node is MethodDeclaration) {
|
||||
// TODO(scheglov) test
|
||||
appendParameters(node.parameters);
|
||||
} else {
|
||||
_appendLocals(node.parent);
|
||||
_appendParameters(node.parameters);
|
||||
}
|
||||
_appendLocals(node.parent);
|
||||
}
|
||||
|
||||
void _appendParameters(FormalParameterList parameters) {
|
||||
if (parameters != null) {
|
||||
for (var parameter in parameters.parameters) {
|
||||
VariableElement element = parameter.element;
|
||||
locals[element.name] ??= element;
|
||||
}
|
||||
}
|
||||
// TODO(scheglov) support method/function/class
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,14 +33,21 @@ class RuntimeCompletionComputerTest extends AbstractContextTest {
|
|||
reason: "Not found '// context line'.");
|
||||
}
|
||||
|
||||
void assertSuggest(String completion) {
|
||||
expect(result.suggestions, isNotNull);
|
||||
for (var suggestion in result.suggestions) {
|
||||
if (suggestion.completion == completion) {
|
||||
return;
|
||||
}
|
||||
void assertNotSuggested(String completion) {
|
||||
CompletionSuggestion suggestion = getSuggest(completion);
|
||||
if (suggestion != null) {
|
||||
failedCompletion('unexpected $completion');
|
||||
}
|
||||
}
|
||||
|
||||
void assertSuggested(String completion, {String returnType}) {
|
||||
CompletionSuggestion suggestion = getSuggest(completion);
|
||||
if (suggestion == null) {
|
||||
failedCompletion('expected $completion');
|
||||
}
|
||||
if (returnType != null) {
|
||||
expect(suggestion.returnType, returnType);
|
||||
}
|
||||
failedCompletion('expected $completion');
|
||||
}
|
||||
|
||||
Future<void> computeCompletion(
|
||||
|
@ -78,6 +85,16 @@ class RuntimeCompletionComputerTest extends AbstractContextTest {
|
|||
fail(sb.toString());
|
||||
}
|
||||
|
||||
CompletionSuggestion getSuggest(String completion) {
|
||||
expect(result.suggestions, isNotNull);
|
||||
for (var suggestion in result.suggestions) {
|
||||
if (suggestion.completion == completion) {
|
||||
return suggestion;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
test_locals_block() async {
|
||||
addContextFile(r'''
|
||||
class A {
|
||||
|
@ -90,12 +107,12 @@ void contextFunction() {
|
|||
}
|
||||
''');
|
||||
await computeCompletion('a.^');
|
||||
assertSuggest('foo');
|
||||
assertSuggested('foo');
|
||||
|
||||
// There was an issue with cleaning up
|
||||
// Check that the second time it works too.
|
||||
await computeCompletion('a.^');
|
||||
assertSuggest('foo');
|
||||
assertSuggested('foo');
|
||||
}
|
||||
|
||||
test_locals_block_codeWithClosure() async {
|
||||
|
@ -106,6 +123,94 @@ main() {
|
|||
}
|
||||
''');
|
||||
await computeCompletion('items.forEach((e) => e.^)');
|
||||
assertSuggest('toUpperCase');
|
||||
assertSuggested('toUpperCase');
|
||||
}
|
||||
|
||||
test_locals_nested() async {
|
||||
addContextFile(r'''
|
||||
void main() {
|
||||
var a = 0;
|
||||
var b = 0.0;
|
||||
{
|
||||
var a = '';
|
||||
// context line
|
||||
}
|
||||
var c = 0;
|
||||
}
|
||||
''');
|
||||
await computeCompletion('^');
|
||||
assertSuggested('a', returnType: 'String');
|
||||
assertSuggested('b', returnType: 'double');
|
||||
|
||||
// "c" is defined after the context offset, so is not visible.
|
||||
assertNotSuggested('c');
|
||||
}
|
||||
|
||||
test_parameters_function() async {
|
||||
addContextFile(r'''
|
||||
void main(int a, double b) {
|
||||
// context line
|
||||
}
|
||||
''');
|
||||
await computeCompletion('^');
|
||||
assertSuggested('a', returnType: 'int');
|
||||
assertSuggested('b', returnType: 'double');
|
||||
}
|
||||
|
||||
test_parameters_function_locals() async {
|
||||
addContextFile(r'''
|
||||
void main(int a, int b) {
|
||||
String a;
|
||||
double c;
|
||||
// context line
|
||||
}
|
||||
''');
|
||||
await computeCompletion('^');
|
||||
assertSuggested('a', returnType: 'String');
|
||||
assertSuggested('b', returnType: 'int');
|
||||
assertSuggested('c', returnType: 'double');
|
||||
}
|
||||
|
||||
test_parameters_function_nested() async {
|
||||
addContextFile(r'''
|
||||
void foo(int a, double b) {
|
||||
void bar(String a, bool c) {
|
||||
// context line
|
||||
}
|
||||
}
|
||||
''');
|
||||
await computeCompletion('^');
|
||||
assertSuggested('a', returnType: 'String');
|
||||
assertSuggested('b', returnType: 'double');
|
||||
assertSuggested('c', returnType: 'bool');
|
||||
}
|
||||
|
||||
test_parameters_method() async {
|
||||
addContextFile(r'''
|
||||
class C {
|
||||
void main(int a, double b) {
|
||||
// context line
|
||||
}
|
||||
}
|
||||
''');
|
||||
await computeCompletion('^');
|
||||
assertSuggested('a', returnType: 'int');
|
||||
assertSuggested('b', returnType: 'double');
|
||||
}
|
||||
|
||||
test_parameters_method_locals() async {
|
||||
addContextFile(r'''
|
||||
class C {
|
||||
void main(int a, int b) {
|
||||
String a;
|
||||
double c;
|
||||
// context line
|
||||
}
|
||||
}
|
||||
''');
|
||||
await computeCompletion('^');
|
||||
assertSuggested('a', returnType: 'String');
|
||||
assertSuggested('b', returnType: 'int');
|
||||
assertSuggested('c', returnType: 'double');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue