mirror of
https://github.com/dart-lang/sdk
synced 2024-09-22 00:21:20 +00:00
Merge remote-tracking branch 'origin/master' into analyzer-breaking-0.27
This commit is contained in:
commit
de3a1b22c8
2
DEPS
2
DEPS
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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()}');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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('==');
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
'''
|
||||
|
|
|
@ -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 ]
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue