From 0bf3812043d273f132e282e6d26e0e9830c21c8f Mon Sep 17 00:00:00 2001 From: "brianwilkerson@google.com" Date: Fri, 15 May 2015 00:00:59 +0000 Subject: [PATCH] Fix exception in code completion (issue 23439) R=danrubel@google.com Review URL: https://codereview.chromium.org//1138963005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45805 260f80e4-7a28-3924-810f-c04153c831b5 --- .../completion/local_declaration_visitor.dart | 5 +- .../local_declaration_visitor_test.dart | 86 +++++++++++++++++++ .../test/services/completion/test_all.dart | 9 +- 3 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart diff --git a/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart b/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart index 6ba0afa8c44..9032b05bd84 100644 --- a/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart +++ b/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart @@ -160,7 +160,10 @@ abstract class LocalDeclarationVisitor extends GeneralizingAstVisitor { id = node.identifier; type = null; } - declaredLocalVar(id, type); + if (id != null) { + // If there is no loop variable, don't declare it. + declaredLocalVar(id, type); + } visitNode(node); } diff --git a/pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart b/pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart new file mode 100644 index 00000000000..230291d8ad7 --- /dev/null +++ b/pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart @@ -0,0 +1,86 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library test.services.completion.local_declaration_visitor_test; + +import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart'; +import 'package:analyzer/src/generated/ast.dart'; +import 'package:analyzer/src/generated/error.dart'; +import 'package:analyzer/src/generated/parser.dart'; +import 'package:analyzer/src/generated/scanner.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; +import 'package:unittest/unittest.dart'; + +main() { + groupSep = ' | '; + defineReflectiveTests(LocalDeclarationVisitorTest); +} + +@reflectiveTest +class LocalDeclarationVisitorTest { + CompilationUnit parseCompilationUnit(String source) { + AnalysisErrorListener listener = AnalysisErrorListener.NULL_LISTENER; + Scanner scanner = + new Scanner(null, new CharSequenceReader(source), listener); + Token token = scanner.tokenize(); + Parser parser = new Parser(null, listener); + CompilationUnit unit = parser.parseCompilationUnit(token); + expect(unit, isNotNull); + return unit; + } + + test_visitForEachStatement() { + CompilationUnit unit = parseCompilationUnit(''' +class MyClass {} +f(List list) { + for(MyClas( x in list) {} +} +'''); + NodeList declarations = unit.declarations; + expect(declarations, hasLength(2)); + FunctionDeclaration f = declarations[1]; + expect(f, isNotNull); + BlockFunctionBody body = f.functionExpression.body; + Statement statement = body.block.statements[0]; + expect(statement, new isInstanceOf()); + statement.accept(new TestVisitor(statement.offset)); + } +} + +class TestVisitor extends LocalDeclarationVisitor { + TestVisitor(int offset) : super(offset); + + @override + void declaredClass(ClassDeclaration declaration) {} + + @override + void declaredClassTypeAlias(ClassTypeAlias declaration) {} + + @override + void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {} + + @override + void declaredFunction(FunctionDeclaration declaration) {} + + @override + void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {} + + @override + void declaredLabel(Label label, bool isCaseLabel) {} + + @override + void declaredLocalVar(SimpleIdentifier name, TypeName type) { + expect(name, isNotNull); + } + + @override + void declaredMethod(MethodDeclaration declaration) {} + + @override + void declaredParam(SimpleIdentifier name, TypeName type) {} + + @override + void declaredTopLevelVar( + VariableDeclarationList varList, VariableDeclaration varDecl) {} +} diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart index 2c5ff9cdc29..3ccfb645c3a 100644 --- a/pkg/analysis_server/test/services/completion/test_all.dart +++ b/pkg/analysis_server/test/services/completion/test_all.dart @@ -15,7 +15,9 @@ import 'completion_target_test.dart' as completion_target_test; import 'import_uri_contributor_test.dart' as import_uri_test; import 'imported_reference_contributor_test.dart' as imported_test; import 'keyword_contributor_test.dart' as keyword_test; -import 'local_reference_contributor_test.dart' as local_test; +import 'local_declaration_visitor_test.dart' as local_declaration_visitor_test; +import 'local_reference_contributor_test.dart' + as local_reference_contributor_test; import 'optype_test.dart' as optype_test; import 'prefixed_element_contributor_test.dart' as invocation_test; @@ -31,9 +33,10 @@ main() { completion_target_test.main(); import_uri_test.main(); imported_test.main(); - keyword_test.main(); invocation_test.main(); - local_test.main(); + keyword_test.main(); + local_declaration_visitor_test.main(); + local_reference_contributor_test.main(); optype_test.main(); }); }