Merge remote-tracking branch 'origin/master' into analyzer-breaking-0.27

This commit is contained in:
Paul Berry 2015-12-07 07:04:07 -08:00
commit de3a1b22c8
19 changed files with 478 additions and 114 deletions

2
DEPS
View file

@ -46,7 +46,7 @@ vars = {
"chrome_rev" : "@19997",
"clang_rev" : "@28450",
"cli_util_tag" : "@0.0.1+2",
"collection_rev": "@1da9a07f32efa2ba0c391b289e2037391e31da0e",
"collection_rev": "@f6135e6350c63eb3f4dd12953b8d4363faff16fc",
"crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
"csslib_tag" : "@0.12.0",
"dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",

View file

@ -10,6 +10,7 @@ import 'package:analysis_server/src/provisional/completion/dart/completion_dart.
import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
import 'package:plugin/plugin.dart';
@ -71,6 +72,8 @@ class DartCompletionPlugin implements Plugin {
() => new ArgListContributor());
registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
() => new CombinatorContributor());
registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
() => new FieldFormalContributor());
registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
() => new KeywordContributor());
registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,

View file

@ -0,0 +1,89 @@
// 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 services.completion.contributor.dart.field_formal;
import 'dart:async';
import 'package:analysis_server/src/protocol_server.dart'
hide Element, ElementKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/src/generated/ast.dart';
/**
* A contributor for calculating invocation / access suggestions
* `completion.getSuggestions` request results.
*/
class FieldFormalContributor extends DartCompletionContributor {
@override
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request) async {
if (request.target.containingNode is! FieldFormalParameter) {
return EMPTY_LIST;
}
// Partially resolve the compilation unit
CompilationUnit unit = await request.resolveDeclarationsInScope();
// Gracefully degrade if the compilation unit could not be resolved
// e.g. detached part file or source change
if (unit == null) {
return EMPTY_LIST;
}
// Recompute the target since resolution may have changed it
AstNode node = request.target.containingNode;
if (node is! FieldFormalParameter) {
return EMPTY_LIST;
}
// If this is a constructor declaration
// then compute fields already referenced
ConstructorDeclaration constructorDecl =
node.getAncestor((p) => p is ConstructorDeclaration);
if (constructorDecl == null) {
return EMPTY_LIST;
}
// Compute the list of fields already referenced in the constructor
List<String> referencedFields = new List<String>();
for (FormalParameter param in constructorDecl.parameters.parameters) {
if (param is FieldFormalParameter) {
SimpleIdentifier fieldId = param.identifier;
if (fieldId != null && fieldId != request.target.entity) {
String fieldName = fieldId.name;
if (fieldName != null && fieldName.length > 0) {
referencedFields.add(fieldName);
}
}
}
}
// Add suggestions for fields that are not already referenced
ClassDeclaration classDecl =
constructorDecl.getAncestor((p) => p is ClassDeclaration);
List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
for (ClassMember member in classDecl.members) {
if (member is FieldDeclaration && !member.isStatic) {
for (VariableDeclaration varDecl in member.fields.variables) {
SimpleIdentifier fieldId = varDecl.name;
if (fieldId != null) {
String fieldName = fieldId.name;
if (fieldName != null && fieldName.length > 0) {
if (!referencedFields.contains(fieldName)) {
CompletionSuggestion suggestion = createSuggestion(
fieldId.bestElement,
relevance: DART_RELEVANCE_LOCAL_FIELD);
if (suggestion != null) {
suggestions.add(suggestion);
}
}
}
}
}
}
}
return suggestions;
}
}

View file

