Remove ReferencedNames(Builder).

Nobody uses them anymore, so there is no point in computing it.

R=brianwilkerson@google.com
BUG=

Review-Url: https://codereview.chromium.org/2835703002 .
This commit is contained in:
Konstantin Shcheglov
2017-04-21 14:28:49 -07:00
parent dca21921fb
commit d780f10d72
6 changed files with 5 additions and 1025 deletions
@@ -531,7 +531,6 @@ class GetHandler implements AbstractGetHandler {
results.add(LIBRARY_ERRORS_READY);
results.add(PARSE_ERRORS);
results.add(PARSED_UNIT);
results.add(REFERENCED_NAMES);
results.add(SCAN_ERRORS);
results.add(SOURCE_KIND);
results.add(TOKEN_STREAM);
@@ -1509,8 +1509,6 @@ class ValueComparison {
return _compareLibrarySpecificUnits(expected, actual, buffer);
} else if (actual is LineInfo) {
return _compareLineInfos(expected, actual, buffer);
} else if (actual is ReferencedNames) {
return _compareReferencedNames(expected, actual, buffer);
} else if (actual is Source) {
return _compareSources(expected, actual, buffer);
} else if (actual is SourceKind) {
@@ -1546,116 +1544,6 @@ class ValueComparison {
return false;
}
bool _compareReferencedNames(
ReferencedNames expected, ReferencedNames actual, StringBuffer buffer) {
Set<String> expectedNames = expected.names;
Map<String, Set<String>> expectedUserToDependsOn = expected.userToDependsOn;
Set<String> expectedKeys = expectedUserToDependsOn.keys.toSet();
Set<String> actualNames = actual.names;
Map<String, Set<String>> actualUserToDependsOn = actual.userToDependsOn;
Set<String> actualKeys = actualUserToDependsOn.keys.toSet();
Set<String> missingNames = expectedNames.difference(actualNames);
Set<String> extraNames = actualNames.difference(expectedNames);
Set<String> missingKeys = expectedKeys.difference(actualKeys);
Set<String> extraKeys = actualKeys.difference(expectedKeys);
Map<String, List<Set<String>>> mismatchedDependencies =
new HashMap<String, List<Set<String>>>();
Set<String> commonKeys = expectedKeys.intersection(actualKeys);
for (String key in commonKeys) {
Set<String> expectedDependencies = expectedUserToDependsOn[key];
Set<String> actualDependencies = actualUserToDependsOn[key];
Set<String> missingDependencies =
expectedDependencies.difference(actualDependencies);
Set<String> extraDependencies =
actualDependencies.difference(expectedDependencies);
if (missingDependencies.isNotEmpty || extraDependencies.isNotEmpty) {
mismatchedDependencies[key] = [missingDependencies, extraDependencies];
}
}
if (missingNames.isEmpty &&
extraNames.isEmpty &&
missingKeys.isEmpty &&
extraKeys.isEmpty &&
mismatchedDependencies.isEmpty) {
return true;
}
if (buffer != null) {
void write(String title, Set<String> names) {
buffer.write(names.length);
buffer.write(' ');
buffer.write(title);
buffer.write(': {');
bool first = true;
for (String name in names) {
if (first) {
first = false;
} else {
buffer.write(', ');
}
buffer.write(name);
}
buffer.write('}');
}
bool needsNewline = false;
if (missingNames.isNotEmpty) {
buffer.write('Has ');
write('missing names', missingNames);
needsNewline = true;
}
if (extraNames.isNotEmpty) {
if (needsNewline) {
buffer.write('</p><p>');
}
buffer.write('Has ');
write('extra names', extraNames);
needsNewline = true;
}
if (missingKeys.isNotEmpty) {
if (needsNewline) {
buffer.write('</p><p>');
}
buffer.write('Has ');
write('missing keys', missingKeys);
needsNewline = true;
}
if (extraKeys.isNotEmpty) {
if (needsNewline) {
buffer.write('</p><p>');
}
buffer.write('Has ');
write('extra keys', extraKeys);
needsNewline = true;
}
mismatchedDependencies.forEach((String key, List<Set<String>> value) {
Set<String> missingDependencies = value[0];
Set<String> extraDependencies = value[1];
if (needsNewline) {
buffer.write('</p><p>');
}
buffer.write('The key ');
buffer.write(key);
buffer.write(' has ');
bool needsConjunction = false;
if (missingNames.isNotEmpty) {
write('missing dependencies', missingDependencies);
needsConjunction = true;
}
if (extraNames.isNotEmpty) {
if (needsConjunction) {
buffer.write(' and ');
}
write('extra dependencies', extraDependencies);
}
needsNewline = true;
});
}
return true;
}
bool _compareSources(Source expected, Source actual, StringBuffer buffer) {
if (actual.fullName == expected.fullName) {
return true;
@@ -886,10 +886,6 @@ class PoorMansIncrementalResolver {
// parse results
_sourceEntry.setValueIncremental(PARSE_ERRORS, _newParseErrors, true);
_sourceEntry.setValueIncremental(PARSED_UNIT, _oldUnit, false);
// referenced names
ReferencedNames referencedNames = new ReferencedNames(_unitSource);
new ReferencedNamesBuilder(referencedNames).build(_oldUnit);
_sourceEntry.setValueIncremental(REFERENCED_NAMES, referencedNames, false);
}
/**
-417
View File
@@ -675,14 +675,6 @@ final ResultDescriptor<bool> READY_LIBRARY_ELEMENT7 =
final ResultDescriptor<bool> READY_RESOLVED_UNIT =
new ResultDescriptor<bool>('READY_RESOLVED_UNIT', false);
/**
* The names (resolved and not) referenced by a unit.
*
* The result is only available for [Source]s representing a compilation unit.
*/
final ResultDescriptor<ReferencedNames> REFERENCED_NAMES =
new ResultDescriptor<ReferencedNames>('REFERENCED_NAMES', null);
/**
* The sources of the Dart files that a library references.
*
@@ -3735,7 +3727,6 @@ class ParseDartTask extends SourceBasedAnalysisTask {
LIBRARY_SPECIFIC_UNITS,
PARSE_ERRORS,
PARSED_UNIT,
REFERENCED_NAMES,
REFERENCED_SOURCES,
SOURCE_KIND,
UNITS,
@@ -3851,11 +3842,6 @@ class ParseDartTask extends SourceBasedAnalysisTask {
sourceKind = SourceKind.PART;
}
//
// Compute referenced names.
//
ReferencedNames referencedNames = new ReferencedNames(_source);
new ReferencedNamesBuilder(referencedNames).build(unit);
//
// Compute source lists.
//
List<Source> explicitlyImportedSources =
@@ -3892,7 +3878,6 @@ class ParseDartTask extends SourceBasedAnalysisTask {
outputs[LIBRARY_SPECIFIC_UNITS] = librarySpecificUnits;
outputs[PARSE_ERRORS] = parseErrors;
outputs[PARSED_UNIT] = unit;
outputs[REFERENCED_NAMES] = referencedNames;
outputs[REFERENCED_SOURCES] = referencedSources.toList();
outputs[SOURCE_KIND] = sourceKind;
outputs[UNITS] = unitSources;
@@ -4265,408 +4250,6 @@ class ReadyResolvedUnitTask extends SourceBasedAnalysisTask {
}
}
/**
* Information about a Dart [source] - which names it uses, which names it
* defines with their externally visible dependencies.
*/
class ReferencedNames {
final Source source;
/**
* The mapping from the name of a class to the set of names of other classes
* that extend, mix-in, or implement it.
*
* If the set of member of a class is changed, these changes might change
* the list of unimplemented inherited members in the class and classes that
* extend, mix-in, or implement it. So, we might need to report (or stop
* reporting) the corresponding warning.
*/
final Map<String, Set<String>> superToSubs = <String, Set<String>>{};
/**
* The names of extended classes for which the unnamed constructor is
* invoked. Because we cannot use the name of the constructor to identify
* whether the unit is affected, we need to use the class name.
*/
final Set<String> extendedUsedUnnamedConstructorNames = new Set<String>();
/**
* The names of instantiated classes.
*
* If one of these classes changes its set of members, it might change
* its list of unimplemented inherited members. So, we might need to report
* (or stop reporting) the corresponding warning.
*/
final Set<String> instantiatedNames = new Set<String>();
/**
* The set of names that are referenced by the library, both inside and
* outside of method bodies.
*/
final Set<String> names = new Set<String>();
/**
* The mapping from the name of a top-level element to the set of names that
* the element uses in a way that is visible outside of the element, e.g.
* the return type, or a parameter type.
*/
final Map<String, Set<String>> userToDependsOn = <String, Set<String>>{};
ReferencedNames(this.source);
void addSubclass(String subName, String superName) {
superToSubs.putIfAbsent(superName, () => new Set<String>()).add(subName);
}
}
/**
* A builder for creating [ReferencedNames].
*/
class ReferencedNamesBuilder extends GeneralizingAstVisitor {
final Set<String> importPrefixNames = new Set<String>();
final ReferencedNames names;
String enclosingSuperClassName;
ReferencedNamesScope scope = new ReferencedNamesScope(null);
int localLevel = 0;
Set<String> dependsOn;
ReferencedNamesBuilder(this.names);
ReferencedNames build(CompilationUnit unit) {
unit.accept(this);
return names;
}
@override
visitBlock(Block node) {
ReferencedNamesScope outerScope = scope;
try {
scope = new ReferencedNamesScope.forBlock(scope, node);
super.visitBlock(node);
} finally {
scope = outerScope;
}
}
@override
visitClassDeclaration(ClassDeclaration node) {
ReferencedNamesScope outerScope = scope;
try {
scope = new ReferencedNamesScope.forClass(scope, node);
dependsOn = new Set<String>();
enclosingSuperClassName =
_getSimpleName(node.extendsClause?.superclass?.name);
super.visitClassDeclaration(node);
String className = node.name.name;
names.userToDependsOn[className] = dependsOn;
_addSuperName(className, node.extendsClause?.superclass);
_addSuperNames(className, node.withClause?.mixinTypes);
_addSuperNames(className, node.implementsClause?.interfaces);
} finally {
enclosingSuperClassName = null;
dependsOn = null;
scope = outerScope;
}
}
@override
visitClassTypeAlias(ClassTypeAlias node) {
ReferencedNamesScope outerScope = scope;
try {
scope = new ReferencedNamesScope.forClassTypeAlias(scope, node);
dependsOn = new Set<String>();
super.visitClassTypeAlias(node);
String className = node.name.name;
names.userToDependsOn[className] = dependsOn;
_addSuperName(className, node.superclass);
_addSuperNames(className, node.withClause?.mixinTypes);
_addSuperNames(className, node.implementsClause?.interfaces);
} finally {
dependsOn = null;
scope = outerScope;
}
}
@override
visitComment(Comment node) {
try {
localLevel++;
super.visitComment(node);
} finally {
localLevel--;
}
}
@override
visitConstructorName(ConstructorName node) {
if (node.parent is! ConstructorDeclaration) {
super.visitConstructorName(node);
}
}
@override
visitFunctionBody(FunctionBody node) {
try {
localLevel++;
super.visitFunctionBody(node);
} finally {
localLevel--;
}
}
@override
visitFunctionDeclaration(FunctionDeclaration node) {
if (localLevel == 0) {
ReferencedNamesScope outerScope = scope;
try {
scope = new ReferencedNamesScope.forFunction(scope, node);
dependsOn = new Set<String>();
super.visitFunctionDeclaration(node);
names.userToDependsOn[node.name.name] = dependsOn;
} finally {
dependsOn = null;
scope = outerScope;
}
} else {
super.visitFunctionDeclaration(node);
}
}
@override
visitFunctionTypeAlias(FunctionTypeAlias node) {
if (localLevel == 0) {
ReferencedNamesScope outerScope = scope;
try {
scope = new ReferencedNamesScope.forFunctionTypeAlias(scope, node);
dependsOn = new Set<String>();
super.visitFunctionTypeAlias(node);
names.userToDependsOn[node.name.name] = dependsOn;
} finally {
dependsOn = null;
scope = outerScope;
}
} else {
super.visitFunctionTypeAlias(node);
}
}
@override
visitImportDirective(ImportDirective node) {
if (node.prefix != null) {
importPrefixNames.add(node.prefix.name);
}
super.visitImportDirective(node);
}
@override
visitInstanceCreationExpression(InstanceCreationExpression node) {
ConstructorName constructorName = node.constructorName;
Identifier typeName = constructorName.type.name;
if (typeName is SimpleIdentifier) {
names.instantiatedNames.add(typeName.name);
}
if (typeName is PrefixedIdentifier) {
String prefixName = typeName.prefix.name;
if (importPrefixNames.contains(prefixName)) {
names.instantiatedNames.add(typeName.identifier.name);
} else {
names.instantiatedNames.add(prefixName);
}
}
super.visitInstanceCreationExpression(node);
}
@override
visitMethodDeclaration(MethodDeclaration node) {
ReferencedNamesScope outerScope = scope;
try {
scope = new ReferencedNamesScope.forMethod(scope, node);
super.visitMethodDeclaration(node);
} finally {
scope = outerScope;
}
}
@override
visitSimpleIdentifier(SimpleIdentifier node) {
// Ignore all declarations.
if (node.inDeclarationContext()) {
return;
}
// Ignore class names references from constructors.
AstNode parent = node.parent;
if (parent is ConstructorDeclaration && parent.returnType == node) {
return;
}
// Prepare name.
String name = node.name;
// Ignore unqualified names shadowed by local elements.
if (!node.isQualified) {
if (scope.contains(name)) {
return;
}
if (importPrefixNames.contains(name)) {
return;
}
}
// Do add the dependency.
names.names.add(name);
if (dependsOn != null && localLevel == 0) {
dependsOn.add(name);
}
}
@override
visitSuperConstructorInvocation(SuperConstructorInvocation node) {
if (node.constructorName == null && enclosingSuperClassName != null) {
names.extendedUsedUnnamedConstructorNames.add(enclosingSuperClassName);
}
super.visitSuperConstructorInvocation(node);
}
@override
visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
VariableDeclarationList variableList = node.variables;
// Prepare type dependencies.
Set<String> typeDependencies = new Set<String>();
dependsOn = typeDependencies;
variableList.type?.accept(this);
// Combine individual variable dependencies with the type dependencies.
for (VariableDeclaration variable in variableList.variables) {
dependsOn = new Set<String>();
variable.accept(this);
dependsOn.addAll(typeDependencies);
names.userToDependsOn[variable.name.name] = dependsOn;
}
dependsOn = null;
}
void _addSuperName(String className, TypeName type) {
if (type != null) {
Identifier typeName = type.name;
if (typeName is SimpleIdentifier) {
names.addSubclass(className, typeName.name);
}
if (typeName is PrefixedIdentifier) {
names.addSubclass(className, typeName.identifier.name);
}
}
}
void _addSuperNames(String className, List<TypeName> types) {
types?.forEach((type) => _addSuperName(className, type));
}
static String _getSimpleName(Identifier identifier) {
if (identifier is SimpleIdentifier) {
return identifier.name;
}
if (identifier is PrefixedIdentifier) {
return identifier.identifier.name;
}
return null;
}
}
class ReferencedNamesScope {
final ReferencedNamesScope enclosing;
Set<String> names;
ReferencedNamesScope(this.enclosing);
factory ReferencedNamesScope.forBlock(
ReferencedNamesScope enclosing, Block node) {
ReferencedNamesScope scope = new ReferencedNamesScope(enclosing);
for (Statement statement in node.statements) {
if (statement is FunctionDeclarationStatement) {
scope.add(statement.functionDeclaration.name.name);
} else if (statement is VariableDeclarationStatement) {
for (VariableDeclaration variable in statement.variables.variables) {
scope.add(variable.name.name);
}
}
}
return scope;
}
factory ReferencedNamesScope.forClass(
ReferencedNamesScope enclosing, ClassDeclaration node) {
ReferencedNamesScope scope = new ReferencedNamesScope(enclosing);
scope._addTypeParameters(node.typeParameters);
for (ClassMember member in node.members) {
if (member is FieldDeclaration) {
for (VariableDeclaration variable in member.fields.variables) {
scope.add(variable.name.name);
}
} else if (member is MethodDeclaration) {
scope.add(member.name.name);
}
}
return scope;
}
factory ReferencedNamesScope.forClassTypeAlias(
ReferencedNamesScope enclosing, ClassTypeAlias node) {
ReferencedNamesScope scope = new ReferencedNamesScope(enclosing);
scope._addTypeParameters(node.typeParameters);
return scope;
}
factory ReferencedNamesScope.forFunction(
ReferencedNamesScope enclosing, FunctionDeclaration node) {
ReferencedNamesScope scope = new ReferencedNamesScope(enclosing);
scope._addTypeParameters(node.functionExpression.typeParameters);
scope._addFormalParameters(node.functionExpression.parameters);
return scope;
}
factory ReferencedNamesScope.forFunctionTypeAlias(
ReferencedNamesScope enclosing, FunctionTypeAlias node) {
ReferencedNamesScope scope = new ReferencedNamesScope(enclosing);
scope._addTypeParameters(node.typeParameters);
return scope;
}
factory ReferencedNamesScope.forMethod(
ReferencedNamesScope enclosing, MethodDeclaration node) {
ReferencedNamesScope scope = new ReferencedNamesScope(enclosing);
scope._addTypeParameters(node.typeParameters);
scope._addFormalParameters(node.parameters);
return scope;
}
void add(String name) {
names ??= new Set<String>();
names.add(name);
}
bool contains(String name) {
if (names != null && names.contains(name)) {
return true;
}
if (enclosing != null) {
return enclosing.contains(name);
}
return false;
}
void _addFormalParameters(FormalParameterList parameterList) {
if (parameterList != null) {
parameterList.parameters
.map((p) => p is NormalFormalParameter ? p.identifier.name : '')
.forEach(add);
}
}
void _addTypeParameters(TypeParameterList typeParameterList) {
if (typeParameterList != null) {
typeParameterList.typeParameters.map((p) => p.name.name).forEach(add);
}
}
}
/**
* A task that ensures that the expression AST for a constant is resolved and
* sets the [CONSTANT_EXPRESSION_RESOLVED] result.
@@ -514,20 +514,6 @@ class PoorMansIncrementalResolutionTest extends ResolverTestCase {
CompilationUnit oldUnit;
CompilationUnitElement oldUnitElement;
void assertSameReferencedNames(
ReferencedNames incNames, ReferencedNames fullNames) {
expectEqualSets(Iterable actual, Iterable expected) {
expect(actual, unorderedEquals(expected));
}
expectEqualSets(incNames.names, fullNames.names);
expectEqualSets(incNames.instantiatedNames, fullNames.instantiatedNames);
expectEqualSets(incNames.superToSubs.keys, fullNames.superToSubs.keys);
for (String key in fullNames.superToSubs.keys) {
expectEqualSets(incNames.superToSubs[key], fullNames.superToSubs[key]);
}
}
@override
void setUp() {
super.setUp();
@@ -2097,8 +2083,6 @@ class B extends A {}
logger.expectNoErrors();
List<AnalysisError> newErrors = analysisContext.computeErrors(source);
LineInfo newLineInfo = analysisContext.getLineInfo(source);
ReferencedNames newReferencedNames =
analysisContext.getResult(source, REFERENCED_NAMES);
// check for expected failure
if (!expectedSuccess) {
expect(newUnit.element, isNot(same(oldUnitElement)));
@@ -2131,10 +2115,6 @@ class B extends A {}
_assertEqualTokens(newUnit, fullNewUnit);
// Validate LineInfo
_assertEqualLineInfo(newLineInfo, analysisContext.getLineInfo(source));
// Validate referenced names.
ReferencedNames fullReferencedNames =
analysisContext.getResult(source, REFERENCED_NAMES);
assertSameReferencedNames(newReferencedNames, fullReferencedNames);
// Validate that "incremental" and "full" units have the same resolution.
try {
assertSameResolution(newUnit, fullNewUnit, validateTypes: true);
+5 -471
View File
@@ -63,7 +63,6 @@ main() {
defineReflectiveTests(LibraryUnitErrorsTaskTest);
defineReflectiveTests(ParseDartTaskTest);
defineReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
defineReflectiveTests(ReferencedNamesBuilderTest);
defineReflectiveTests(ResolveDirectiveElementsTaskTest);
defineReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
defineReflectiveTests(ResolveLibraryTaskTest);
@@ -3173,7 +3172,7 @@ class ParseDartTaskTest extends _AbstractDartTaskTest {
_performParseTask(r'''
part of lib;
class B {}''');
expect(outputs, hasLength(11));
expect(outputs, hasLength(10));
expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
_assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
@@ -3181,7 +3180,6 @@ class B {}''');
expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
expect(outputs[PARSE_ERRORS], hasLength(0));
expect(outputs[PARSED_UNIT], isNotNull);
expect(outputs[REFERENCED_NAMES], isNotNull);
expect(outputs[REFERENCED_SOURCES], hasLength(2));
expect(outputs[SOURCE_KIND], SourceKind.PART);
expect(outputs[UNITS], hasLength(1));
@@ -3209,7 +3207,7 @@ part 'test.dart';
test_perform_doesNotExist() {
_performParseTask(null);
expect(outputs, hasLength(11));
expect(outputs, hasLength(10));
expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
_assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
@@ -3217,7 +3215,6 @@ part 'test.dart';
expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
expect(outputs[PARSE_ERRORS], hasLength(0));
expect(outputs[PARSED_UNIT], isNotNull);
expect(outputs[REFERENCED_NAMES], isNotNull);
expect(outputs[REFERENCED_SOURCES], hasLength(2));
expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
expect(outputs[UNITS], hasLength(1));
@@ -3238,7 +3235,7 @@ import '://invaliduri.dart';
export '${a}lib3.dart';
part 'part.dart';
class A {}''');
expect(outputs, hasLength(11));
expect(outputs, hasLength(10));
expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
_assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
@@ -3246,7 +3243,6 @@ class A {}''');
expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(2));
expect(outputs[PARSE_ERRORS], hasLength(2));
expect(outputs[PARSED_UNIT], isNotNull);
expect(outputs[REFERENCED_NAMES], isNotNull);
expect(outputs[REFERENCED_SOURCES], hasLength(4));
expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
expect(outputs[UNITS], hasLength(2));
@@ -3259,7 +3255,7 @@ import 'lib2.dart';
export 'lib3.dart';
part 'part.dart';
class A {''');
expect(outputs, hasLength(11));
expect(outputs, hasLength(10));
expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
expect(outputs[EXPORTED_LIBRARIES], hasLength(1));
_assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
@@ -3267,7 +3263,6 @@ class A {''');
expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(2));
expect(outputs[PARSE_ERRORS], hasLength(1));
expect(outputs[PARSED_UNIT], isNotNull);
expect(outputs[REFERENCED_NAMES], isNotNull);
expect(outputs[REFERENCED_SOURCES], hasLength(5));
expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
expect(outputs[UNITS], hasLength(2));
@@ -3397,7 +3392,7 @@ part 'test.dart';
_performParseTask(r'''
part of lib;
class B {}''');
expect(outputs, hasLength(11));
expect(outputs, hasLength(10));
expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
_assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
@@ -3405,7 +3400,6 @@ class B {}''');
expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
expect(outputs[PARSE_ERRORS], hasLength(0));
expect(outputs[PARSED_UNIT], isNotNull);
expect(outputs[REFERENCED_NAMES], isNotNull);
expect(outputs[REFERENCED_SOURCES], hasLength(2));
expect(outputs[SOURCE_KIND], SourceKind.PART);
expect(outputs[UNITS], hasLength(1));
@@ -3588,466 +3582,6 @@ class C {
}
}
@reflectiveTest
class ReferencedNamesBuilderTest extends _AbstractDartTaskTest {
void setUp() {
super.setUp();
context.analysisOptions = new AnalysisOptionsImpl()..strongMode = true;
}
test_class_constructor() {
ReferencedNames info = _computeReferencedNames('''
class U {
U.named(A a, B b) {
C c = null;
}
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
}
test_class_extendedUsedUnnamedConstructorNames() {
ReferencedNames info = _computeReferencedNames('''
class U1 extends A {
U1() : super();
}
class U2 extends p.B {
U2() : super();
}
class U3 extends p.C {
U3() : super.named();
}
''');
expect(
info.extendedUsedUnnamedConstructorNames, unorderedEquals(['A', 'B']));
}
test_class_field() {
ReferencedNames info = _computeReferencedNames('''
class U {
A f = new B();
}
''');
expect(info.names, unorderedEquals(['A', 'B']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, unorderedEquals(['B']));
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
}
test_class_getter() {
ReferencedNames info = _computeReferencedNames('''
class U {
A get a => new B();
}
''');
expect(info.names, unorderedEquals(['A', 'B']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, unorderedEquals(['B']));
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A']));
}
test_class_members() {
ReferencedNames info = _computeReferencedNames('''
class U {
int a;
int get b;
set c(_) {}
m(D d) {
a;
b;
c = 1;
m();
}
}
''');
expect(info.names, unorderedEquals(['int', 'D']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['int', 'D']));
}
test_class_members_dontHideQualified() {
ReferencedNames info = _computeReferencedNames('''
class U {
int a;
int get b;
set c(_) {}
m(D d) {
d.a;
d.b;
d.c;
}
}
''');
expect(info.names, unorderedEquals(['int', 'D', 'a', 'b', 'c']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['int', 'D']));
}
test_class_method() {
ReferencedNames info = _computeReferencedNames('''
class U {
A m(B p) {
C v = 0;
}
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
}
test_class_method_localVariables() {
ReferencedNames info = _computeReferencedNames('''
class U {
A m() {
B b = null;
b;
{
C c = null;
b;
c;
}
d;
}
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A']));
}
test_class_method_parameters() {
ReferencedNames info = _computeReferencedNames('''
class U {
m(A a) {
a;
b;
}
}
''');
expect(info.names, unorderedEquals(['A', 'b']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A']));
}
test_class_method_typeParameters() {
ReferencedNames info = _computeReferencedNames('''
class U {
A m<T>(B b, T t) {
C c = 0;
}
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
}
test_class_setter() {
ReferencedNames info = _computeReferencedNames('''
class U {
set a(A a) {
B b = null;
}
}
''');
expect(info.names, unorderedEquals(['A', 'B']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A']));
}
test_class_typeParameters() {
ReferencedNames info = _computeReferencedNames('''
class U<T> {
T f = new A<T>();
}
''');
expect(info.names, unorderedEquals(['A']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, unorderedEquals(['A']));
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A']));
}
test_instantiatedNames_importPrefix() {
ReferencedNames info = _computeReferencedNames('''
import 'a.dart' as p1;
import 'b.dart' as p2;
main() {
new p1.A();
new p1.A.c1();
new p1.B();
new p2.C();
new D();
new D.c2();
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C', 'D', 'c1', 'c2']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, unorderedEquals(['A', 'B', 'C', 'D']));
expect(info.userToDependsOn.keys, unorderedEquals(['main']));
expect(info.userToDependsOn['main'], isEmpty);
}
test_localFunction() {
ReferencedNames info = _computeReferencedNames('''
f(A a) {
g(B b) {}
}
''');
expect(info.names, unorderedEquals(['A', 'B']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['f']));
expect(info.userToDependsOn['f'], unorderedEquals(['A']));
}
test_superToSubs_importPrefix() {
ReferencedNames info = _computeReferencedNames('''
import 'a.dart' as p1;
import 'b.dart' as p2;
class U extends p1.A with p2.B implements p2.C {}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs['A'], unorderedEquals(['U']));
expect(info.superToSubs['B'], unorderedEquals(['U']));
expect(info.superToSubs['C'], unorderedEquals(['U']));
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C']));
}
test_topLevelVariable() {
ReferencedNames info = _computeReferencedNames('''
A v = new B(c);
''');
expect(info.names, unorderedEquals(['A', 'B', 'c']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, unorderedEquals(['B']));
expect(info.userToDependsOn.keys, unorderedEquals(['v']));
expect(info.userToDependsOn['v'], unorderedEquals(['A', 'B', 'c']));
}
test_topLevelVariable_multiple() {
ReferencedNames info = _computeReferencedNames('''
A v1 = new B(c), v2 = new D<E>(f);
''');
expect(info.names, unorderedEquals(['A', 'B', 'c', 'D', 'E', 'f']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, unorderedEquals(['B', 'D']));
expect(info.userToDependsOn.keys, unorderedEquals(['v1', 'v2']));
expect(info.userToDependsOn['v1'], unorderedEquals(['A', 'B', 'c']));
expect(info.userToDependsOn['v2'], unorderedEquals(['A', 'D', 'E', 'f']));
}
test_unit_classTypeAlias() {
ReferencedNames info = _computeReferencedNames('''
class U = A with B implements C;
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs['A'], unorderedEquals(['U']));
expect(info.superToSubs['B'], unorderedEquals(['U']));
expect(info.superToSubs['C'], unorderedEquals(['U']));
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C']));
}
test_unit_classTypeAlias_typeParameters() {
ReferencedNames info = _computeReferencedNames('''
class U<T1, T2 extends D> = A<T1> with B<T2> implements C<T1, T2>;
''');
expect(info.names, unorderedEquals(['A', 'B', 'C', 'D']));
expect(info.superToSubs.keys, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs['A'], unorderedEquals(['U']));
expect(info.superToSubs['B'], unorderedEquals(['U']));
expect(info.superToSubs['C'], unorderedEquals(['U']));
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['U']));
expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C', 'D']));
}
test_unit_function() {
ReferencedNames info = _computeReferencedNames('''
A f(B b) {
C c = 0;
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['f']));
expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
}
test_unit_function_doc() {
ReferencedNames info = _computeReferencedNames('''
/**
* Documentation [C.d] reference.
*/
A f(B b) {}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['f']));
expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
}
test_unit_function_localFunctions() {
ReferencedNames info = _computeReferencedNames('''
A f() {
B b = null;
C g() {}
g();
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['f']));
expect(info.userToDependsOn['f'], unorderedEquals(['A']));
}
test_unit_function_localsDontHideQualified() {
ReferencedNames info = _computeReferencedNames('''
f(A a, B b) {
var v = 0;
a.v;
a.b;
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'v', 'b']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['f']));
expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
}
test_unit_function_localVariables() {
ReferencedNames info = _computeReferencedNames('''
A f() {
B b = null;
b;
{
C c = null;
b;
c;
}
d;
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['f']));
expect(info.userToDependsOn['f'], unorderedEquals(['A']));
}
test_unit_function_parameters() {
ReferencedNames info = _computeReferencedNames('''
A f(B b) {
C c = 0;
b;
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['f']));
expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
}
test_unit_function_typeParameters() {
ReferencedNames info = _computeReferencedNames('''
A f<T>(B b, T t) {
C c = 0;
}
''');
expect(info.names, unorderedEquals(['A', 'B', 'C']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['f']));
expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
}
test_unit_functionTypeAlias() {
ReferencedNames info = _computeReferencedNames('''
typedef A F(B B, C c(D d));
''');
expect(info.names, unorderedEquals(['A', 'B', 'C', 'D']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['F']));
expect(info.userToDependsOn['F'], unorderedEquals(['A', 'B', 'C', 'D']));
}
test_unit_functionTypeAlias_typeParameters() {
ReferencedNames info = _computeReferencedNames('''
typedef A F<T>(B b, T t);
''');
expect(info.names, unorderedEquals(['A', 'B']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['F']));
expect(info.userToDependsOn['F'], unorderedEquals(['A', 'B']));
}
test_unit_getter() {
ReferencedNames info = _computeReferencedNames('''
A get aaa {
return new B();
}
''');
expect(info.names, unorderedEquals(['A', 'B']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, unorderedEquals(['B']));
expect(info.userToDependsOn.keys, unorderedEquals(['aaa']));
expect(info.userToDependsOn['aaa'], unorderedEquals(['A']));
}
test_unit_setter() {
ReferencedNames info = _computeReferencedNames('''
set aaa(A a) {
B b = null;
}
''');
expect(info.names, unorderedEquals(['A', 'B']));
expect(info.superToSubs.keys, isEmpty);
expect(info.instantiatedNames, isEmpty);
expect(info.userToDependsOn.keys, unorderedEquals(['aaa']));
expect(info.userToDependsOn['aaa'], unorderedEquals(['A']));
}
ReferencedNames _computeReferencedNames(String code) {
Source source = newSource('/test.dart', code);
computeResult(source, REFERENCED_NAMES, matcher: isParseDartTask);
return outputs[REFERENCED_NAMES];
}
}
@reflectiveTest
class ResolveDirectiveElementsTaskTest extends _AbstractDartTaskTest {
test_perform() {