Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(501)

Unified Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 229653004: New analyzer snapshot with MapIterator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/parser.dart ('k') | pkg/analyzer/lib/src/generated/scanner.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/resolver.dart
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 44dcd88606b00fd62a2da49d270de85e2e56398d..3572534ff34ea85bbf495a25d873523021ecc9ae 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -16,6 +16,7 @@ import 'error.dart';
import 'scanner.dart' as sc;
import 'utilities_dart.dart';
import 'utilities_general.dart';
+import 'utilities_collection.dart';
import 'ast.dart';
import 'parser.dart' show Parser, ParserErrorCode;
import 'sdk.dart' show DartSdk, SdkLibrary;
@@ -242,11 +243,6 @@ class AngularCompilationUnitBuilder {
ClassElementImpl _classElement;
/**
- * The [ToolkitObjectElement]s to set for [classElement].
- */
- List<ToolkitObjectElement> _classToolkitObjects = [];
-
- /**
* The [Annotation] that is currently being analyzed.
*/
Annotation _annotation;
@@ -270,7 +266,6 @@ class AngularCompilationUnitBuilder {
if (unitMember is ClassDeclaration) {
this._classDeclaration = unitMember;
this._classElement = _classDeclaration.element as ClassElementImpl;
- this._classToolkitObjects.clear();
// process annotations
NodeList<Annotation> annotations = _classDeclaration.metadata;
for (Annotation annotation in annotations) {
@@ -300,11 +295,6 @@ class AngularCompilationUnitBuilder {
continue;
}
}
- // set toolkit objects
- if (!_classToolkitObjects.isEmpty) {
- List<ToolkitObjectElement> objects = _classToolkitObjects;
- _classElement.toolkitObjects = new List.from(objects);
- }
}
}
}
@@ -414,7 +404,7 @@ class AngularCompilationUnitBuilder {
element.styleUriOffset = styleUriOffset;
element.properties = _parseNgComponentProperties();
element.scopeProperties = _parseScopeProperties();
- _classToolkitObjects.add(element);
+ _classElement.addToolkitObjects(element);
}
}
@@ -566,7 +556,7 @@ class AngularCompilationUnitBuilder {
int nameOffset = _getStringArgumentOffset(_PUBLISH_AS);
AngularControllerElementImpl element = new AngularControllerElementImpl(name, nameOffset);
element.selector = selector;
- _classToolkitObjects.add(element);
+ _classElement.addToolkitObjects(element);
}
}
@@ -591,7 +581,7 @@ class AngularCompilationUnitBuilder {
AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offset);
element.selector = selector;
element.properties = _parseNgComponentProperties();
- _classToolkitObjects.add(element);
+ _classElement.addToolkitObjects(element);
}
}
@@ -606,7 +596,7 @@ class AngularCompilationUnitBuilder {
if (isValid) {
String name = _getStringArgument(_NAME);
int nameOffset = _getStringArgumentOffset(_NAME);
- _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset));
+ _classElement.addToolkitObjects(new AngularFilterElementImpl(name, nameOffset));
}
}
@@ -2206,20 +2196,120 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
}
/**
+ * Instances of the class `PolymerCompilationUnitBuilder` build a Polymer specific element
+ * model for a single compilation unit.
+ */
+class PolymerCompilationUnitBuilder {
+ static String _CUSTOM_TAG = "CustomTag";
+
+ static Element getElement(AstNode node, int offset) {
+ // maybe node is not SimpleStringLiteral
+ if (node is! SimpleStringLiteral) {
+ return null;
+ }
+ SimpleStringLiteral literal = node as SimpleStringLiteral;
+ // maybe has PolymerElement
+ {
+ Element element = literal.toolkitElement;
+ if (element is PolymerElement) {
+ return element;
+ }
+ }
+ // no Element
+ return null;
+ }
+
+ /**
+ * The compilation unit with built Dart element models.
+ */
+ final CompilationUnit _unit;
+
+ /**
+ * The [ClassDeclaration] that is currently being analyzed.
+ */
+ ClassDeclaration _classDeclaration;
+
+ /**
+ * The [ClassElementImpl] that is currently being analyzed.
+ */
+ ClassElementImpl _classElement;
+
+ /**
+ * The [Annotation] that is currently being analyzed.
+ */
+ Annotation _annotation;
+
+ /**
+ * Initialize a newly created compilation unit element builder.
+ *
+ * @param unit the compilation unit with built Dart element models
+ */
+ PolymerCompilationUnitBuilder(this._unit);
+
+ /**
+ * Builds Polymer specific element models and adds them to the existing Dart elements.
+ */
+ void build() {
+ // process classes
+ for (CompilationUnitMember unitMember in _unit.declarations) {
+ if (unitMember is ClassDeclaration) {
+ this._classDeclaration = unitMember;
+ this._classElement = _classDeclaration.element as ClassElementImpl;
+ // process annotations
+ NodeList<Annotation> annotations = _classDeclaration.metadata;
+ for (Annotation annotation in annotations) {
+ // verify annotation
+ if (annotation.arguments == null) {
+ continue;
+ }
+ this._annotation = annotation;
+ // @CustomTag
+ if (_isAnnotation(annotation, _CUSTOM_TAG)) {
+ _parseCustomTag();
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if given [Annotation] is an annotation with required name.
+ */
+ bool _isAnnotation(Annotation annotation, String name) {
+ Element element = annotation.element;
+ if (element is ConstructorElement) {
+ ConstructorElement constructorElement = element;
+ return constructorElement.returnType.displayName == name;
+ }
+ return false;
+ }
+
+ void _parseCustomTag() {
+ List<Expression> arguments = _annotation.arguments.arguments;
+ if (arguments.length == 1) {
+ Expression nameExpression = arguments[0];
+ if (nameExpression is SimpleStringLiteral) {
+ SimpleStringLiteral nameLiteral = nameExpression;
+ String name = nameLiteral.value;
+ int nameOffset = nameLiteral.valueOffset;
+ PolymerTagDartElementImpl element = new PolymerTagDartElementImpl(name, nameOffset, _classElement);
+ _classElement.addToolkitObjects(element);
+ nameLiteral.toolkitElement = element;
+ }
+ }
+ }
+}
+
+/**
* Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
* violations of Dart best practices.
*/
class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
- static String _GETTER = "getter";
-
static String _HASHCODE_GETTER_NAME = "hashCode";
- static String _METHOD = "method";
-
static String _NULL_TYPE_NAME = "Null";
- static String _SETTER = "setter";
-
static String _TO_INT_METHOD_NAME = "toInt";
/**
@@ -2273,10 +2363,11 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
@override
Object visitAssignmentExpression(AssignmentExpression node) {
sc.TokenType operatorType = node.operator.type;
- if (operatorType != sc.TokenType.EQ) {
- _checkForDeprecatedMemberUse(node.bestElement, node);
- } else {
+ if (operatorType == sc.TokenType.EQ) {
_checkForUseOfVoidResult(node.rightHandSide);
+ _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
+ } else {
+ _checkForDeprecatedMemberUse(node.bestElement, node);
}
return super.visitAssignmentExpression(node);
}
@@ -2378,6 +2469,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
@override
Object visitVariableDeclaration(VariableDeclaration node) {
_checkForUseOfVoidResult(node.initializer);
+ _checkForInvalidAssignment(node.name, node.initializer);
return super.visitVariableDeclaration(node);
}
@@ -2623,6 +2715,44 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * This verifies that the passed left hand side and right hand side represent a valid assignment.
+ *
+ * This method corresponds to ErrorVerifier.checkForInvalidAssignment.
+ *
+ * @param lhs the left hand side expression
+ * @param rhs the right hand side expression
+ * @return `true` if and only if an error code is generated on the passed node
+ * @see HintCode#INVALID_ASSIGNMENT
+ */
+ bool _checkForInvalidAssignment(Expression lhs, Expression rhs) {
+ if (lhs == null || rhs == null) {
+ return false;
+ }
+ VariableElement leftElement = ErrorVerifier.getVariableElement(lhs);
+ DartType leftType = (leftElement == null) ? ErrorVerifier.getStaticType(lhs) : leftElement.type;
+ DartType staticRightType = ErrorVerifier.getStaticType(rhs);
+ if (!staticRightType.isAssignableTo(leftType)) {
+ // The warning was generated on this rhs
+ return false;
+ }
+ // Test for, and then generate the hint
+ DartType bestRightType = rhs.bestType;
+ if (leftType != null && bestRightType != null) {
+ if (!bestRightType.isAssignableTo(leftType)) {
+ String leftName = leftType.displayName;
+ String rightName = bestRightType.displayName;
+ if (leftName == rightName) {
+ leftName = ErrorVerifier.getExtendedDisplayName(leftType);
+ rightName = ErrorVerifier.getExtendedDisplayName(bestRightType);
+ }
+ _errorReporter.reportErrorForNode(HintCode.INVALID_ASSIGNMENT, rhs, [rightName, leftName]);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Generate a hint for functions or methods that have a return type, but do not have a return
* statement on all branches. At the end of blocks with no return, Dart implicitly returns
* `null`, avoiding these implicit returns is considered a best practice.
@@ -2680,75 +2810,6 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
}
/**
- * Checks that if the passed method declaration is private, it does not override a private member
- * in a superclass.
- *
- * @param node the method declaration to check
- * @return `true` if and only if a hint code is generated on the passed node
- * @see HintCode#OVERRIDDING_PRIVATE_MEMBER
- */
- bool _checkForOverridingPrivateMember(MethodDeclaration node) {
- // If not in an enclosing class, return false
- if (_enclosingClass == null) {
- return false;
- }
- // If the member is not private, return false
- if (!Identifier.isPrivateName(node.name.name)) {
- return false;
- }
- // Get the element of the member, if null, return false
- ExecutableElement executableElement = node.element;
- if (executableElement == null) {
- return false;
- }
- // Loop through all of the superclasses looking for a matching method or accessor
- // TODO(jwren) If the HintGenerator needs or has easy access to the InheritanceManager in the
- // future then this could be refactored down to be more readable, however, since we are only
- // looking through super classes (and not the entire interface graph) there is no pressing need
- String elementName = executableElement.name;
- bool isGetterOrSetter = executableElement is PropertyAccessorElement;
- InterfaceType superType = _enclosingClass.supertype;
- if (superType == null) {
- return false;
- }
- ClassElement classElement = superType.element;
- while (classElement != null) {
- if (_enclosingClass.library != classElement.library) {
- if (isGetterOrSetter) {
- PropertyAccessorElement overriddenAccessor = null;
- List<PropertyAccessorElement> accessors = classElement.accessors;
- for (PropertyAccessorElement propertyAccessorElement in accessors) {
- if (elementName == propertyAccessorElement.name) {
- overriddenAccessor = propertyAccessorElement;
- break;
- }
- }
- if (overriddenAccessor != null) {
- String memberType = (executableElement as PropertyAccessorElement).isGetter ? _GETTER : _SETTER;
- _errorReporter.reportErrorForNode(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
- memberType,
- executableElement.displayName,
- classElement.displayName]);
- return true;
- }
- } else {
- MethodElement overriddenMethod = classElement.getMethod(elementName);
- if (overriddenMethod != null) {
- _errorReporter.reportErrorForNode(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
- _METHOD,
- executableElement.displayName,
- classElement.displayName]);
- return true;
- }
- }
- }
- superType = classElement.supertype;
- classElement = superType != null ? superType.element : null;
- }
- return false;
- }
-
- /**
* Check for the passed as expression for the [HintCode#UNNECESSARY_CAST] hint code.
*
* @param node the as expression to check
@@ -3000,10 +3061,10 @@ class DeadCodeVerifier extends RecursiveAstVisitor<Object> {
if (currentType.isObject) {
// Found catch clause clause that has Object as an exception type, this is equivalent to
// having a catch clause that doesn't have an exception type, visit the block, but
- // generate an error on any following catch clauses (and don't visit them).
+ // generate an error on any following catch clauses (and don't visit them).
_safelyVisit(catchClause);
if (i + 1 != numOfCatchClauses) {
- // this catch clause is not the last in the try statement
+ // this catch clause is not the last in the try statement
CatchClause nextCatchClause = catchClauses[i + 1];
CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
int offset = nextCatchClause.offset;
@@ -3025,7 +3086,7 @@ class DeadCodeVerifier extends RecursiveAstVisitor<Object> {
}
_safelyVisit(catchClause);
} else {
- // Found catch clause clause that doesn't have an exception type, visit the block, but
+ // Found catch clause clause that doesn't have an exception type, visit the block, but
// generate an error on any following catch clauses (and don't visit them).
_safelyVisit(catchClause);
if (i + 1 != numOfCatchClauses) {
@@ -3080,24 +3141,15 @@ class DeadCodeVerifier extends RecursiveAstVisitor<Object> {
}
// Don't consider situations where we could evaluate to a constant boolean expression with the
// ConstantVisitor
-//
- // else {
-//
- // EvaluationResultImpl result = expression.accept(new ConstantVisitor());
-//
- // if (result == ValidResult.RESULT_TRUE) {
-//
- // return ValidResult.RESULT_TRUE;
-//
- // } else if (result == ValidResult.RESULT_FALSE) {
-//
- // return ValidResult.RESULT_FALSE;
-//
- // }
-//
- // return null;
-//
- // }
+ // else {
+ // EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+ // if (result == ValidResult.RESULT_TRUE) {
+ // return ValidResult.RESULT_TRUE;
+ // } else if (result == ValidResult.RESULT_FALSE) {
+ // return ValidResult.RESULT_FALSE;
+ // }
+ // return null;
+ // }
return null;
}
@@ -8581,9 +8633,9 @@ class InheritanceManager {
//
// Loop through the entries in the unionMap, adding them to the resultMap appropriately.
//
- for (MapEntry<String, List<ExecutableElement>> entry in getMapEntrySet(unionMap)) {
- String key = entry.getKey();
- List<ExecutableElement> list = entry.getValue();
+ for (MapIterator<String, List<ExecutableElement>> iter = SingleMapIterator.forMap(unionMap); iter.moveNext();) {
+ String key = iter.key;
+ List<ExecutableElement> list = iter.value;
int numOfEltsWithMatchingNames = list.length;
if (numOfEltsWithMatchingNames == 1) {
//
@@ -8659,12 +8711,30 @@ class InheritanceManager {
} else {
if (subtypesOfAllOtherTypesIndexes.isEmpty) {
//
+ // Determine if the current class has a method or accessor with the member name, if it
+ // does then then this class does not "inherit" from any of the supertypes.
+ // See issue 16134.
+ //
+ bool classHasMember = false;
+ if (allMethods) {
+ classHasMember = classElt.getMethod(key) != null;
+ } else {
+ List<PropertyAccessorElement> accessors = classElt.accessors;
+ for (int i = 0; i < accessors.length; i++) {
+ if (accessors[i].name == key) {
+ classHasMember = true;
+ }
+ }
+ }
+ //
// Example: class A inherited only 2 method named 'm'. One has the function type
// '() -> int' and one has the function type '() -> String'. Since neither is a subtype
// of the other, we create a warning, and have this class inherit nothing.
//
- String firstTwoFuntionTypesStr = "${executableElementTypes[0].toString()}, ${executableElementTypes[1].toString()}";
- _reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFuntionTypesStr]);
+ if (!classHasMember) {
+ String firstTwoFuntionTypesStr = "${executableElementTypes[0].toString()}, ${executableElementTypes[1].toString()}";
+ _reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFuntionTypesStr]);
+ }
} else {
//
// Example: class A inherits 2 methods named 'm'. One has the function type
@@ -9725,6 +9795,7 @@ class LibraryResolver {
importElement.uriOffset = uriLiteral.offset;
importElement.uriEnd = uriLiteral.end;
importElement.uri = uriContent;
+ importElement.deferred = importDirective.deferredToken != null;
importElement.combinators = _buildCombinators(importDirective);
LibraryElement importedLibraryElement = importedLibrary.libraryElement;
if (importedLibraryElement != null) {
@@ -10074,6 +10145,16 @@ class LibraryResolver {
} finally {
timeCounter.stop();
}
+ // Polymer
+ timeCounter = PerformanceStatistics.polymer.start();
+ try {
+ for (Source source in library.compilationUnitSources) {
+ CompilationUnit ast = library.getAST(source);
+ new PolymerCompilationUnitBuilder(ast).build();
+ }
+ } finally {
+ timeCounter.stop();
+ }
}
/**
@@ -10296,6 +10377,7 @@ class LibraryResolver2 {
importElement.uriEnd = uriLiteral.end;
}
importElement.uri = uriContent;
+ importElement.deferred = importDirective.deferredToken != null;
importElement.combinators = _buildCombinators(importDirective);
LibraryElement importedLibraryElement = importedLibrary.libraryElement;
if (importedLibraryElement != null) {
@@ -10505,6 +10587,16 @@ class LibraryResolver2 {
} finally {
timeCounter.stop();
}
+ // Polymer
+ timeCounter = PerformanceStatistics.polymer.start();
+ try {
+ for (Source source in library.compilationUnitSources) {
+ CompilationUnit ast = library.getAST(source);
+ new PolymerCompilationUnitBuilder(ast).build();
+ }
+ } finally {
+ timeCounter.stop();
+ }
}
}
@@ -14902,8 +14994,8 @@ class TypeOverrideManager_TypeOverrideScope {
* @param overrides the overrides to be applied
*/
void applyOverrides(Map<Element, DartType> overrides) {
- for (MapEntry<Element, DartType> entry in getMapEntrySet(overrides)) {
- _overridenTypes[entry.getKey()] = entry.getValue();
+ for (MapIterator<Element, DartType> iter = SingleMapIterator.forMap(overrides); iter.moveNext();) {
+ _overridenTypes[iter.key] = iter.value;
}
}
@@ -17253,8 +17345,8 @@ class NamespaceBuilder {
* @param namespace the namespace containing the names to be added to this namespace
*/
void _addAllFromMap(Map<String, Element> definedNames, Map<String, Element> newNames) {
- for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) {
- definedNames[entry.getKey()] = entry.getValue();
+ for (MapIterator<String, Element> iter = SingleMapIterator.forMap(newNames); iter.moveNext();) {
+ definedNames[iter.key] = iter.value;
}
}
@@ -17336,8 +17428,8 @@ class NamespaceBuilder {
if (prefixElement != null) {
String prefix = prefixElement.name;
Map<String, Element> newNames = new Map<String, Element>();
- for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) {
- newNames["${prefix}.${entry.getKey()}"] = entry.getValue();
+ for (MapIterator<String, Element> iter = SingleMapIterator.forMap(definedNames); iter.moveNext();) {
+ newNames["${prefix}.${iter.key}"] = iter.value;
}
return newNames;
} else {
@@ -18086,6 +18178,56 @@ class ConstantVisitor_ConstantVerifier_validateInitializerExpression extends Con
*/
class ErrorVerifier extends RecursiveAstVisitor<Object> {
/**
+ * Return a display name for the given type that includes the path to the compilation unit in
+ * which the type is defined.
+ *
+ * @param type the type for which an extended display name is to be returned
+ * @return a display name that can help distiguish between two types with the same name
+ */
+ static String getExtendedDisplayName(DartType type) {
+ Element element = type.element;
+ if (element != null) {
+ Source source = element.source;
+ if (source != null) {
+ return "${type.displayName} (${source.fullName})";
+ }
+ }
+ return type.displayName;
+ }
+
+ /**
+ * Return the static type of the given expression that is to be used for type analysis.
+ *
+ * @param expression the expression whose type is to be returned
+ * @return the static type of the given expression
+ */
+ static DartType getStaticType(Expression expression) {
+ DartType type = expression.staticType;
+ if (type == null) {
+ // TODO(brianwilkerson) This should never happen.
+ return DynamicTypeImpl.instance;
+ }
+ return type;
+ }
+
+ /**
+ * Return the variable element represented by the given expression, or `null` if there is no
+ * such element.
+ *
+ * @param expression the expression whose element is to be returned
+ * @return the variable element represented by the expression
+ */
+ static VariableElement getVariableElement(Expression expression) {
+ if (expression is Identifier) {
+ Element element = expression.staticElement;
+ if (element is VariableElement) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ /**
* The error reporter by which errors will be reported.
*/
final ErrorReporter _errorReporter;
@@ -18096,11 +18238,6 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
final LibraryElement _currentLibrary;
/**
- * The type representing the type 'dynamic'.
- */
- DartType _dynamicType;
-
- /**
* The type representing the type 'bool'.
*/
InterfaceType _boolType;
@@ -18308,7 +18445,6 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
_isInInstanceVariableInitializer = false;
_isInConstructorInitializer = false;
_isInStaticMethod = false;
- _dynamicType = _typeProvider.dynamicType;
_boolType = _typeProvider.boolType;
_intType = _typeProvider.intType;
_DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [
@@ -18334,8 +18470,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
@override
Object visitAssignmentExpression(AssignmentExpression node) {
- sc.Token operator = node.operator;
- sc.TokenType operatorType = operator.type;
+ sc.TokenType operatorType = node.operator.type;
if (operatorType == sc.TokenType.EQ) {
_checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
} else {
@@ -18400,9 +18535,9 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
try {
_isInNativeClass = node.nativeClause != null;
_enclosingClass = node.element;
- WithClause withClause = node.withClause;
- ImplementsClause implementsClause = node.implementsClause;
ExtendsClause extendsClause = node.extendsClause;
+ ImplementsClause implementsClause = node.implementsClause;
+ WithClause withClause = node.withClause;
_checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
_checkForMemberWithClassName();
_checkForNoDefaultSuperConstructorImplicit(node);
@@ -18412,7 +18547,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
// Only check for all of the inheritance logic around clauses if there isn't an error code
// such as "Cannot extend double" already on the class.
if (!_checkForImplementsDisallowedClass(implementsClause) && !_checkForExtendsDisallowedClass(extendsClause) && !_checkForAllMixinErrorCodes(withClause)) {
- _checkForNonAbstractClassInheritsAbstractMember(node);
+ _checkForNonAbstractClassInheritsAbstractMember(node.name);
_checkForInconsistentMethodInheritance();
_checkForRecursiveInterfaceInheritance(_enclosingClass);
_checkForConflictingGetterAndMethod();
@@ -18446,14 +18581,16 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
@override
Object visitClassTypeAlias(ClassTypeAlias node) {
_checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
- _checkForExtendsDisallowedClassInTypeAlias(node);
- _checkForImplementsDisallowedClass(node.implementsClause);
- _checkForAllMixinErrorCodes(node.withClause);
ClassElement outerClassElement = _enclosingClass;
try {
_enclosingClass = node.element;
- _checkForRecursiveInterfaceInheritance(node.element);
- _checkForTypeAliasCannotReferenceItself_mixin(node);
+ // Only check for all of the inheritance logic around clauses if there isn't an error code
+ // such as "Cannot extend double" already on the class.
+ if (!_checkForExtendsDisallowedClassInTypeAlias(node) && !_checkForImplementsDisallowedClass(node.implementsClause) && !_checkForAllMixinErrorCodes(node.withClause)) {
+ _checkForRecursiveInterfaceInheritance(node.element);
+ _checkForTypeAliasCannotReferenceItself_mixin(node);
+ _checkForNonAbstractClassInheritsAbstractMember(node.name);
+ }
} finally {
_enclosingClass = outerClassElement;
}
@@ -18471,6 +18608,12 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
@override
+ Object visitCompilationUnit(CompilationUnit node) {
+ _checkForDeferredPrefixCollisions(node);
+ return super.visitCompilationUnit(node);
+ }
+
+ @override
Object visitConditionalExpression(ConditionalExpression node) {
_checkForNonBoolCondition(node.condition);
return super.visitConditionalExpression(node);
@@ -18671,6 +18814,9 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (importElement != null) {
_checkForImportDuplicateLibraryName(node, importElement);
_checkForImportInternalLibrary(node, importElement);
+ if (importElement.isDeferred) {
+ _checkForLoadLibraryFunction(node, importElement);
+ }
}
return super.visitImportDirective(node);
}
@@ -19073,9 +19219,9 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
}
// Visit all of the states in the map to ensure that none were never initialized.
- for (MapEntry<FieldElement, INIT_STATE> entry in getMapEntrySet(fieldElementsMap)) {
- if (entry.getValue() == INIT_STATE.NOT_INIT) {
- FieldElement fieldElement = entry.getKey();
+ for (MapIterator<FieldElement, INIT_STATE> iter = SingleMapIterator.forMap(fieldElementsMap); iter.moveNext();) {
+ if (iter.value == INIT_STATE.NOT_INIT) {
+ FieldElement fieldElement = iter.key;
if (fieldElement.isConst) {
_errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
foundError = true;
@@ -19249,22 +19395,21 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
parameterIndex++;
}
// SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
- JavaIterator<MapEntry<String, DartType>> overriddenNamedPTIterator = new JavaIterator(getMapEntrySet(overriddenNamedPT));
- while (overriddenNamedPTIterator.hasNext) {
- MapEntry<String, DartType> overriddenNamedPTEntry = overriddenNamedPTIterator.next();
- DartType overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey()];
+ MapIterator<String, DartType> overriddenNamedPTIterator = SingleMapIterator.forMap(overriddenNamedPT);
+ while (overriddenNamedPTIterator.moveNext()) {
+ DartType overridingType = overridingNamedPT[overriddenNamedPTIterator.key];
if (overridingType == null) {
// Error, this is never reached- INVALID_OVERRIDE_NAMED would have been created above if
// this could be reached.
continue;
}
- if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) {
+ if (!overriddenNamedPTIterator.value.isAssignableTo(overridingType)) {
// lookup the parameter for the error to select
ParameterElement parameterToSelect = null;
AstNode parameterLocationToSelect = null;
for (int i = 0; i < parameters.length; i++) {
ParameterElement parameter = parameters[i];
- if (parameter.parameterKind == ParameterKind.NAMED && overriddenNamedPTEntry.getKey() == parameter.name) {
+ if (parameter.parameterKind == ParameterKind.NAMED && overriddenNamedPTIterator.key == parameter.name) {
parameterToSelect = parameter;
parameterLocationToSelect = parameterLocations[i];
break;
@@ -19273,7 +19418,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (parameterToSelect != null) {
_errorReporter.reportErrorForNode(StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, parameterLocationToSelect, [
overridingType.displayName,
- overriddenNamedPTEntry.getValue().displayName,
+ overriddenNamedPTIterator.value.displayName,
overriddenExecutable.enclosingElement.displayName]);
return true;
}
@@ -19611,9 +19756,9 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
// check exported names
Namespace namespace = new NamespaceBuilder().createExportNamespaceForDirective(exportElement);
Map<String, Element> definedNames = namespace.definedNames;
- for (MapEntry<String, Element> definedEntry in getMapEntrySet(definedNames)) {
- String name = definedEntry.getKey();
- Element element = definedEntry.getValue();
+ for (MapIterator<String, Element> iter = SingleMapIterator.forMap(definedNames); iter.moveNext();) {
+ String name = iter.key;
+ Element element = iter.value;
Element prevElement = _exportedElements[name];
if (element != null && prevElement != null && prevElement != element) {
_errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node, [
@@ -19699,7 +19844,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
* @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
* @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
*/
- bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, DartType expectedStaticType, ErrorCode errorCode) => _checkForArgumentTypeNotAssignable(expression, expectedStaticType, _getStaticType(expression), errorCode);
+ bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, DartType expectedStaticType, ErrorCode errorCode) => _checkForArgumentTypeNotAssignable(expression, expectedStaticType, getStaticType(expression), errorCode);
/**
* This verifies that the passed arguments can be assigned to their corresponding parameters.
@@ -20552,6 +20697,47 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * This verifies that any deferred imports in the given compilation unit have a unique prefix.
+ *
+ * @param node the compilation unit containing the imports to be checked
+ * @return `true` if an error was generated
+ * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
+ */
+ bool _checkForDeferredPrefixCollisions(CompilationUnit node) {
+ bool foundError = false;
+ NodeList<Directive> directives = node.directives;
+ int count = directives.length;
+ if (count > 0) {
+ Map<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = new Map<PrefixElement, List<ImportDirective>>();
+ for (int i = 0; i < count; i++) {
+ Directive directive = directives[i];
+ if (directive is ImportDirective) {
+ ImportDirective importDirective = directive;
+ SimpleIdentifier prefix = importDirective.prefix;
+ if (prefix != null) {
+ Element element = prefix.staticElement;
+ if (element is PrefixElement) {
+ PrefixElement prefixElement = element;
+ List<ImportDirective> elements = prefixToDirectivesMap[prefixElement];
+ if (elements == null) {
+ elements = new List<ImportDirective>();
+ prefixToDirectivesMap[prefixElement] = elements;
+ }
+ elements.add(importDirective);
+ }
+ }
+ }
+ }
+ for (List<ImportDirective> imports in prefixToDirectivesMap.values) {
+ if (_hasDeferredPrefixCollision(imports)) {
+ foundError = true;
+ }
+ }
+ }
+ return foundError;
+ }
+
+ /**
* This verifies that the enclosing class does not have an instance member with the given name of
* the static member.
*
@@ -20785,7 +20971,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
return false;
}
// test the static type of the expression
- DartType staticType = _getStaticType(expression);
+ DartType staticType = getStaticType(expression);
if (staticType == null) {
return false;
}
@@ -21159,31 +21345,19 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (lhs == null || rhs == null) {
return false;
}
- VariableElement leftElement = _getVariableElement(lhs);
- DartType leftType = (leftElement == null) ? _getStaticType(lhs) : leftElement.type;
- DartType staticRightType = _getStaticType(rhs);
- bool isStaticAssignable = staticRightType.isAssignableTo(leftType);
- if (!isStaticAssignable) {
+ VariableElement leftElement = getVariableElement(lhs);
+ DartType leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.type;
+ DartType staticRightType = getStaticType(rhs);
+ if (!staticRightType.isAssignableTo(leftType)) {
String leftName = leftType.displayName;
String rightName = staticRightType.displayName;
if (leftName == rightName) {
- leftName = _getExtendedDisplayName(leftType);
- rightName = _getExtendedDisplayName(staticRightType);
+ leftName = getExtendedDisplayName(leftType);
+ rightName = getExtendedDisplayName(staticRightType);
}
_errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightName, leftName]);
return true;
}
- // TODO(brianwilkerson) Define a hint corresponding to the warning and report it if appropriate.
- // Type propagatedRightType = rhs.getPropagatedType();
- // boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(leftType);
- // if (!isStaticAssignable && !isPropagatedAssignable) {
- // errorReporter.reportError(
- // StaticTypeWarningCode.INVALID_ASSIGNMENT,
- // rhs,
- // staticRightType.getDisplayName(),
- // leftType.getDisplayName());
- // return true;
- // }
return false;
}
@@ -21200,8 +21374,8 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (lhs == null) {
return false;
}
- VariableElement leftElement = _getVariableElement(lhs);
- DartType leftType = (leftElement == null) ? _getStaticType(lhs) : leftElement.type;
+ VariableElement leftElement = getVariableElement(lhs);
+ DartType leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.type;
MethodElement invokedMethod = node.staticElement;
if (invokedMethod == null) {
return false;
@@ -21214,8 +21388,8 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
String leftName = leftType.displayName;
String rightName = rightType.displayName;
if (leftName == rightName) {
- leftName = _getExtendedDisplayName(leftType);
- rightName = _getExtendedDisplayName(rightType);
+ leftName = getExtendedDisplayName(leftType);
+ rightName = getExtendedDisplayName(rightType);
}
_errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, node.rightHandSide, [rightName, leftName]);
return true;
@@ -21316,6 +21490,26 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * Check that the imported library does not define a loadLibrary function.
+ *
+ * @param node the import directive to evaluate
+ * @param importElement the [ImportElement] retrieved from the node
+ * @return `true` if and only if an error code is generated on the passed node
+ * @see CompileTimeErrorCode#IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION
+ */
+ bool _checkForLoadLibraryFunction(ImportDirective node, ImportElement importElement) {
+ LibraryElement importedLibrary = importElement.importedLibrary;
+ if (importedLibrary == null) {
+ return false;
+ }
+ if (importedLibrary.hasLoadLibraryFunction) {
+ _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, node, [importedLibrary.name]);
+ return true;
+ }
+ return false;
+ }
+
+ /**
* This verifies that the key/value of entries of the given [MapLiteral] are subtypes of the
* key/value types specified in the type arguments.
*
@@ -21657,7 +21851,8 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
* This checks that passed class declaration overrides all members required by its superclasses
* and interfaces.
*
- * @param node the [ClassDeclaration] to evaluate
+ * @param classNameNode the [SimpleIdentifier] to be used if there is a violation, this is
+ * either the named from the [ClassDeclaration] or from the [ClassTypeAlias].
* @return `true` if and only if an error code is generated on the passed node
* @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
* @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
@@ -21665,7 +21860,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
* @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR
* @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS
*/
- bool _checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) {
+ bool _checkForNonAbstractClassInheritsAbstractMember(SimpleIdentifier classNameNode) {
if (_enclosingClass.isAbstract) {
return false;
}
@@ -21673,8 +21868,6 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
// Store in local sets the set of all method and accessor names
//
List<MethodElement> methods = _enclosingClass.methods;
- List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
- Set<String> methodsInEnclosingClass = new Set<String>();
for (MethodElement method in methods) {
String methodName = method.name;
// If the enclosing class declares the method noSuchMethod(), then return.
@@ -21684,11 +21877,6 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (methodName == ElementResolver.NO_SUCH_METHOD_METHOD_NAME) {
return false;
}
- methodsInEnclosingClass.add(methodName);
- }
- Set<String> accessorsInEnclosingClass = new Set<String>();
- for (PropertyAccessorElement accessor in accessors) {
- accessorsInEnclosingClass.add(accessor.name);
}
Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>();
//
@@ -21773,22 +21961,22 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
List<String> stringMembersArray = new List.from(stringMembersArrayListSet);
AnalysisErrorWithProperties analysisError;
if (stringMembersArray.length == 1) {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, node.name, [stringMembersArray[0]]);
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, classNameNode, [stringMembersArray[0]]);
} else if (stringMembersArray.length == 2) {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, node.name, [stringMembersArray[0], stringMembersArray[1]]);
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, classNameNode, [stringMembersArray[0], stringMembersArray[1]]);
} else if (stringMembersArray.length == 3) {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, node.name, [
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, classNameNode, [
stringMembersArray[0],
stringMembersArray[1],
stringMembersArray[2]]);
} else if (stringMembersArray.length == 4) {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, node.name, [
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, classNameNode, [
stringMembersArray[0],
stringMembersArray[1],
stringMembersArray[2],
stringMembersArray[3]]);
} else {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, node.name, [
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, classNameNode, [
stringMembersArray[0],
stringMembersArray[1],
stringMembersArray[2],
@@ -21809,7 +21997,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
* @see StaticTypeWarningCode#NON_BOOL_CONDITION
*/
bool _checkForNonBoolCondition(Expression condition) {
- DartType conditionType = _getStaticType(condition);
+ DartType conditionType = getStaticType(condition);
if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
_errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_CONDITION, condition, []);
return true;
@@ -21826,7 +22014,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
*/
bool _checkForNonBoolExpression(AssertStatement node) {
Expression expression = node.condition;
- DartType type = _getStaticType(expression);
+ DartType type = getStaticType(expression);
if (type is InterfaceType) {
if (!type.isAssignableTo(_boolType)) {
_errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
@@ -21850,7 +22038,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
* @see StaticTypeWarningCode#NON_BOOL_NEGATION_EXPRESSION
*/
bool _checkForNonBoolNegationExpression(Expression expression) {
- DartType conditionType = _getStaticType(expression);
+ DartType conditionType = getStaticType(expression);
if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
_errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression, []);
return true;
@@ -22193,7 +22381,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
* @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
*/
bool _checkForReturnOfInvalidType(Expression returnExpression, DartType expectedReturnType) {
- DartType staticReturnType = _getStaticType(returnExpression);
+ DartType staticReturnType = getStaticType(returnExpression);
if (expectedReturnType.isVoid) {
if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnType.isBottom) {
return false;
@@ -22257,7 +22445,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) {
// prepare 'switch' expression type
Expression expression = node.expression;
- DartType expressionType = _getStaticType(expression);
+ DartType expressionType = getStaticType(expression);
if (expressionType == null) {
return false;
}
@@ -22270,7 +22458,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
SwitchCase switchCase = switchMember as SwitchCase;
// prepare 'case' type
Expression caseExpression = switchCase.expression;
- DartType caseType = _getStaticType(caseExpression);
+ DartType caseType = getStaticType(caseExpression);
// check types
if (expressionType.isAssignableTo(caseType)) {
return false;
@@ -22667,24 +22855,6 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/**
- * Return a display name for the given type that includes the path to the compilation unit in
- * which the type is defined.
- *
- * @param type the type for which an extended display name is to be returned
- * @return a display name that can help distiguish between two types with the same name
- */
- String _getExtendedDisplayName(DartType type) {
- Element element = type.element;
- if (element != null) {
- Source source = element.source;
- if (source != null) {
- return "${type.displayName} (${source.fullName})";
- }
- }
- return type.displayName;
- }
-
- /**
* Returns the Type (return type) for a given getter.
*
* @param propertyAccessorElement
@@ -22716,35 +22886,26 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/**
- * Return the static type of the given expression that is to be used for type analysis.
- *
- * @param expression the expression whose type is to be returned
- * @return the static type of the given expression
- */
- DartType _getStaticType(Expression expression) {
- DartType type = expression.staticType;
- if (type == null) {
- // TODO(brianwilkerson) This should never happen.
- return _dynamicType;
- }
- return type;
- }
-
- /**
- * Return the variable element represented by the given expression, or `null` if there is no
- * such element.
+ * Given a list of directives that have the same prefix, generate an error if there is more than
+ * one import and any of those imports is deferred.
*
- * @param expression the expression whose element is to be returned
- * @return the variable element represented by the expression
+ * @param directives the list of directives that have the same prefix
+ * @return `true` if an error was generated
+ * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
*/
- VariableElement _getVariableElement(Expression expression) {
- if (expression is Identifier) {
- Element element = expression.staticElement;
- if (element is VariableElement) {
- return element;
+ bool _hasDeferredPrefixCollision(List<ImportDirective> directives) {
+ bool foundError = false;
+ int count = directives.length;
+ if (count > 1) {
+ for (int i = 0; i < count; i++) {
+ sc.Token deferredToken = directives[i].deferredToken;
+ if (deferredToken != null) {
+ _errorReporter.reportErrorForToken(CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken, []);
+ foundError = true;
+ }
}
}
- return null;
+ return foundError;
}
/**
@@ -22842,7 +23003,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
/**
* Return `true` iff the passed [ClassElement] has a method, getter or setter that
* matches the name of the passed [ExecutableElement] in either the class itself, or one of
- * its' mixins.
+ * its' mixins that is concrete.
*
* By "match", only the name of the member is tested to match, it does not have to equal or be a
* subtype of the passed executable element, this is due to the specific use where this method is
@@ -22857,14 +23018,14 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
String executableName = executableElt.name;
if (executableElt is MethodElement) {
foundElt = classElt.getMethod(executableName);
- if (foundElt != null) {
+ if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
return true;
}
List<InterfaceType> mixins = classElt.mixins;
for (int i = 0; i < mixins.length && foundElt == null; i++) {
foundElt = mixins[i].getMethod(executableName);
}
- if (foundElt != null) {
+ if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
return true;
}
} else if (executableElt is PropertyAccessorElement) {
@@ -22875,7 +23036,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (foundElt == null && propertyAccessorElement.isSetter) {
foundElt = classElt.getSetter(executableName);
}
- if (foundElt != null) {
+ if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
return true;
}
List<InterfaceType> mixins = classElt.mixins;
@@ -22885,7 +23046,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
foundElt = mixins[i].getSetter(executableName);
}
}
- if (foundElt != null) {
+ if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
return true;
}
}
« no previous file with comments | « pkg/analyzer/lib/src/generated/parser.dart ('k') | pkg/analyzer/lib/src/generated/scanner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698