@ -52,9 +52,12 @@ CompletionSuggestion createSuggestion(Element element,
suggestion.parameterNames = element.parameters
.map((ParameterElement parameter) => parameter.name)
.toList();
suggestion.parameterTypes = element.parameters
.map((ParameterElement parameter) => parameter.type.displayName)
.toList();
suggestion.parameterTypes =
element.parameters.map((ParameterElement parameter) {
DartType paramType = parameter.type;
// Gracefully degrade if type not resolved yet
return paramType != null ? paramType.displayName : 'var';
}).toList();
suggestion.requiredParameterCount = element.parameters
.where((ParameterElement parameter) =>
parameter.parameterKind == ParameterKind.REQUIRED)

View file

@ -95,73 +95,6 @@ class _ExpressionSuggestionBuilder implements SuggestionBuilder {
}
}
/**
* A suggestion builder for 'this.' constructor arguments.
*/
class _FieldFormalSuggestionBuilder implements SuggestionBuilder {
final DartCompletionRequest request;
_FieldFormalSuggestionBuilder(this.request);
@override
bool computeFast(AstNode node) {
if (node is FieldFormalParameter) {
ConstructorDeclaration constructorDecl =
node.getAncestor((p) => p is ConstructorDeclaration);
if (constructorDecl != null) {
// Compute fields already referenced
List<String> referencedFields = new List<String>();
for (FormalParameter param in constructorDecl.parameters.parameters) {
if (param is FieldFormalParameter) {
SimpleIdentifier fieldId = param.identifier;
if (fieldId != null && fieldId != request.target.entity) {
String fieldName = fieldId.name;
if (fieldName != null && fieldName.length > 0) {
referencedFields.add(fieldName);
}
}
}
}
// Add suggestions for fields that are not already referenced
ClassDeclaration classDecl =
constructorDecl.getAncestor((p) => p is ClassDeclaration);
for (ClassMember member in classDecl.members) {
if (member is FieldDeclaration && !member.isStatic) {
for (VariableDeclaration varDecl in member.fields.variables) {
SimpleIdentifier fieldId = varDecl.name;
if (fieldId != null) {
String fieldName = fieldId.name;
if (fieldName != null && fieldName.length > 0) {
if (!referencedFields.contains(fieldName)) {
CompletionSuggestion suggestion =
createFieldSuggestion(request.source, member, varDecl);
if (suggestion != null) {
request.addSuggestion(suggestion);
}
}
}
}
}
}
}
}
} else {
// This should never be called with a case not handled above.
assert(false);
}
return true;
}
@override
Future<bool> computeFull(AstNode node) {
// This should never be called; we should always be able to compute
// suggestions and return true in computeFast method.
assert(false);
return null;
}
}
/**
* An [AstNode] vistor for determining which suggestion builder
* should be used to build invocation/access suggestions.
@ -178,11 +111,6 @@ class _InvocationAstVisitor extends GeneralizingAstVisitor<SuggestionBuilder> {
return new _PrefixedIdentifierSuggestionBuilder(request);
}
@override
SuggestionBuilder visitFieldFormalParameter(FieldFormalParameter node) {
return new _FieldFormalSuggestionBuilder(request);
}
@override
SuggestionBuilder visitMethodInvocation(MethodInvocation node) {
return new _ExpressionSuggestionBuilder(request);

View file

@ -332,7 +332,7 @@ import "../foo/foo.dart";
subscriptions[service] = <String>[bar.path].toSet();
}
server.setAnalysisSubscriptions(subscriptions);
await pumpEventQueue(500);
await pumpEventQueue(1000);
expect(server.statusAnalyzing, isFalse);
channel.notificationsReceived.clear();
server.updateContent(

View file

@ -1121,44 +1121,38 @@ main(A a) {
buildTests(
'testCompletion_combinator_afterComma',
'''
"import 'dart:math' show cos, !1;''',
<String>["1+PI", "1+sin", "1+Random", "1-String"],
failingTests: '1');
import 'dart:math' show cos, !1;''',
<String>["1+PI", "1+sin", "1+Random", "1-String"]);
buildTests(
'testCompletion_combinator_ended',
'''
import 'dart:math' show !1;"''',
<String>["1+PI", "1+sin", "1+Random", "1-String"],
failingTests: '1');
<String>["1+PI", "1+sin", "1+Random", "1-String"]);
buildTests(
'testCompletion_combinator_export',
'''
export 'dart:math' show !1;"''',
<String>["1+PI", "1+sin", "1+Random", "1-String"],
failingTests: '1');
<String>["1+PI", "1+sin", "1+Random", "1-String"]);
buildTests(
'testCompletion_combinator_hide',
'''
import 'dart:math' hide !1;"''',
<String>["1+PI", "1+sin", "1+Random", "1-String"],
failingTests: '1');
<String>["1+PI", "1+sin", "1+Random", "1-String"]);
buildTests(
'testCompletion_combinator_notEnded',
'''
import 'dart:math' show !1"''',
<String>["1+PI", "1+sin", "1+Random", "1-String"],
failingTests: '1');
<String>["1+PI", "1+sin", "1+Random", "1-String"]);
buildTests(
'testCompletion_combinator_usePrefix',
'''
import 'dart:math' show s!1"''',
<String>["1+sin", "1+sqrt", "1-cos", "1-String"],
failingTests: '1');
<String>["1+sin", "1+sqrt", "1-cos", "1-String"]);
buildTests(
'testCompletion_constructor_field',

View file

@ -366,6 +366,8 @@ class CompletionTest extends AbstractAnalysisTest {
expect(suggestionsDone, isNotNull);
suggestions = params.results;
}
} else if (notification.event == SERVER_ERROR) {
fail('server error: ${notification.toJson()}');
}
}

View file

@ -4418,10 +4418,9 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
assertSuggestInvocationField('b', null,
relevance: DART_RELEVANCE_LOCAL_FIELD);
assertSuggestInvocationField('_c', 'X',
relevance: DART_RELEVANCE_LOCAL_FIELD);
// Contributed by FieldFormalConstructorContributor
assertNotSuggested('b');
assertNotSuggested('_c');
assertNotSuggested('sb');
assertNotSuggested('d');
assertNotSuggested('_e');
@ -4458,10 +4457,9 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset - 1);
expect(request.replacementLength, 1);
assertSuggestInvocationField('b', null,
relevance: DART_RELEVANCE_LOCAL_FIELD);
assertSuggestInvocationField('_c', 'X',
relevance: DART_RELEVANCE_LOCAL_FIELD);
// Contributed by FieldFormalConstructorContributor
assertNotSuggested('b');
assertNotSuggested('_c');
assertNotSuggested('d');
assertNotSuggested('_e');
assertNotSuggested('f');
@ -4497,10 +4495,9 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 1);
assertSuggestInvocationField('b', null,
relevance: DART_RELEVANCE_LOCAL_FIELD);
assertSuggestInvocationField('_c', 'X',
relevance: DART_RELEVANCE_LOCAL_FIELD);
// Contributed by FieldFormalConstructorContributor
assertNotSuggested('b');
assertNotSuggested('_c');
assertNotSuggested('d');
assertNotSuggested('_e');
assertNotSuggested('f');
@ -4537,8 +4534,8 @@ abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
assertNotSuggested('b');
assertSuggestInvocationField('_c', 'X',
relevance: DART_RELEVANCE_LOCAL_FIELD);
// Contributed by FieldFormalConstructorContributor
assertNotSuggested('_c');
assertNotSuggested('d');
assertNotSuggested('_e');
assertNotSuggested('f');

View file

@ -76,8 +76,8 @@ class CombinatorContributorTest extends DartCompletionContributorTest {
assertSuggestClass('PB',
relevance: DART_RELEVANCE_DEFAULT,
kind: CompletionSuggestionKind.IDENTIFIER);
assertSuggestTopLevelVar('T1', null, DART_RELEVANCE_DEFAULT,
CompletionSuggestionKind.IDENTIFIER);
assertSuggestTopLevelVar('T1', null,
kind: CompletionSuggestionKind.IDENTIFIER);
assertSuggestFunction('F1', 'PB',
kind: CompletionSuggestionKind.IDENTIFIER);
assertNotSuggested('C');
@ -127,8 +127,8 @@ class CombinatorContributorTest extends DartCompletionContributorTest {
assertSuggestClass('PB',
relevance: DART_RELEVANCE_DEFAULT,
kind: CompletionSuggestionKind.IDENTIFIER);
assertSuggestTopLevelVar('T1', null, DART_RELEVANCE_DEFAULT,
CompletionSuggestionKind.IDENTIFIER);
assertSuggestTopLevelVar('T1', null,
kind: CompletionSuggestionKind.IDENTIFIER);
assertSuggestFunction('F1', 'PB',
kind: CompletionSuggestionKind.IDENTIFIER);
assertSuggestClass('Clz',
@ -141,4 +141,11 @@ class CombinatorContributorTest extends DartCompletionContributorTest {
assertNotSuggested('X');
assertNotSuggested('Object');
}
test_Combinator_show_PI() async {
addTestSource('import "dart:math" show ^;');
await computeSuggestions();
assertSuggestTopLevelVar('PI', 'double',
kind: CompletionSuggestionKind.IDENTIFIER);
}
}

View file

@ -160,6 +160,62 @@ abstract class DartCompletionContributorTest extends AbstractContextTest {
return cs;
}
CompletionSuggestion assertSuggestConstructor(String name,
{int relevance: DART_RELEVANCE_DEFAULT,
String importUri,
int elemOffset}) {
CompletionSuggestion cs = assertSuggest(name,
relevance: relevance, importUri: importUri, elemOffset: elemOffset);
protocol.Element element = cs.element;
expect(element, isNotNull);
expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
int index = name.indexOf('.');
expect(element.name, index >= 0 ? name.substring(index + 1) : '');
return cs;
}
CompletionSuggestion assertSuggestEnum(String completion,
{bool isDeprecated: false}) {
CompletionSuggestion suggestion =
assertSuggest(completion, isDeprecated: isDeprecated);
expect(suggestion.isDeprecated, isDeprecated);
expect(suggestion.element.kind, protocol.ElementKind.ENUM);
return suggestion;
}
CompletionSuggestion assertSuggestEnumConst(String completion,
{bool isDeprecated: false}) {
CompletionSuggestion suggestion =
assertSuggest(completion, isDeprecated: isDeprecated);
expect(suggestion.isDeprecated, isDeprecated);
expect(suggestion.element.kind, protocol.ElementKind.ENUM_CONSTANT);
return suggestion;
}
CompletionSuggestion assertSuggestField(String name, String type,
{int relevance: DART_RELEVANCE_DEFAULT,
String importUri,
CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
bool isDeprecated: false}) {
CompletionSuggestion cs = assertSuggest(name,
csKind: kind,
relevance: relevance,
importUri: importUri,
elemKind: protocol.ElementKind.FIELD,
isDeprecated: isDeprecated);
// The returnType represents the type of a field
expect(cs.returnType, type != null ? type : 'dynamic');
protocol.Element element = cs.element;
expect(element, isNotNull);
expect(element.kind, equals(protocol.ElementKind.FIELD));
expect(element.name, equals(name));
expect(element.parameters, isNull);
// The returnType represents the type of a field
expect(element.returnType, type != null ? type : 'dynamic');
assertHasNoParameterInfo(cs);
return cs;
}
CompletionSuggestion assertSuggestFunction(String name, String returnType,
{CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
bool deprecated: false,
@ -214,10 +270,82 @@ abstract class DartCompletionContributorTest extends AbstractContextTest {
return cs;
}
CompletionSuggestion assertSuggestTopLevelVar(String name, String returnType,
CompletionSuggestion assertSuggestGetter(String name, String returnType,
{int relevance: DART_RELEVANCE_DEFAULT,
String importUri,
CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
bool isDeprecated: false}) {
CompletionSuggestion cs = assertSuggest(name,
csKind: kind,
relevance: relevance,
importUri: importUri,
elemKind: protocol.ElementKind.GETTER,
isDeprecated: isDeprecated);
expect(cs.returnType, returnType != null ? returnType : 'dynamic');
protocol.Element element = cs.element;
expect(element, isNotNull);
expect(element.kind, equals(protocol.ElementKind.GETTER));
expect(element.name, equals(name));
expect(element.parameters, isNull);
expect(element.returnType,
equals(returnType != null ? returnType : 'dynamic'));
assertHasNoParameterInfo(cs);
return cs;
}
CompletionSuggestion assertSuggestMethod(
String name, String declaringType, String returnType,
{int relevance: DART_RELEVANCE_DEFAULT,
String importUri,
CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
bool isDeprecated: false}) {
CompletionSuggestion cs = assertSuggest(name,
csKind: kind,
relevance: relevance,
importUri: importUri,
isDeprecated: isDeprecated);
expect(cs.declaringType, equals(declaringType));
expect(cs.returnType, returnType != null ? returnType : 'dynamic');
protocol.Element element = cs.element;
expect(element, isNotNull);
expect(element.kind, equals(protocol.ElementKind.METHOD));
expect(element.name, equals(name));
String param = element.parameters;
expect(param, isNotNull);
expect(param[0], equals('('));
expect(param[param.length - 1], equals(')'));
expect(element.returnType, returnType != null ? returnType : 'dynamic');
assertHasParameterInfo(cs);
return cs;
}
CompletionSuggestion assertSuggestSetter(String name,
[int relevance = DART_RELEVANCE_DEFAULT,
CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
String importUri]) {
String importUri,
CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
CompletionSuggestion cs = assertSuggest(name,
csKind: kind,
relevance: relevance,
importUri: importUri,
elemKind: protocol.ElementKind.SETTER);
protocol.Element element = cs.element;
expect(element, isNotNull);
expect(element.kind, equals(protocol.ElementKind.SETTER));
expect(element.name, equals(name));
// TODO (danrubel) assert setter param
//expect(element.parameters, isNull);
// TODO (danrubel) it would be better if this was always null
if (element.returnType != null) {
expect(element.returnType, 'dynamic');
}
assertHasNoParameterInfo(cs);
return cs;
}
CompletionSuggestion assertSuggestTopLevelVar(String name, String returnType,
{int relevance: DART_RELEVANCE_DEFAULT,
CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
String importUri}) {
CompletionSuggestion cs = assertSuggest(name,
csKind: kind, relevance: relevance, importUri: importUri);
expect(cs.returnType, returnType != null ? returnType : 'dynamic');

View file

@ -0,0 +1,167 @@
// 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.field_formal;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
initializeTestEnvironment();
defineReflectiveTests(FieldFormalContributorTest);
}
@reflectiveTest
class FieldFormalContributorTest extends DartCompletionContributorTest {
@override
DartCompletionContributor createContributor() {
return new FieldFormalContributor();
}
test_ThisExpression_constructor_param() async {
// SimpleIdentifier FieldFormalParameter FormalParameterList
addTestSource('''
main() { }
class I {X get f => new A();get _g => new A();}
class A implements I {
A(this.^) {}
A.z() {}
var b; X _c; static sb;
X get d => new A();get _e => new A();
// no semicolon between completion point and next statement
set s1(I x) {} set _s2(I x) {m(null);}
m(X x) {} I _n(X x) {}}
class X{}''');
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
assertNotSuggested('sb');
assertNotSuggested('d');
assertNotSuggested('_e');
assertNotSuggested('f');
assertNotSuggested('_g');
assertNotSuggested('m');
assertNotSuggested('_n');
assertNotSuggested('s1');
assertNotSuggested('_s2');
assertNotSuggested('z');
assertNotSuggested('I');
assertNotSuggested('A');
assertNotSuggested('X');
assertNotSuggested('Object');
assertNotSuggested('==');
}
test_ThisExpression_constructor_param2() async {
// SimpleIdentifier FieldFormalParameter FormalParameterList
addTestSource('''
main() { }
class I {X get f => new A();get _g => new A();}
class A implements I {
A(this.b^) {}
A.z() {}
var b; X _c;
X get d => new A();get _e => new A();
// no semicolon between completion point and next statement
set s1(I x) {} set _s2(I x) {m(null);}
m(X x) {} I _n(X x) {}}
class X{}''');
await computeSuggestions();
expect(replacementOffset, completionOffset - 1);
expect(replacementLength, 1);
assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
assertNotSuggested('d');
assertNotSuggested('_e');
assertNotSuggested('f');
assertNotSuggested('_g');
assertNotSuggested('m');
assertNotSuggested('_n');
assertNotSuggested('s1');
assertNotSuggested('_s2');
assertNotSuggested('z');
assertNotSuggested('I');
assertNotSuggested('A');
assertNotSuggested('X');
assertNotSuggested('Object');
assertNotSuggested('==');
}
test_ThisExpression_constructor_param3() async {
// SimpleIdentifier FieldFormalParameter FormalParameterList
addTestSource('''
main() { }
class I {X get f => new A();get _g => new A();}
class A implements I {
A(this.^b) {}
A.z() {}
var b; X _c;
X get d => new A();get _e => new A();
// no semicolon between completion point and next statement
set s1(I x) {} set _s2(I x) {m(null);}
m(X x) {} I _n(X x) {}}
class X{}''');
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 1);
assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
assertNotSuggested('d');
assertNotSuggested('_e');
assertNotSuggested('f');
assertNotSuggested('_g');
assertNotSuggested('m');
assertNotSuggested('_n');
assertNotSuggested('s1');
assertNotSuggested('_s2');
assertNotSuggested('z');
assertNotSuggested('I');
assertNotSuggested('A');
assertNotSuggested('X');
assertNotSuggested('Object');
assertNotSuggested('==');
}
test_ThisExpression_constructor_param4() async {
// SimpleIdentifier FieldFormalParameter FormalParameterList
addTestSource('''
main() { }
class I {X get f => new A();get _g => new A();}
class A implements I {
A(this.b, this.^) {}
A.z() {}
var b; X _c;
X get d => new A();get _e => new A();
// no semicolon between completion point and next statement
set s1(I x) {} set _s2(I x) {m(null);}
m(X x) {} I _n(X x) {}}
class X{}''');
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertNotSuggested('b');
assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
assertNotSuggested('d');
assertNotSuggested('_e');
assertNotSuggested('f');
assertNotSuggested('_g');
assertNotSuggested('m');
assertNotSuggested('_n');
assertNotSuggested('s1');
assertNotSuggested('_s2');
assertNotSuggested('z');
assertNotSuggested('I');
assertNotSuggested('A');
assertNotSuggested('X');
assertNotSuggested('Object');
assertNotSuggested('==');
}
}

View file

@ -10,6 +10,7 @@ import '../../../utils.dart';
import 'combinator_contributor_test.dart' as combinator_test;
import 'arglist_contributor_test.dart' as arglist_test;
import 'common_usage_sorter_test.dart' as common_usage_test;
import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
import 'inherited_contributor_test.dart' as inherited_contributor_test;
import 'keyword_contributor_test.dart' as keyword_test;
import 'uri_contributor_test.dart' as uri_contributor_test;
@ -21,6 +22,7 @@ main() {
arglist_test.main();
combinator_test.main();
common_usage_test.main();
field_formal_contributor_test.main();
inherited_contributor_test.main();
keyword_test.main();
uri_contributor_test.main();

View file

@ -12,6 +12,7 @@ import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/task/general.dart';
import 'package:analyzer/src/task/strong/info.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
import 'package:source_span/source_span.dart';
@ -125,6 +126,10 @@ class ErrorFilterOptionValidator extends OptionsValidator {
new List.from(AnalyzerOptions.ignoreSynonyms)
..addAll(AnalyzerOptions.includeSynonyms));
bool recognizedErrorCode(String name) =>
ErrorCode.values.any((ErrorCode code) => code.name == name) ||
StaticInfo.names.contains(name);
@override
void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
var analyzer = options[AnalyzerOptions.analyzer];
@ -138,7 +143,7 @@ class ErrorFilterOptionValidator extends OptionsValidator {
filters.nodes.forEach((k, v) {
if (k is YamlScalar) {
value = toUpperCase(k.value);
if (!ErrorCode.values.any((ErrorCode code) => code.name == value)) {
if (!recognizedErrorCode(value)) {
reporter.reportErrorForSpan(
AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
k.span,

View file

@ -481,6 +481,32 @@ abstract class StaticError extends StaticInfo {
// Analyzer instead has template strings, and replaces '{0}' with the first
// argument.
abstract class StaticInfo {
/// Strong-mode error code names.
///
/// Used for error code configuration validation in `.analysis_options`.
static const List<String> names = const [
//
// Manually populated.
//
'STRONG_MODE_ASSIGNMENT_CAST',
'STRONG_MODE_DOWN_CAST_COMPOSITE',
'STRONG_MODE_DOWN_CAST_IMPLICIT',
'STRONG_MODE_DYNAMIC_CAST',
'STRONG_MODE_DYNAMIC_INVOKE',
'STRONG_MODE_INFERRED_TYPE',
'STRONG_MODE_INFERRED_TYPE_ALLOCATION',
'STRONG_MODE_INFERRED_TYPE_CLOSURE',
'STRONG_MODE_INFERRED_TYPE_LITERAL',
'STRONG_MODE_INVALID_FIELD_OVERRIDE',
'STRONG_MODE_INVALID_METHOD_OVERRIDE',
'STRONG_MODE_INVALID_PARAMETER_DECLARATION',
'STRONG_MODE_INVALID_SUPER_INVOCATION',
'STRONG_MODE_INVALID_VARIABLE_DECLARATION',
'STRONG_MODE_NON_GROUND_TYPE_CHECK_INFO',
'STRONG_MODE_STATIC_TYPE_ERROR',
'STRONG_MODE_UNINFERRED_CLOSURE',
];
List<Object> get arguments => [node];
String get name;

View file

@ -284,6 +284,16 @@ analyzer:
[AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
}
test_analyzer_strong_mode_error_code_supported() {
validate(
'''
analyzer:
errors:
strong_mode_assignment_cast: ignore
''',
[]);
}
test_analyzer_supported_exclude() {
validate(
'''

View file

@ -164,7 +164,7 @@ assert_test: Fail # Issue 14651.
javascript_int_overflow_literal_test/01: Fail # Issue 14651.
javascript_int_overflow_test: Fail # Issue 14651.
[ $compiler == none && $runtime == drt && $arch == x64 ]
[ $compiler == none && $runtime == drt ]
map_literal_oom_test: RuntimeError # Issue 24571
[ $compiler == dartanalyzer || $compiler == dart2analyzer ]

View file

@ -39,6 +39,9 @@ poi/serialize_test: SkipByDesign # Uses dart:io.
[ $compiler == dart2js ]
poi/*: Skip # Issue 20031
[ $compiler == dart2js && $runtime == none ]
poi/serialize_test: RuntimeError # Issue 25125
[ $compiler == dart2js ]
# Compilation is slow, test fails at runtime due to time out, but
# unpredictably.

View file

@ -33,7 +33,7 @@ vars.update({
"args_tag": "@0.13.0",
"barback_rev" : "@29ee90dbcf77cfd64632fa2797a4c8a4f29a4b51",
"charcode_tag": "@1.1.0",
"collection_rev": "@1da9a07f32efa2ba0c391b289e2037391e31da0e",
"collection_rev": "@f6135e6350c63eb3f4dd12953b8d4363faff16fc",
"crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
"csslib_tag" : "@0.12.0",
"dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",