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

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

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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 | « packages/analyzer/lib/src/generated/parser.dart ('k') | packages/analyzer/lib/src/generated/scanner.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: packages/analyzer/lib/src/generated/resolver.dart
diff --git a/analyzer/lib/src/generated/resolver.dart b/packages/analyzer/lib/src/generated/resolver.dart
similarity index 92%
rename from analyzer/lib/src/generated/resolver.dart
rename to packages/analyzer/lib/src/generated/resolver.dart
index 49fc6c797dbba3b06d1751515bcc705ed477f46f..a5b2e92abb20313d3747f572a60bcc6e17006206 100644
--- a/analyzer/lib/src/generated/resolver.dart
+++ b/packages/analyzer/lib/src/generated/resolver.dart
@@ -44,6 +44,10 @@ typedef TypeResolverVisitor TypeResolverVisitorFactory(
typedef void VoidFunction();
+typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
+
+typedef bool _SubtypeChecker<T>(T t1, T t2);
+
/**
* Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
* violations of Dart best practices.
@@ -73,12 +77,19 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
final InterfaceType _futureNullType;
/**
+ * The type system primitives
+ */
+ TypeSystem _typeSystem;
+
+ /**
* Create a new instance of the [BestPracticesVerifier].
*
* @param errorReporter the error reporter
*/
- BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider)
- : _futureNullType = typeProvider.futureNullType;
+ BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider,
+ {TypeSystem typeSystem})
+ : _futureNullType = typeProvider.futureNullType,
+ _typeSystem = (typeSystem != null) ? typeSystem : new TypeSystemImpl();
@override
Object visitArgumentList(ArgumentList node) {
@@ -293,15 +304,18 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
* @return `true` if and only if an hint code is generated on the passed node
* See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
*/
- bool _checkForArgumentTypeNotAssignable(Expression expression,
- DartType expectedStaticType, DartType actualStaticType,
- DartType expectedPropagatedType, DartType actualPropagatedType,
+ bool _checkForArgumentTypeNotAssignable(
+ Expression expression,
+ DartType expectedStaticType,
+ DartType actualStaticType,
+ DartType expectedPropagatedType,
+ DartType actualPropagatedType,
ErrorCode hintCode) {
//
// Warning case: test static type information
//
if (actualStaticType != null && expectedStaticType != null) {
- if (!actualStaticType.isAssignableTo(expectedStaticType)) {
+ if (!_typeSystem.isAssignableTo(actualStaticType, expectedStaticType)) {
// A warning was created in the ErrorVerifier, return false, don't
// create a hint when a warning has already been created.
return false;
@@ -317,7 +331,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
DartType actualBestType =
actualPropagatedType != null ? actualPropagatedType : actualStaticType;
if (actualBestType != null && expectedBestType != null) {
- if (!actualBestType.isAssignableTo(expectedBestType)) {
+ if (!_typeSystem.isAssignableTo(actualBestType, expectedBestType)) {
_errorReporter.reportTypeErrorForNode(
hintCode, expression, [actualBestType, expectedBestType]);
return true;
@@ -347,8 +361,10 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
DartType propagatedParameterType = propagatedParameterElement == null
? null
: propagatedParameterElement.type;
- return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
- staticParameterType, propagatedParameterType,
+ return _checkForArgumentTypeNotAssignableWithExpectedTypes(
+ argument,
+ staticParameterType,
+ propagatedParameterType,
HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
}
@@ -364,11 +380,17 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
* See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
*/
bool _checkForArgumentTypeNotAssignableWithExpectedTypes(
- Expression expression, DartType expectedStaticType,
- DartType expectedPropagatedType, ErrorCode errorCode) =>
- _checkForArgumentTypeNotAssignable(expression, expectedStaticType,
- expression.staticType, expectedPropagatedType,
- expression.propagatedType, errorCode);
+ Expression expression,
+ DartType expectedStaticType,
+ DartType expectedPropagatedType,
+ ErrorCode errorCode) =>
+ _checkForArgumentTypeNotAssignable(
+ expression,
+ expectedStaticType,
+ expression.staticType,
+ expectedPropagatedType,
+ expression.propagatedType,
+ errorCode);
/**
* This verifies that the passed arguments can be assigned to their corresponding parameters.
@@ -508,14 +530,14 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
? ErrorVerifier.getStaticType(lhs)
: leftVariableElement.type;
DartType staticRightType = ErrorVerifier.getStaticType(rhs);
- if (!staticRightType.isAssignableTo(leftType)) {
+ if (!_typeSystem.isAssignableTo(staticRightType, 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)) {
+ if (!_typeSystem.isAssignableTo(bestRightType, leftType)) {
_errorReporter.reportTypeErrorForNode(
HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]);
return true;
@@ -541,7 +563,8 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
}
if (importedLibrary.hasLoadLibraryFunction) {
_errorReporter.reportErrorForNode(
- HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, node,
+ HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
+ node,
[importedLibrary.name]);
return true;
}
@@ -581,7 +604,8 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
}
// For async, give no hint if Future<Null> is assignable to the return
// type.
- if (body.isAsynchronous && _futureNullType.isAssignableTo(returnTypeType)) {
+ if (body.isAsynchronous &&
+ _typeSystem.isAssignableTo(_futureNullType, returnTypeType)) {
return false;
}
// Check the block for a return statement, if not, create the hint
@@ -740,13 +764,17 @@ class ClassScope extends EnclosedScope {
AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
if (existing is PropertyAccessorElement && duplicate is MethodElement) {
if (existing.nameOffset < duplicate.nameOffset) {
- return new AnalysisError(duplicate.source, duplicate.nameOffset,
- duplicate.displayName.length,
+ return new AnalysisError(
+ duplicate.source,
+ duplicate.nameOffset,
+ duplicate.nameLength,
CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
[existing.displayName]);
} else {
- return new AnalysisError(existing.source, existing.nameOffset,
- existing.displayName.length,
+ return new AnalysisError(
+ existing.source,
+ existing.nameOffset,
+ existing.nameLength,
CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
[existing.displayName]);
}
@@ -823,6 +851,11 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
final TypeProvider _typeProvider;
/**
+ * The type system in use.
+ */
+ final TypeSystem _typeSystem;
+
+ /**
* The set of variables declared using '-D' on the command line.
*/
final DeclaredVariables declaredVariables;
@@ -857,8 +890,10 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
*
* @param errorReporter the error reporter by which errors will be reported
*/
- ConstantVerifier(this._errorReporter, this._currentLibrary,
- this._typeProvider, this.declaredVariables) {
+ ConstantVerifier(this._errorReporter, LibraryElement currentLibrary,
+ this._typeProvider, this.declaredVariables)
+ : _currentLibrary = currentLibrary,
+ _typeSystem = currentLibrary.context.typeSystem {
this._boolType = _typeProvider.boolType;
this._intType = _typeProvider.intType;
this._numType = _typeProvider.numType;
@@ -916,11 +951,15 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
ConstructorElement constructor = node.staticElement;
if (constructor != null) {
ConstantEvaluationEngine evaluationEngine =
- new ConstantEvaluationEngine(_typeProvider, declaredVariables);
+ new ConstantEvaluationEngine(_typeProvider, declaredVariables,
+ typeSystem: _typeSystem);
ConstantVisitor constantVisitor =
new ConstantVisitor(evaluationEngine, _errorReporter);
- evaluationEngine.evaluateConstructorCall(node,
- node.argumentList.arguments, constructor, constantVisitor,
+ evaluationEngine.evaluateConstructorCall(
+ node,
+ node.argumentList.arguments,
+ constructor,
+ constantVisitor,
_errorReporter);
}
}
@@ -976,7 +1015,8 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
if (_implementsEqualsWhenNotAllowed(type)) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
- key, [type.displayName]);
+ key,
+ [type.displayName]);
}
}
} else {
@@ -986,7 +1026,8 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
ErrorReporter subErrorReporter =
new ErrorReporter(errorListener, _errorReporter.source);
DartObjectImpl result = key.accept(new ConstantVisitor(
- new ConstantEvaluationEngine(_typeProvider, declaredVariables),
+ new ConstantEvaluationEngine(_typeProvider, declaredVariables,
+ typeSystem: _typeSystem),
subErrorReporter));
if (result != null) {
if (keys.contains(result)) {
@@ -1040,7 +1081,8 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
if (firstType != nType) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
- expression, [expression.toSource(), firstType.displayName]);
+ expression,
+ [expression.toSource(), firstType.displayName]);
foundError = true;
}
}
@@ -1093,7 +1135,8 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
// report error
_errorReporter.reportErrorForToken(
CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
- node.switchKeyword, [type.displayName]);
+ node.switchKeyword,
+ [type.displayName]);
return true;
}
@@ -1190,7 +1233,8 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
ErrorReporter subErrorReporter =
new ErrorReporter(errorListener, _errorReporter.source);
DartObjectImpl result = expression.accept(new ConstantVisitor(
- new ConstantEvaluationEngine(_typeProvider, declaredVariables),
+ new ConstantEvaluationEngine(_typeProvider, declaredVariables,
+ typeSystem: _typeSystem),
subErrorReporter));
_reportErrors(errorListener.errors, errorCode);
return result;
@@ -1298,12 +1342,14 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
ErrorReporter subErrorReporter =
new ErrorReporter(errorListener, _errorReporter.source);
DartObjectImpl result = initializer.accept(new ConstantVisitor(
- new ConstantEvaluationEngine(
- _typeProvider, declaredVariables), subErrorReporter));
+ new ConstantEvaluationEngine(_typeProvider, declaredVariables,
+ typeSystem: _typeSystem),
+ subErrorReporter));
if (result == null) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
- errorSite, [variableDeclaration.name.name]);
+ errorSite,
+ [variableDeclaration.name.name]);
}
}
}
@@ -1326,7 +1372,8 @@ class ConstantVerifier extends RecursiveAstVisitor<Object> {
new ErrorReporter(errorListener, _errorReporter.source);
DartObjectImpl result = expression.accept(
new _ConstantVerifier_validateInitializerExpression(_typeProvider,
- subErrorReporter, this, parameterElements, declaredVariables));
+ subErrorReporter, this, parameterElements, declaredVariables,
+ typeSystem: _typeSystem));
_reportErrors(errorListener.errors,
CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER);
if (result != null) {
@@ -1451,11 +1498,18 @@ class DeadCodeVerifier extends RecursiveAstVisitor<Object> {
final ErrorReporter _errorReporter;
/**
+ * The type system for this visitor
+ */
+ final TypeSystem _typeSystem;
+
+ /**
* Create a new instance of the [DeadCodeVerifier].
*
* @param errorReporter the error reporter
*/
- DeadCodeVerifier(this._errorReporter);
+ DeadCodeVerifier(this._errorReporter, {TypeSystem typeSystem})
+ : this._typeSystem =
+ (typeSystem != null) ? typeSystem : new TypeSystemImpl();
@override
Object visitBinaryExpression(BinaryExpression node) {
@@ -1620,15 +1674,15 @@ class DeadCodeVerifier extends RecursiveAstVisitor<Object> {
}
}
for (DartType type in visitedTypes) {
- if (currentType.isSubtypeOf(type)) {
+ if (_typeSystem.isSubtypeOf(currentType, type)) {
CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
int offset = catchClause.offset;
int length = lastCatchClause.end - offset;
_errorReporter.reportErrorForOffset(
- HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, offset, length, [
- currentType.displayName,
- type.displayName
- ]);
+ HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
+ offset,
+ length,
+ [currentType.displayName, type.displayName]);
return null;
}
}
@@ -1925,9 +1979,10 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
String uri = _getStringValue(node.uri);
if (uri != null) {
LibraryElement library = _enclosingUnit.library;
- ExportElement exportElement = _findExport(library.exports,
- _enclosingUnit.context.sourceFactory.resolveUri(
- _enclosingUnit.source, uri));
+ ExportElement exportElement = _findExport(
+ library.exports,
+ _enclosingUnit.context.sourceFactory
+ .resolveUri(_enclosingUnit.source, uri));
node.element = exportElement;
}
return super.visitExportDirective(node);
@@ -2031,9 +2086,11 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
String uri = _getStringValue(node.uri);
if (uri != null) {
LibraryElement library = _enclosingUnit.library;
- ImportElement importElement = _findImport(library.imports,
- _enclosingUnit.context.sourceFactory.resolveUri(
- _enclosingUnit.source, uri), node.prefix);
+ ImportElement importElement = _findImport(
+ library.imports,
+ _enclosingUnit.context.sourceFactory
+ .resolveUri(_enclosingUnit.source, uri),
+ node.prefix);
node.element = importElement;
}
return super.visitImportDirective(node);
@@ -2084,8 +2141,8 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
Object visitPartDirective(PartDirective node) {
String uri = _getStringValue(node.uri);
if (uri != null) {
- Source partSource = _enclosingUnit.context.sourceFactory.resolveUri(
- _enclosingUnit.source, uri);
+ Source partSource = _enclosingUnit.context.sourceFactory
+ .resolveUri(_enclosingUnit.source, uri);
node.element = _findPart(_enclosingUnit.library.parts, partSource);
}
return super.visitPartDirective(node);
@@ -2404,6 +2461,9 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
// exception
LocalVariableElementImpl exception =
new LocalVariableElementImpl.forNode(exceptionParameter);
+ if (node.exceptionType == null) {
+ exception.hasImplicitType = true;
+ }
_currentHolder.addLocalVariable(exception);
exceptionParameter.staticElement = exception;
// stack trace
@@ -2455,6 +2515,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
//
constructors = _createDefaultConstructors(interfaceType);
}
+ _setDocRange(element, node);
element.abstract = node.isAbstract;
element.accessors = holder.accessors;
element.constructors = constructors;
@@ -2528,6 +2589,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
SimpleIdentifier constructorName = node.name;
ConstructorElementImpl element =
new ConstructorElementImpl.forNode(constructorName);
+ _setDocRange(element, node);
if (node.externalKeyword != null) {
element.external = true;
}
@@ -2573,6 +2635,9 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1);
element.const3 = node.isConst;
element.final2 = node.isFinal;
+ if (node.type == null) {
+ element.hasImplicitType = true;
+ }
_currentHolder.addLocalVariable(element);
variableName.staticElement = element;
return super.visitDeclaredIdentifier(node);
@@ -2613,6 +2678,10 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
}
// visible range
_setParameterVisibleRange(node, parameter);
+ if (normalParameter is SimpleFormalParameter &&
+ normalParameter.type == null) {
+ parameter.hasImplicitType = true;
+ }
_currentHolder.addParameter(parameter);
parameterName.staticElement = parameter;
normalParameter.accept(this);
@@ -2625,6 +2694,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
SimpleIdentifier enumName = node.name;
ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName);
enumElement.enum2 = true;
+ _setDocRange(enumElement, node);
InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement);
enumElement.type = enumType;
// The equivalent code for enums in the spec shows a single constructor,
@@ -2697,6 +2767,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
SimpleIdentifier functionName = node.name;
FunctionElementImpl element =
new FunctionElementImpl.forNode(functionName);
+ _setDocRange(element, node);
if (node.externalKeyword != null) {
element.external = true;
}
@@ -2719,6 +2790,9 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
}
}
+ if (node.returnType == null) {
+ element.hasImplicitReturnType = true;
+ }
_currentHolder.addFunction(element);
expression.element = element;
functionName.staticElement = element;
@@ -2740,6 +2814,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
if (node.isGetter) {
PropertyAccessorElementImpl getter =
new PropertyAccessorElementImpl.forNode(propertyNameNode);
+ _setDocRange(getter, node);
if (node.externalKeyword != null) {
getter.external = true;
}
@@ -2756,12 +2831,16 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
getter.getter = true;
getter.static = true;
variable.getter = getter;
+ if (node.returnType == null) {
+ getter.hasImplicitReturnType = true;
+ }
_currentHolder.addAccessor(getter);
expression.element = getter;
propertyNameNode.staticElement = getter;
} else {
PropertyAccessorElementImpl setter =
new PropertyAccessorElementImpl.forNode(propertyNameNode);
+ _setDocRange(setter, node);
if (node.externalKeyword != null) {
setter.external = true;
}
@@ -2832,6 +2911,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
_functionTypesToFix.add(type);
}
element.type = type;
+ element.hasImplicitReturnType = true;
_currentHolder.addFunction(element);
node.element = element;
holder.validate();
@@ -2847,6 +2927,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
List<TypeParameterElement> typeParameters = holder.typeParameters;
FunctionTypeAliasElementImpl element =
new FunctionTypeAliasElementImpl.forNode(aliasName);
+ _setDocRange(element, node);
element.parameters = parameters;
element.typeParameters = typeParameters;
FunctionTypeImpl type = new FunctionTypeImpl.forTypedef(element);
@@ -2918,6 +2999,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
}
MethodElementImpl element =
new MethodElementImpl(nameOfMethod, methodName.offset);
+ _setDocRange(element, node);
element.abstract = node.isAbstract;
if (node.externalKeyword != null) {
element.external = true;
@@ -2934,6 +3016,9 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
if (body.isGenerator) {
element.generator = true;
}
+ if (node.returnType == null) {
+ element.hasImplicitReturnType = true;
+ }
_currentHolder.addMethod(element);
methodName.staticElement = element;
} else {
@@ -2951,6 +3036,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
if (node.isGetter) {
PropertyAccessorElementImpl getter =
new PropertyAccessorElementImpl.forNode(propertyNameNode);
+ _setDocRange(getter, node);
if (node.externalKeyword != null) {
getter.external = true;
}
@@ -2968,11 +3054,15 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
getter.getter = true;
getter.static = isStatic;
field.getter = getter;
+ if (node.returnType == null) {
+ getter.hasImplicitReturnType = true;
+ }
_currentHolder.addAccessor(getter);
propertyNameNode.staticElement = getter;
} else {
PropertyAccessorElementImpl setter =
new PropertyAccessorElementImpl.forNode(propertyNameNode);
+ _setDocRange(setter, node);
if (node.externalKeyword != null) {
setter.external = true;
}
@@ -3012,8 +3102,8 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
} else {
String message =
"Exception caught in ElementBuilder.visitMethodDeclaration()";
- AnalysisEngine.instance.logger.logError(
- message, new CaughtException(exception, stackTrace));
+ AnalysisEngine.instance.logger
+ .logError(message, new CaughtException(exception, stackTrace));
}
} finally {
if (node.name.staticElement == null) {
@@ -3025,7 +3115,8 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
buffer.write(" in ");
buffer.write(classNode.name);
buffer.write(" was not set while trying to resolve types.");
- AnalysisEngine.instance.logger.logError(buffer.toString(),
+ AnalysisEngine.instance.logger.logError(
+ buffer.toString(),
new CaughtException(
new AnalysisException(buffer.toString()), null));
}
@@ -3043,6 +3134,9 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
parameter.final2 = node.isFinal;
parameter.parameterKind = node.kind;
_setParameterVisibleRange(node, parameter);
+ if (node.type == null) {
+ parameter.hasImplicitType = true;
+ }
_currentHolder.addParameter(parameter);
parameterName.staticElement = parameter;
}
@@ -3105,6 +3199,12 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
field = new FieldElementImpl.forNode(fieldName);
}
element = field;
+ if (node.parent.parent is FieldDeclaration) {
+ _setDocRange(element, node.parent.parent);
+ }
+ if ((node.parent as VariableDeclarationList).type == null) {
+ field.hasImplicitType = true;
+ }
_currentHolder.addField(field);
fieldName.staticElement = field;
} else if (_inFunction) {
@@ -3120,6 +3220,9 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
// TODO(brianwilkerson) This isn't right for variables declared in a for
// loop.
variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
+ if ((node.parent as VariableDeclarationList).type == null) {
+ variable.hasImplicitType = true;
+ }
_currentHolder.addLocalVariable(variable);
variableName.staticElement = element;
} else {
@@ -3131,6 +3234,9 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
variable = new TopLevelVariableElementImpl.forNode(variableName);
}
element = variable;
+ if ((node.parent as VariableDeclarationList).type == null) {
+ variable.hasImplicitType = true;
+ }
_currentHolder.addTopLevelVariable(variable);
variableName.staticElement = element;
}
@@ -3162,6 +3268,9 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
PropertyAccessorElementImpl getter =
new PropertyAccessorElementImpl.forVariable(element);
getter.getter = true;
+ if (element.hasImplicitType) {
+ getter.hasImplicitReturnType = true;
+ }
_currentHolder.addAccessor(getter);
element.getter = getter;
if (!isConst && !isFinal) {
@@ -3258,6 +3367,17 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
}
/**
+ * If the given [node] has a documentation comment, remember its range
+ * into the given [element].
+ */
+ void _setDocRange(ElementImpl element, AnnotatedNode node) {
+ Comment comment = node.documentationComment;
+ if (comment != null && comment.isDocumentation) {
+ element.setDocRange(comment.offset, comment.length);
+ }
+ }
+
+ /**
* Sets the visible source range for formal parameter.
*/
void _setParameterVisibleRange(
@@ -3726,8 +3846,10 @@ class EnclosedScope extends Scope {
if (_hasHiddenName) {
Element hiddenElement = _hiddenElements[name];
if (hiddenElement != null) {
- errorListener.onError(new AnalysisError(getSource(identifier),
- identifier.offset, identifier.length,
+ errorListener.onError(new AnalysisError(
+ getSource(identifier),
+ identifier.offset,
+ identifier.length,
CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, []));
return hiddenElement;
}
@@ -3862,11 +3984,23 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
bool visitAsExpression(AsExpression node) => _nodeExits(node.expression);
@override
- bool visitAssertStatement(AssertStatement node) => _nodeExits(node.condition);
+ bool visitAssertStatement(AssertStatement node) => false;
@override
- bool visitAssignmentExpression(AssignmentExpression node) =>
- _nodeExits(node.leftHandSide) || _nodeExits(node.rightHandSide);
+ bool visitAssignmentExpression(AssignmentExpression node) {
+ Expression leftHandSide = node.leftHandSide;
+ if (_nodeExits(leftHandSide)) {
+ return true;
+ }
+ if (node.operator.type == sc.TokenType.QUESTION_QUESTION_EQ) {
+ return false;
+ }
+ if (leftHandSide is PropertyAccess &&
+ leftHandSide.operator.type == sc.TokenType.QUESTION_PERIOD) {
+ return false;
+ }
+ return _nodeExits(node.rightHandSide);
+ }
@override
bool visitAwaitExpression(AwaitExpression node) =>
@@ -3875,9 +4009,10 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
@override
bool visitBinaryExpression(BinaryExpression node) {
Expression lhsExpression = node.leftOperand;
+ Expression rhsExpression = node.rightOperand;
sc.TokenType operatorType = node.operator.type;
- // If the operator is || and the left hand side is false literal, don't
- // consider the RHS of the binary expression.
+ // If the operator is ||, then only consider the RHS of the binary
+ // expression if the left hand side is the false literal.
// TODO(jwren) Do we want to take constant expressions into account,
// evaluate if(false) {} differently than if(<condition>), when <condition>
// evaluates to a constant false value?
@@ -3885,21 +4020,27 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
if (lhsExpression is BooleanLiteral) {
BooleanLiteral booleanLiteral = lhsExpression;
if (!booleanLiteral.value) {
- return false;
+ return _nodeExits(rhsExpression);
}
}
+ return _nodeExits(lhsExpression);
}
- // If the operator is && and the left hand side is true literal, don't
- // consider the RHS of the binary expression.
+ // If the operator is &&, then only consider the RHS of the binary
+ // expression if the left hand side is the true literal.
if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) {
if (lhsExpression is BooleanLiteral) {
BooleanLiteral booleanLiteral = lhsExpression;
if (booleanLiteral.value) {
- return false;
+ return _nodeExits(rhsExpression);
}
}
+ return _nodeExits(lhsExpression);
+ }
+ // If the operator is ??, then don't consider the RHS of the binary
+ // expression.
+ if (operatorType == sc.TokenType.QUESTION_QUESTION) {
+ return _nodeExits(lhsExpression);
}
- Expression rhsExpression = node.rightOperand;
return _nodeExits(lhsExpression) || _nodeExits(rhsExpression);
}
@@ -4094,8 +4235,13 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
@override
bool visitMethodInvocation(MethodInvocation node) {
Expression target = node.realTarget;
- if (target != null && target.accept(this)) {
- return true;
+ if (target != null) {
+ if (target.accept(this)) {
+ return true;
+ }
+ if (node.operator.type == sc.TokenType.QUESTION_PERIOD) {
+ return false;
+ }
}
return _nodeExits(node.argumentList);
}
@@ -4707,15 +4853,16 @@ class HintGenerator {
ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
unit.accept(_usedImportedElementsVisitor);
// dead code analysis
- unit.accept(new DeadCodeVerifier(errorReporter));
+ unit.accept(
+ new DeadCodeVerifier(errorReporter, typeSystem: _context.typeSystem));
unit.accept(_usedLocalElementsVisitor);
// dart2js analysis
if (_enableDart2JSHints) {
unit.accept(new Dart2JSVerifier(errorReporter));
}
// Dart best practices
- unit.accept(
- new BestPracticesVerifier(errorReporter, _context.typeProvider));
+ unit.accept(new BestPracticesVerifier(errorReporter, _context.typeProvider,
+ typeSystem: _context.typeSystem));
unit.accept(new OverrideVerifier(errorReporter, _manager));
// Find to-do comments
new ToDoFinder(errorReporter).findIn(unit);
@@ -4758,12 +4905,7 @@ class HtmlTagInfo {
* @param classToTagsMap a table mapping the classes defined in the HTML file to an array
* containing the names of tags with that class
*/
- HtmlTagInfo(List<String> allTags, HashMap<String, String> idToTagMap,
- HashMap<String, List<String>> classToTagsMap) {
- this.allTags = allTags;
- this.idToTagMap = idToTagMap;
- this.classToTagsMap = classToTagsMap;
- }
+ HtmlTagInfo(this.allTags, this.idToTagMap, this.classToTagsMap);
/**
* Return an array containing the tags that have the given class, or {@code null} if there are no
@@ -5678,7 +5820,8 @@ class InheritanceManager {
* @return the passed function type with any parameterized types substituted
*/
FunctionType substituteTypeArgumentsInMemberFromInheritance(
- FunctionType baseFunctionType, String memberName,
+ FunctionType baseFunctionType,
+ String memberName,
InterfaceType definingType) {
// if the baseFunctionType is null, or does not have any parameters,
// return it.
@@ -6180,11 +6323,13 @@ class InheritanceManager {
continue;
}
bool subtypeOfAllTypes = true;
+ TypeSystem typeSystem = _library.context.typeSystem;
for (int j = 0;
j < numOfEltsWithMatchingNames && subtypeOfAllTypes;
j++) {
if (i != j) {
- if (!subtype.isSubtypeOf(executableElementTypes[j])) {
+ if (!typeSystem.isSubtypeOf(
+ subtype, executableElementTypes[j])) {
subtypeOfAllTypes = false;
break;
}
@@ -6235,12 +6380,12 @@ class InheritanceManager {
if (!classHasMember) {
String firstTwoFuntionTypesStr =
"${executableElementTypes[0]}, ${executableElementTypes[1]}";
- _reportError(classElt, classElt.nameOffset,
- classElt.displayName.length,
- StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [
- key,
- firstTwoFuntionTypesStr
- ]);
+ _reportError(
+ classElt,
+ classElt.nameOffset,
+ classElt.nameLength,
+ StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+ [key, firstTwoFuntionTypesStr]);
}
} else {
//
@@ -6252,9 +6397,8 @@ class InheritanceManager {
// Tests: test_getMapOfMembersInheritedFromInterfaces_
// union_multipleSubtypes_*
//
- List<ExecutableElement> elementArrayToMerge =
- new List<ExecutableElement>(
- subtypesOfAllOtherTypesIndexes.length);
+ List<ExecutableElement> elementArrayToMerge = new List<
+ ExecutableElement>(subtypesOfAllOtherTypesIndexes.length);
for (int i = 0; i < elementArrayToMerge.length; i++) {
elementArrayToMerge[i] =
elements[subtypesOfAllOtherTypesIndexes[i]];
@@ -6265,8 +6409,10 @@ class InheritanceManager {
}
}
} else {
- _reportError(classElt, classElt.nameOffset,
- classElt.displayName.length,
+ _reportError(
+ classElt,
+ classElt.nameOffset,
+ classElt.nameLength,
StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
[key]);
}
@@ -6388,8 +6534,11 @@ class InheritanceManager {
}
namedParametersList.addAll(_getNamedParameterNames(element));
}
- return _createSyntheticExecutableElement(elementArrayToMerge,
- elementArrayToMerge[0].displayName, r, h - r,
+ return _createSyntheticExecutableElement(
+ elementArrayToMerge,
+ elementArrayToMerge[0].displayName,
+ r,
+ h - r,
new List.from(namedParametersList));
}
@@ -6405,8 +6554,10 @@ class InheritanceManager {
* @return the created synthetic element
*/
static ExecutableElement _createSyntheticExecutableElement(
- List<ExecutableElement> elementArrayToMerge, String name,
- int numOfRequiredParameters, int numOfPositionalParameters,
+ List<ExecutableElement> elementArrayToMerge,
+ String name,
+ int numOfRequiredParameters,
+ int numOfPositionalParameters,
List<String> namedParameters) {
DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
SimpleIdentifier nameIdentifier = new SimpleIdentifier(
@@ -6788,8 +6939,8 @@ class Library {
LibraryElementImpl get libraryElement {
if (_libraryElement == null) {
try {
- _libraryElement = _analysisContext
- .computeLibraryElement(librarySource) as LibraryElementImpl;
+ _libraryElement = _analysisContext.computeLibraryElement(librarySource)
+ as LibraryElementImpl;
} on AnalysisException catch (exception, stackTrace) {
AnalysisEngine.instance.logger.logError(
"Could not compute library element for ${librarySource.fullName}",
@@ -6866,9 +7017,12 @@ class Library {
Source source =
_analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
if (!_analysisContext.exists(source)) {
- errorListener.onError(new AnalysisError(librarySource,
- uriLiteral.offset, uriLiteral.length,
- CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent]));
+ errorListener.onError(new AnalysisError(
+ librarySource,
+ uriLiteral.offset,
+ uriLiteral.length,
+ CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+ [uriContent]));
}
return source;
} on URISyntaxException {
@@ -6934,6 +7088,7 @@ class LibraryElementBuilder {
.buildCompilationUnit(
librarySource, definingCompilationUnit, librarySource);
NodeList<Directive> directives = definingCompilationUnit.directives;
+ LibraryDirective libraryDirective = null;
LibraryIdentifier libraryNameNode = null;
bool hasPartDirective = false;
FunctionElement entryPoint =
@@ -6951,6 +7106,7 @@ class LibraryElementBuilder {
//
if (directive is LibraryDirective) {
if (libraryNameNode == null) {
+ libraryDirective = directive;
libraryNameNode = directive.name;
directivesToResolve.add(directive);
}
@@ -6973,21 +7129,24 @@ class LibraryElementBuilder {
String partLibraryName =
_getPartLibraryName(partSource, partUnit, directivesToResolve);
if (partLibraryName == null) {
- _errorListener.onError(new AnalysisError(librarySource,
- partUri.offset, partUri.length,
- CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSource()]));
+ _errorListener.onError(new AnalysisError(
+ librarySource,
+ partUri.offset,
+ partUri.length,
+ CompileTimeErrorCode.PART_OF_NON_PART,
+ [partUri.toSource()]));
} else if (libraryNameNode == null) {
// TODO(brianwilkerson) Collect the names declared by the part.
// If they are all the same then we can use that name as the
// inferred name of the library and present it in a quick-fix.
// partLibraryNames.add(partLibraryName);
} else if (libraryNameNode.name != partLibraryName) {
- _errorListener.onError(new AnalysisError(librarySource,
- partUri.offset, partUri.length,
- StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [
- libraryNameNode.name,
- partLibraryName
- ]));
+ _errorListener.onError(new AnalysisError(
+ librarySource,
+ partUri.offset,
+ partUri.length,
+ StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
+ [libraryNameNode.name, partLibraryName]));
}
if (entryPoint == null) {
entryPoint = _findEntryPoint(part);
@@ -7006,6 +7165,7 @@ class LibraryElementBuilder {
//
LibraryElementImpl libraryElement = new LibraryElementImpl.forNode(
_analysisContext.getContextFor(librarySource), libraryNameNode);
+ _setDocRange(libraryElement, libraryDirective);
libraryElement.definingCompilationUnit = definingCompilationUnitElement;
if (entryPoint != null) {
libraryElement.entryPoint = entryPoint;
@@ -7037,6 +7197,7 @@ class LibraryElementBuilder {
.buildCompilationUnit(
librarySource, definingCompilationUnit, librarySource);
NodeList<Directive> directives = definingCompilationUnit.directives;
+ LibraryDirective libraryDirective = null;
LibraryIdentifier libraryNameNode = null;
bool hasPartDirective = false;
FunctionElement entryPoint =
@@ -7054,6 +7215,7 @@ class LibraryElementBuilder {
//
if (directive is LibraryDirective) {
if (libraryNameNode == null) {
+ libraryDirective = directive;
libraryNameNode = directive.name;
directivesToResolve.add(directive);
}
@@ -7077,21 +7239,24 @@ class LibraryElementBuilder {
String partLibraryName =
_getPartLibraryName(partSource, partUnit, directivesToResolve);
if (partLibraryName == null) {
- _errorListener.onError(new AnalysisError(librarySource,
- partUri.offset, partUri.length,
- CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSource()]));
+ _errorListener.onError(new AnalysisError(
+ librarySource,
+ partUri.offset,
+ partUri.length,
+ CompileTimeErrorCode.PART_OF_NON_PART,
+ [partUri.toSource()]));
} else if (libraryNameNode == null) {
// TODO(brianwilkerson) Collect the names declared by the part.
// If they are all the same then we can use that name as the
// inferred name of the library and present it in a quick-fix.
// partLibraryNames.add(partLibraryName);
} else if (libraryNameNode.name != partLibraryName) {
- _errorListener.onError(new AnalysisError(librarySource,
- partUri.offset, partUri.length,
- StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [
- libraryNameNode.name,
- partLibraryName
- ]));
+ _errorListener.onError(new AnalysisError(
+ librarySource,
+ partUri.offset,
+ partUri.length,
+ StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
+ [libraryNameNode.name, partLibraryName]));
}
if (entryPoint == null) {
entryPoint = _findEntryPoint(part);
@@ -7111,6 +7276,7 @@ class LibraryElementBuilder {
//
LibraryElementImpl libraryElement = new LibraryElementImpl.forNode(
_analysisContext.getContextFor(librarySource), libraryNameNode);
+ _setDocRange(libraryElement, libraryDirective);
libraryElement.definingCompilationUnit = definingCompilationUnitElement;
if (entryPoint != null) {
libraryElement.entryPoint = entryPoint;
@@ -7214,6 +7380,19 @@ class LibraryElementBuilder {
}
}
}
+
+ /**
+ * If the given [node] has a documentation comment, remember its range
+ * into the given [element].
+ */
+ void _setDocRange(ElementImpl element, LibraryDirective node) {
+ if (node != null) {
+ Comment comment = node.documentationComment;
+ if (comment != null && comment.isDocumentation) {
+ element.setDocRange(comment.offset, comment.length);
+ }
+ }
+ }
}
/**
@@ -7296,8 +7475,10 @@ class LibraryImportScope extends Scope {
libraryNames[i] = _getLibraryName(conflictingMembers[i]);
}
libraryNames.sort();
- errorListener.onError(new AnalysisError(getSource(identifier),
- identifier.offset, identifier.length,
+ errorListener.onError(new AnalysisError(
+ getSource(identifier),
+ identifier.offset,
+ identifier.length,
StaticWarningCode.AMBIGUOUS_IMPORT, [
foundEltName,
StringUtilities.printListOfQuotedNames(libraryNames)
@@ -7398,13 +7579,12 @@ class LibraryImportScope extends Scope {
if (sdkElement != null && nonSdkElements.length > 0) {
String sdkLibName = _getLibraryName(sdkElement);
String otherLibName = _getLibraryName(nonSdkElements[0]);
- errorListener.onError(new AnalysisError(getSource(identifier),
- identifier.offset, identifier.length,
- StaticWarningCode.CONFLICTING_DART_IMPORT, [
- name,
- sdkLibName,
- otherLibName
- ]));
+ errorListener.onError(new AnalysisError(
+ getSource(identifier),
+ identifier.offset,
+ identifier.length,
+ StaticWarningCode.CONFLICTING_DART_IMPORT,
+ [name, sdkLibName, otherLibName]));
}
if (nonSdkElements.length == conflictingElements.length) {
// None of the members were removed
@@ -7466,6 +7646,11 @@ class LibraryResolver {
TypeProvider _typeProvider;
/**
+ * The type system in use for the library
+ */
+ TypeSystem _typeSystem;
+
+ /**
* A table mapping library sources to the information being maintained for those libraries.
*/
HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>();
@@ -7508,6 +7693,11 @@ class LibraryResolver {
TypeProvider get typeProvider => _typeProvider;
/**
+ * The type system in use.
+ */
+ TypeSystem get typeSystem => _typeSystem;
+
+ /**
* Create an object to represent the information about the library defined by the compilation unit
* with the given source.
*
@@ -7592,6 +7782,7 @@ class LibraryResolver {
}
_buildDirectiveModels();
_typeProvider = new TypeProviderImpl(coreElement, asyncElement);
+ _typeSystem = TypeSystem.create(analysisContext);
_buildTypeHierarchies();
//
// Perform resolution and type analysis.
@@ -7670,6 +7861,7 @@ class LibraryResolver {
}
_buildDirectiveModels();
_typeProvider = new TypeProviderImpl(coreElement, asyncElement);
+ _typeSystem = TypeSystem.create(analysisContext);
_buildEnumMembers();
_buildTypeHierarchies();
//
@@ -7753,7 +7945,8 @@ class LibraryResolver {
* @param visitedLibraries the libraries that have already been visited, used to prevent infinite
* recursion
*/
- void _addToDependencyMap(Library library,
+ void _addToDependencyMap(
+ Library library,
HashMap<Library, List<Library>> dependencyMap,
Set<Library> visitedLibraries) {
if (visitedLibraries.add(library)) {
@@ -7858,8 +8051,11 @@ class LibraryResolver {
ErrorCode errorCode = (importElement.isDeferred
? StaticWarningCode.IMPORT_OF_NON_LIBRARY
: CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
- _errorListener.onError(new AnalysisError(library.librarySource,
- uriLiteral.offset, uriLiteral.length, errorCode,
+ _errorListener.onError(new AnalysisError(
+ library.librarySource,
+ uriLiteral.offset,
+ uriLiteral.length,
+ errorCode,
[uriLiteral.toSource()]));
}
}
@@ -7888,8 +8084,10 @@ class LibraryResolver {
exports.add(exportElement);
if (analysisContext.computeKindOf(exportedSource) !=
SourceKind.LIBRARY) {
- _errorListener.onError(new AnalysisError(library.librarySource,
- uriLiteral.offset, uriLiteral.length,
+ _errorListener.onError(new AnalysisError(
+ library.librarySource,
+ uriLiteral.offset,
+ uriLiteral.length,
CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
[uriLiteral.toSource()]));
}
@@ -8046,7 +8244,8 @@ class LibraryResolver {
*/
void _computeLibraryDependencies(Library library) {
Source librarySource = library.librarySource;
- _computeLibraryDependenciesFromDirectives(library,
+ _computeLibraryDependenciesFromDirectives(
+ library,
analysisContext.computeImportedLibraries(librarySource),
analysisContext.computeExportedLibraries(librarySource));
}
@@ -8175,7 +8374,11 @@ class LibraryResolver {
void _performConstantEvaluation() {
PerformanceStatistics.resolve.makeCurrentWhile(() {
ConstantValueComputer computer = new ConstantValueComputer(
- analysisContext, _typeProvider, analysisContext.declaredVariables);
+ analysisContext,
+ _typeProvider,
+ analysisContext.declaredVariables,
+ null,
+ _typeSystem);
for (Library library in _librariesInCycles) {
for (Source source in library.compilationUnitSources) {
try {
@@ -8200,7 +8403,9 @@ class LibraryResolver {
ErrorReporter errorReporter =
new ErrorReporter(_errorListener, source);
ConstantVerifier constantVerifier = new ConstantVerifier(
- errorReporter, library.libraryElement, _typeProvider,
+ errorReporter,
+ library.libraryElement,
+ _typeProvider,
analysisContext.declaredVariables);
unit.accept(constantVerifier);
} on AnalysisException catch (exception, stackTrace) {
@@ -8306,6 +8511,11 @@ class LibraryResolver2 {
TypeProvider _typeProvider;
/**
+ * The type system in use for the library
+ */
+ TypeSystem _typeSystem;
+
+ /**
* A table mapping library sources to the information being maintained for those libraries.
*/
HashMap<Source, ResolvableLibrary> _libraryMap =
@@ -8395,6 +8605,7 @@ class LibraryResolver2 {
}
_buildDirectiveModels();
_typeProvider = new TypeProviderImpl(coreElement, asyncElement);
+ _typeSystem = TypeSystem.create(analysisContext);
_buildEnumMembers();
_buildTypeHierarchies();
//
@@ -8503,8 +8714,11 @@ class LibraryResolver2 {
ErrorCode errorCode = (importElement.isDeferred
? StaticWarningCode.IMPORT_OF_NON_LIBRARY
: CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
- _errorListener.onError(new AnalysisError(library.librarySource,
- uriLiteral.offset, uriLiteral.length, errorCode,
+ _errorListener.onError(new AnalysisError(
+ library.librarySource,
+ uriLiteral.offset,
+ uriLiteral.length,
+ errorCode,
[uriLiteral.toSource()]));
}
}
@@ -8536,8 +8750,10 @@ class LibraryResolver2 {
exports.add(exportElement);
if (analysisContext.computeKindOf(exportedSource) !=
SourceKind.LIBRARY) {
- _errorListener.onError(new AnalysisError(library.librarySource,
- uriLiteral.offset, uriLiteral.length,
+ _errorListener.onError(new AnalysisError(
+ library.librarySource,
+ uriLiteral.offset,
+ uriLiteral.length,
CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
[uriLiteral.toSource()]));
}
@@ -8631,7 +8847,9 @@ class LibraryResolver2 {
Source source = unit.source;
CompilationUnit ast = unit.compilationUnit;
TypeResolverVisitor visitor = new TypeResolverVisitor(
- library.libraryElement, source, _typeProvider,
+ library.libraryElement,
+ source,
+ _typeProvider,
library.libraryScope.errorListener,
nameScope: library.libraryScope);
ast.accept(visitor);
@@ -8661,7 +8879,11 @@ class LibraryResolver2 {
void _performConstantEvaluation() {
PerformanceStatistics.resolve.makeCurrentWhile(() {
ConstantValueComputer computer = new ConstantValueComputer(
- analysisContext, _typeProvider, analysisContext.declaredVariables);
+ analysisContext,
+ _typeProvider,
+ analysisContext.declaredVariables,
+ null,
+ _typeSystem);
for (ResolvableLibrary library in _librariesInCycle) {
for (ResolvableCompilationUnit unit
in library.resolvableCompilationUnits) {
@@ -8681,7 +8903,9 @@ class LibraryResolver2 {
ErrorReporter errorReporter =
new ErrorReporter(_errorListener, unit.source);
ConstantVerifier constantVerifier = new ConstantVerifier(
- errorReporter, library.libraryElement, _typeProvider,
+ errorReporter,
+ library.libraryElement,
+ _typeProvider,
analysisContext.declaredVariables);
ast.accept(constantVerifier);
}
@@ -8751,46 +8975,6 @@ class LibraryResolver2 {
}
/**
- * Instances of the class `TypeAliasInfo` hold information about a [TypeAlias].
- */
-class LibraryResolver2_TypeAliasInfo {
- final ResolvableLibrary _library;
-
- final Source _source;
-
- final FunctionTypeAlias _typeAlias;
-
- /**
- * Initialize a newly created information holder with the given information.
- *
- * @param library the library containing the type alias
- * @param source the source of the file containing the type alias
- * @param typeAlias the type alias being remembered
- */
- LibraryResolver2_TypeAliasInfo(this._library, this._source, this._typeAlias);
-}
-
-/**
- * Instances of the class `TypeAliasInfo` hold information about a [TypeAlias].
- */
-class LibraryResolver_TypeAliasInfo {
- final Library _library;
-
- final Source _source;
-
- final FunctionTypeAlias _typeAlias;
-
- /**
- * Initialize a newly created information holder with the given information.
- *
- * @param library the library containing the type alias
- * @param source the source of the file containing the type alias
- * @param typeAlias the type alias being remembered
- */
- LibraryResolver_TypeAliasInfo(this._library, this._source, this._typeAlias);
-}
-
-/**
* Instances of the class `LibraryScope` implement a scope containing all of the names defined
* in a given library.
*/
@@ -8819,8 +9003,10 @@ class LibraryScope extends EnclosedScope {
offset = accessor.variable.nameOffset;
}
}
- return new AnalysisError(duplicate.source, offset,
- duplicate.displayName.length,
+ return new AnalysisError(
+ duplicate.source,
+ offset,
+ duplicate.nameLength,
CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER,
[existing.displayName]);
}
@@ -9082,8 +9268,7 @@ class Namespace {
*
* @return a table containing the same mappings as those defined by this namespace
*/
- Map<String, Element> get definedNames =>
- new HashMap<String, Element>.from(_definedNames);
+ Map<String, Element> get definedNames => _definedNames;
/**
* Return the element in this namespace that is available to the containing scope using the given
@@ -9233,7 +9418,7 @@ class NamespaceBuilder {
List<NamespaceCombinator> combinators) {
for (NamespaceCombinator combinator in combinators) {
if (combinator is HideElementCombinator) {
- _hide(definedNames, combinator.hiddenNames);
+ definedNames = _hide(definedNames, combinator.hiddenNames);
} else if (combinator is ShowElementCombinator) {
definedNames = _show(definedNames, combinator.shownNames);
} else {
@@ -9301,7 +9486,8 @@ class NamespaceBuilder {
definedNames.addAll(exportedNames);
}
}
- _addAllFromNamespace(definedNames,
+ _addAllFromNamespace(
+ definedNames,
(library.context as InternalAnalysisContext)
.getPublicNamespace(library));
return definedNames;
@@ -9311,24 +9497,22 @@ class NamespaceBuilder {
}
/**
- * Hide all of the given names by removing them from the given collection of defined names.
- *
- * @param definedNames the names that were defined before this operation
- * @param hiddenNames the names to be hidden
+ * Return a new map of names which has all the names from [definedNames]
+ * with exception of [hiddenNames].
*/
- void _hide(HashMap<String, Element> definedNames, List<String> hiddenNames) {
+ Map<String, Element> _hide(
+ HashMap<String, Element> definedNames, List<String> hiddenNames) {
+ HashMap<String, Element> newNames =
+ new HashMap<String, Element>.from(definedNames);
for (String name in hiddenNames) {
- definedNames.remove(name);
- definedNames.remove("$name=");
+ newNames.remove(name);
+ newNames.remove("$name=");
}
+ return newNames;
}
/**
- * Show only the given names by removing all other names from the given collection of defined
- * names.
- *
- * @param definedNames the names that were defined before this operation
- * @param shownNames the names to be shown
+ * Return a new map of names which has only [shownNames] from [definedNames].
*/
HashMap<String, Element> _show(
HashMap<String, Element> definedNames, List<String> shownNames) {
@@ -9422,6 +9606,155 @@ class OverrideVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * An AST visitor that is used to resolve the some of the nodes within a single
+ * compilation unit. The nodes that are skipped are those that are within
+ * function bodies.
+ */
+class PartialResolverVisitor extends ResolverVisitor {
+ /**
+ * A flag indicating whether the resolver is being run in strong mode.
+ */
+ final bool strongMode;
+
+ /**
+ * The static variables and fields that have an initializer. These are the
+ * variables that need to be re-resolved after static variables have their
+ * types inferred. A subset of these variables are those whose types should
+ * be inferred. The list will be empty unless the resolver is being run in
+ * strong mode.
+ */
+ final List<VariableElement> variablesAndFields = <VariableElement>[];
+
+ /**
+ * A flag indicating whether we should discard errors while resolving the
+ * initializer for variable declarations. We do this for top-level variables
+ * and fields because their initializer will be re-resolved at a later time.
+ */
+ bool discardErrorsInInitializer = false;
+
+ /**
+ * Initialize a newly created visitor to resolve the nodes in an AST node.
+ *
+ * The [definingLibrary] is the element for the library containing the node
+ * being visited. The [source] is the source representing the compilation unit
+ * containing the node being visited. The [typeProvider] is the object used to
+ * access the types from the core library. The [errorListener] is the error
+ * listener that will be informed of any errors that are found during
+ * resolution. The [nameScope] is the scope used to resolve identifiers in the
+ * node that will first be visited. If `null` or unspecified, a new
+ * [LibraryScope] will be created based on [definingLibrary] and
+ * [typeProvider]. The [inheritanceManager] is used to perform inheritance
+ * lookups. If `null` or unspecified, a new [InheritanceManager] will be
+ * created based on [definingLibrary]. The [typeAnalyzerFactory] is used to
+ * create the type analyzer. If `null` or unspecified, a type analyzer of
+ * type [StaticTypeAnalyzer] will be created.
+ */
+ PartialResolverVisitor(LibraryElement definingLibrary, Source source,
+ TypeProvider typeProvider, AnalysisErrorListener errorListener,
+ {Scope nameScope,
+ InheritanceManager inheritanceManager,
+ StaticTypeAnalyzerFactory typeAnalyzerFactory})
+ : strongMode = definingLibrary.context.analysisOptions.strongMode,
+ super(definingLibrary, source, typeProvider,
+ new DisablableErrorListener(errorListener));
+
+ @override
+ Object visitBlockFunctionBody(BlockFunctionBody node) {
+ if (_shouldBeSkipped(node)) {
+ return null;
+ }
+ return super.visitBlockFunctionBody(node);
+ }
+
+ @override
+ Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ if (_shouldBeSkipped(node)) {
+ return null;
+ }
+ return super.visitExpressionFunctionBody(node);
+ }
+
+ @override
+ Object visitFieldDeclaration(FieldDeclaration node) {
+ if (strongMode && node.isStatic) {
+ _addVariables(node.fields.variables);
+ bool wasDiscarding = discardErrorsInInitializer;
+ discardErrorsInInitializer = true;
+ try {
+ return super.visitFieldDeclaration(node);
+ } finally {
+ discardErrorsInInitializer = wasDiscarding;
+ }
+ }
+ return super.visitFieldDeclaration(node);
+ }
+
+ @override
+ Object visitNode(AstNode node) {
+ if (discardErrorsInInitializer) {
+ AstNode parent = node.parent;
+ if (parent is VariableDeclaration && parent.initializer == node) {
+ DisablableErrorListener listener = errorListener;
+ return listener.disableWhile(() => super.visitNode(node));
+ }
+ }
+ return super.visitNode(node);
+ }
+
+ @override
+ Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ if (strongMode) {
+ _addVariables(node.variables.variables);
+ bool wasDiscarding = discardErrorsInInitializer;
+ discardErrorsInInitializer = true;
+ try {
+ return super.visitTopLevelVariableDeclaration(node);
+ } finally {
+ discardErrorsInInitializer = wasDiscarding;
+ }
+ }
+ return super.visitTopLevelVariableDeclaration(node);
+ }
+
+ /**
+ * Add all of the [variables] with initializers to the list of variables whose
+ * type can be inferred. Technically, we only infer the types of variables
+ * that do not have a static type, but all variables with initializers
+ * potentially need to be re-resolved after inference because they might
+ * refer to a field whose type was inferred.
+ */
+ void _addVariables(NodeList<VariableDeclaration> variables) {
+ for (VariableDeclaration variable in variables) {
+ if (variable.initializer != null) {
+ variablesAndFields.add(variable.element);
+ }
+ }
+ }
+
+ /**
+ * Return `true` if the given function body should be skipped because it is
+ * the body of a top-level function, method or constructor.
+ */
+ bool _shouldBeSkipped(FunctionBody body) {
+ AstNode parent = body.parent;
+ if (parent is MethodDeclaration) {
+ return parent.body == body;
+ }
+ if (parent is ConstructorDeclaration) {
+ return parent.body == body;
+ }
+ if (parent is FunctionExpression) {
+ AstNode parent2 = parent.parent;
+ if (parent2 is FunctionDeclaration &&
+ parent2.parent is! FunctionDeclarationStatement) {
+ return parent.body == body;
+ }
+ }
+ return false;
+ }
+}
+
+/**
* Instances of the class `PubVerifier` traverse an AST structure looking for deviations from
* pub best practices.
*/
@@ -9954,6 +10287,11 @@ class ResolverVisitor extends ScopedVisitor {
*/
StaticTypeAnalyzer typeAnalyzer;
+ /*
+ * The type system in use during resolution.
+ */
+ TypeSystem typeSystem;
+
/**
* The class element representing the class containing the current node,
* or `null` if the current node is not contained in a class.
@@ -10007,34 +10345,34 @@ class ResolverVisitor extends ScopedVisitor {
/**
* Initialize a newly created visitor to resolve the nodes in an AST node.
*
- * [definingLibrary] is the element for the library containing the node being
- * visited.
- * [source] is the source representing the compilation unit containing the
- * node being visited.
- * [typeProvider] the object used to access the types from the core library.
- * [errorListener] the error listener that will be informed of any errors
- * that are found during resolution.
- * [nameScope] is the scope used to resolve identifiers in the node that will
- * first be visited. If `null` or unspecified, a new [LibraryScope] will be
- * created based on [definingLibrary] and [typeProvider].
- * [inheritanceManager] is used to perform inheritance lookups. If `null` or
- * unspecified, a new [InheritanceManager] will be created based on
- * [definingLibrary].
- * [typeAnalyzerFactory] is used to create the type analyzer. If `null` or
- * unspecified, a type analyzer of type [StaticTypeAnalyzer] will be created.
+ * The [definingLibrary] is the element for the library containing the node
+ * being visited. The [source] is the source representing the compilation unit
+ * containing the node being visited. The [typeProvider] is the object used to
+ * access the types from the core library. The [errorListener] is the error
+ * listener that will be informed of any errors that are found during
+ * resolution. The [nameScope] is the scope used to resolve identifiers in the
+ * node that will first be visited. If `null` or unspecified, a new
+ * [LibraryScope] will be created based on [definingLibrary] and
+ * [typeProvider]. The [inheritanceManager] is used to perform inheritance
+ * lookups. If `null` or unspecified, a new [InheritanceManager] will be
+ * created based on [definingLibrary]. The [typeAnalyzerFactory] is used to
+ * create the type analyzer. If `null` or unspecified, a type analyzer of
+ * type [StaticTypeAnalyzer] will be created.
*/
ResolverVisitor(LibraryElement definingLibrary, Source source,
TypeProvider typeProvider, AnalysisErrorListener errorListener,
- {Scope nameScope, InheritanceManager inheritanceManager,
+ {Scope nameScope,
+ InheritanceManager inheritanceManager,
StaticTypeAnalyzerFactory typeAnalyzerFactory})
: super(definingLibrary, source, typeProvider, errorListener,
- nameScope: nameScope) {
+ nameScope: nameScope) {
if (inheritanceManager == null) {
this._inheritanceManager = new InheritanceManager(definingLibrary);
} else {
this._inheritanceManager = inheritanceManager;
}
this.elementResolver = new ElementResolver(this);
+ this.typeSystem = definingLibrary.context.typeSystem;
if (typeAnalyzerFactory == null) {
this.typeAnalyzer = new StaticTypeAnalyzer(this);
} else {
@@ -10056,10 +10394,10 @@ class ResolverVisitor extends ScopedVisitor {
Library library, Source source, TypeProvider typeProvider,
{StaticTypeAnalyzerFactory typeAnalyzerFactory})
: this(
- library.libraryElement, source, typeProvider, library.errorListener,
- nameScope: library.libraryScope,
- inheritanceManager: library.inheritanceManager,
- typeAnalyzerFactory: typeAnalyzerFactory);
+ library.libraryElement, source, typeProvider, library.errorListener,
+ nameScope: library.libraryScope,
+ inheritanceManager: library.inheritanceManager,
+ typeAnalyzerFactory: typeAnalyzerFactory);
/**
* Return the element representing the function containing the current node, or `null` if
@@ -10159,7 +10497,14 @@ class ResolverVisitor extends ScopedVisitor {
/**
* Prepares this [ResolverVisitor] to using it for incremental resolution.
*/
- void initForIncrementalResolution() {
+ void initForIncrementalResolution([Declaration declaration = null]) {
+ if (declaration != null) {
+ Element element = declaration.element;
+ if (element is ExecutableElement) {
+ _enclosingFunction = element;
+ }
+ _commentBeforeFunction = declaration.documentationComment;
+ }
_overrideManager.enterScope();
}
@@ -10203,6 +10548,14 @@ class ResolverVisitor extends ScopedVisitor {
*/
DartType overrideVariable(VariableElement element, DartType potentialType,
bool allowPrecisionLoss) {
+ // TODO(scheglov) type propagation for instance/top-level fields
+ // was disabled because it depends on the order or visiting.
+ // If both field and its client are in the same unit, and we visit
+ // the client before the field, then propagated type is not set yet.
+ if (element is PropertyInducingElement) {
+ return null;
+ }
+
if (potentialType == null || potentialType.isBottom) {
return null;
}
@@ -10235,18 +10588,6 @@ class ResolverVisitor extends ScopedVisitor {
allowPrecisionLoss ||
!currentType.isMoreSpecificThan(potentialType) ||
potentialType.isMoreSpecificThan(currentType)) {
- // TODO(scheglov) type propagation for instance/top-level fields
- // was disabled because it depends on the order or visiting.
- // If both field and its client are in the same unit, and we visit
- // the client before the field, then propagated type is not set yet.
-// if (element is PropertyInducingElement) {
-// PropertyInducingElement variable = element;
-// if (!variable.isConst && !variable.isFinal) {
-// return;
-// }
-// (variable as PropertyInducingElementImpl).propagatedType =
-// potentialType;
-// }
_overrideManager.setType(element, potentialType);
return potentialType;
}
@@ -10254,6 +10595,15 @@ class ResolverVisitor extends ScopedVisitor {
}
/**
+ * A client is about to resolve a member in the given class declaration.
+ */
+ void prepareToResolveMembersInClass(ClassDeclaration node) {
+ _enclosingClassDeclaration = node;
+ enclosingClass = node.element;
+ typeAnalyzer.thisType = enclosingClass == null ? null : enclosingClass.type;
+ }
+
+ /**
* If the given [type] is valid, strongly more specific than the
* existing static type of the given [expression], record it as a propagated
* type of the given [expression]. Otherwise, reset it to `null`.
@@ -10604,6 +10954,11 @@ class ResolverVisitor extends ScopedVisitor {
@override
Object visitDefaultFormalParameter(DefaultFormalParameter node) {
super.visitDefaultFormalParameter(node);
+ ParameterElement element = node.element;
+ if (element.initializer != null && node.defaultValue != null) {
+ (element.initializer as FunctionElementImpl).returnType =
+ node.defaultValue.staticType;
+ }
FormalParameterList parent = node.parent;
AstNode grandparent = parent.parent;
if (grandparent is ConstructorDeclaration &&
@@ -10650,9 +11005,21 @@ class ResolverVisitor extends ScopedVisitor {
ElementResolver.setMetadata(node.element, node);
}
//
- // There is nothing else to do because everything else was resolved by the
- // element builder.
+ // Continue the enum resolution.
//
+ ClassElement outerType = enclosingClass;
+ try {
+ enclosingClass = node.element;
+ typeAnalyzer.thisType =
+ enclosingClass == null ? null : enclosingClass.type;
+ super.visitEnumDeclaration(node);
+ node.accept(elementResolver);
+ node.accept(typeAnalyzer);
+ } finally {
+ typeAnalyzer.thisType = outerType == null ? null : outerType.type;
+ enclosingClass = outerType;
+ _enclosingClassDeclaration = null;
+ }
return null;
}
@@ -10715,16 +11082,24 @@ class ResolverVisitor extends ScopedVisitor {
if (loopVariable != null && iterable != null) {
LocalVariableElement loopElement = loopVariable.element;
if (loopElement != null) {
- DartType iteratorElementType = _getIteratorElementType(iterable);
- overrideVariable(loopElement, iteratorElementType, true);
- _recordPropagatedType(loopVariable.identifier, iteratorElementType);
+ DartType propagatedType = null;
+ if (node.awaitKeyword == null) {
+ propagatedType = _getIteratorElementType(iterable);
+ } else {
+ propagatedType = _getStreamElementType(iterable);
+ }
+ if (propagatedType != null) {
+ overrideVariable(loopElement, propagatedType, true);
+ recordPropagatedTypeIfBetter(
+ loopVariable.identifier, propagatedType);
+ }
}
} else if (identifier != null && iterable != null) {
Element identifierElement = identifier.staticElement;
if (identifierElement is VariableElement) {
DartType iteratorElementType = _getIteratorElementType(iterable);
overrideVariable(identifierElement, iteratorElementType, true);
- _recordPropagatedType(identifier, iteratorElementType);
+ recordPropagatedTypeIfBetter(identifier, iteratorElementType);
}
}
visitStatementInScope(body);
@@ -11022,6 +11397,10 @@ class ResolverVisitor extends ScopedVisitor {
Object visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);
VariableElement element = node.element;
+ if (element.initializer != null && node.initializer != null) {
+ (element.initializer as FunctionElementImpl).returnType =
+ node.initializer.staticType;
+ }
// Note: in addition to cloning the initializers for const variables, we
// have to clone the initializers for non-static final fields (because if
// they occur in a class with a const constructor, they will be needed to
@@ -11099,12 +11478,11 @@ class ResolverVisitor extends ScopedVisitor {
}
/**
- * The given expression is the expression used to compute the iterator for a for-each statement.
- * Attempt to compute the type of objects that will be assigned to the loop variable and return
- * that type. Return `null` if the type could not be determined.
- *
- * @param iterator the iterator for a for-each statement
- * @return the type of objects that will be assigned to the loop variable
+ * The given expression is the expression used to compute the iterator for a
+ * for-each statement. Attempt to compute the type of objects that will be
+ * assigned to the loop variable and return that type. Return `null` if the
+ * type could not be determined. The [iteratorExpression] is the expression
+ * that will return the Iterable being iterated over.
*/
DartType _getIteratorElementType(Expression iteratorExpression) {
DartType expressionType = iteratorExpression.bestType;
@@ -11132,6 +11510,44 @@ class ResolverVisitor extends ScopedVisitor {
}
/**
+ * The given expression is the expression used to compute the stream for an
+ * asyncronous for-each statement. Attempt to compute the type of objects that
+ * will be assigned to the loop variable and return that type. Return `null`
+ * if the type could not be determined. The [streamExpression] is the
+ * expression that will return the stream being iterated over.
+ */
+ DartType _getStreamElementType(Expression streamExpression) {
+ DartType streamType = streamExpression.bestType;
+ if (streamType is InterfaceType) {
+ FunctionType listenFunction =
+ _inheritanceManager.lookupMemberType(streamType, "listen");
+ if (listenFunction == null) {
+ return null;
+ }
+ List<ParameterElement> listenParameters = listenFunction.parameters;
+ if (listenParameters == null || listenParameters.length < 1) {
+ return null;
+ }
+ DartType onDataType = listenParameters[0].type;
+ if (onDataType is FunctionType) {
+ List<ParameterElement> onDataParameters = onDataType.parameters;
+ if (onDataParameters == null || onDataParameters.length < 1) {
+ return null;
+ }
+ DartType eventType = onDataParameters[0].type;
+ // TODO(paulberry): checking that typeParameters.isNotEmpty is a
+ // band-aid fix for dartbug.com/24191. Figure out what the correct
+ // logic should be.
+ if (streamType.typeParameters.isNotEmpty &&
+ eventType.element == streamType.typeParameters[0]) {
+ return streamType.typeArguments[0];
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
* If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its
* required type is [FunctionType], then infer parameters types from [FunctionType].
*/
@@ -11150,7 +11566,7 @@ class ResolverVisitor extends ScopedVisitor {
// If the expectedClosureType is not more specific than the static type,
// return.
DartType staticClosureType =
- (closure.element != null ? closure.element.type : null) as DartType;
+ closure.element != null ? closure.element.type : null;
if (staticClosureType != null &&
!expectedClosureType.isMoreSpecificThan(staticClosureType)) {
return;
@@ -11423,18 +11839,6 @@ class ResolverVisitor extends ScopedVisitor {
_propagateTrueState(condition.expression);
}
}
-
- /**
- * Record that the propagated type of the given node is the given type.
- *
- * @param expression the node whose type is to be recorded
- * @param type the propagated type of the node
- */
- void _recordPropagatedType(Expression expression, DartType type) {
- if (type != null && !type.isDynamic) {
- expression.propagatedType = type;
- }
- }
}
/**
@@ -11540,9 +11944,8 @@ abstract class Scope {
// TODO(jwren) There are 4 error codes for duplicate, but only 1 is being
// generated.
Source source = duplicate.source;
- return new AnalysisError(source, duplicate.nameOffset,
- duplicate.displayName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION,
- [existing.displayName]);
+ return new AnalysisError(source, duplicate.nameOffset, duplicate.nameLength,
+ CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName]);
}
/**
@@ -11640,7 +12043,7 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
/**
* The element for the library containing the compilation unit being visited.
*/
- LibraryElement _definingLibrary;
+ final LibraryElement definingLibrary;
/**
* The source representing the compilation unit being visited.
@@ -11650,7 +12053,7 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
/**
* The error listener that will be informed of any errors that are found during resolution.
*/
- AnalysisErrorListener _errorListener;
+ final AnalysisErrorListener errorListener;
/**
* The scope used to resolve identifiers.
@@ -11694,10 +12097,9 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
* first be visited. If `null` or unspecified, a new [LibraryScope] will be
* created based on [definingLibrary] and [typeProvider].
*/
- ScopedVisitor(LibraryElement definingLibrary, this.source, this.typeProvider,
- AnalysisErrorListener errorListener, {Scope nameScope}) {
- this._definingLibrary = definingLibrary;
- this._errorListener = errorListener;
+ ScopedVisitor(
+ this.definingLibrary, this.source, this.typeProvider, this.errorListener,
+ {Scope nameScope}) {
if (nameScope == null) {
this.nameScope = new LibraryScope(definingLibrary, errorListener);
} else {
@@ -11706,13 +12108,6 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
}
/**
- * Return the library element for the library containing the compilation unit being resolved.
- *
- * @return the library element for the library containing the compilation unit being resolved
- */
- LibraryElement get definingLibrary => _definingLibrary;
-
- /**
* Return the implicit label scope in which the current node is being
* resolved.
*/
@@ -11748,7 +12143,7 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
*/
void reportErrorForNode(ErrorCode errorCode, AstNode node,
[List<Object> arguments]) {
- _errorListener.onError(new AnalysisError(
+ errorListener.onError(new AnalysisError(
source, node.offset, node.length, errorCode, arguments));
}
@@ -11762,7 +12157,7 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
*/
void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
[List<Object> arguments]) {
- _errorListener.onError(
+ errorListener.onError(
new AnalysisError(source, offset, length, errorCode, arguments));
}
@@ -11775,7 +12170,7 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
*/
void reportErrorForToken(ErrorCode errorCode, sc.Token token,
[List<Object> arguments]) {
- _errorListener.onError(new AnalysisError(
+ errorListener.onError(new AnalysisError(
source, token.offset, token.length, errorCode, arguments));
}
@@ -11946,6 +12341,38 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
}
@override
+ Object visitEnumDeclaration(EnumDeclaration node) {
+ ClassElement classElement = node.element;
+ Scope outerScope = nameScope;
+ try {
+ if (classElement == null) {
+ AnalysisEngine.instance.logger.logInformation(
+ "Missing element for enum declaration ${node.name.name} in ${definingLibrary.source.fullName}",
+ new CaughtException(new AnalysisException(), null));
+ super.visitEnumDeclaration(node);
+ } else {
+ ClassElement outerClass = enclosingClass;
+ try {
+ enclosingClass = node.element;
+ nameScope = new ClassScope(nameScope, classElement);
+ visitEnumMembersInScope(node);
+ } finally {
+ enclosingClass = outerClass;
+ }
+ }
+ } finally {
+ nameScope = outerScope;
+ }
+ return null;
+ }
+
+ void visitEnumMembersInScope(EnumDeclaration node) {
+ safelyVisit(node.documentationComment);
+ node.metadata.accept(this);
+ node.constants.accept(this);
+ }
+
+ @override
Object visitForEachStatement(ForEachStatement node) {
Scope outerNameScope = nameScope;
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
@@ -12296,6 +12723,310 @@ abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
}
/**
+ * Implementation of [TypeSystem] using the strong mode rules.
+ * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md
+ */
+class StrongTypeSystemImpl implements TypeSystem {
+ final _specTypeSystem = new TypeSystemImpl();
+
+ StrongTypeSystemImpl();
+
+ @override
+ DartType getLeastUpperBound(
+ TypeProvider typeProvider, DartType type1, DartType type2) {
+ // TODO(leafp): Implement a strong mode version of this.
+ return _specTypeSystem.getLeastUpperBound(typeProvider, type1, type2);
+ }
+
+ // TODO(leafp): Document the rules in play here
+ @override
+ bool isAssignableTo(DartType fromType, DartType toType) {
+ // An actual subtype
+ if (isSubtypeOf(fromType, toType)) {
+ return true;
+ }
+
+ // Don't allow implicit downcasts between function types
+ // and call method objects, as these will almost always fail.
+ if ((fromType is FunctionType && _getCallMethodType(toType) != null) ||
+ (toType is FunctionType && _getCallMethodType(fromType) != null)) {
+ return false;
+ }
+
+ // If the subtype relation goes the other way, allow the implicit downcast.
+ // TODO(leafp): Emit warnings and hints for these in some way.
+ // TODO(leafp): Consider adding a flag to disable these? Or just rely on
+ // --warnings-as-errors?
+ if (isSubtypeOf(toType, fromType) ||
+ _specTypeSystem.isAssignableTo(toType, fromType)) {
+ // TODO(leafp): error if type is known to be exact (literal,
+ // instance creation).
+ // TODO(leafp): Warn on composite downcast.
+ // TODO(leafp): hint on object/dynamic downcast.
+ // TODO(leafp): Consider allowing assignment casts.
+ return true;
+ }
+
+ return false;
+ }
+
+ @override
+ bool isSubtypeOf(DartType leftType, DartType rightType) {
+ return _isSubtypeOf(leftType, rightType, null);
+ }
+
+ FunctionType _getCallMethodType(DartType t) {
+ if (t is InterfaceType) {
+ ClassElement element = t.element;
+ InheritanceManager manager = new InheritanceManager(element.library);
+ FunctionType callType = manager.lookupMemberType(t, "call");
+ return callType;
+ }
+ return null;
+ }
+
+ // Given a type t, if t is an interface type with a call method
+ // defined, return the function type for the call method, otherwise
+ // return null.
+ _GuardedSubtypeChecker<DartType> _guard(
+ _GuardedSubtypeChecker<DartType> check) {
+ return (DartType t1, DartType t2, Set<Element> visited) {
+ Element element = t1.element;
+ if (visited == null) {
+ visited = new HashSet<Element>();
+ }
+ if (element == null || !visited.add(element)) {
+ return false;
+ }
+ try {
+ return check(t1, t2, visited);
+ } finally {
+ visited.remove(element);
+ }
+ };
+ }
+
+ bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
+ return (t.isDynamic && dynamicIsBottom) || t.isBottom;
+ }
+
+ // Guard against loops in the class hierarchy
+ /**
+ * Check that [f1] is a subtype of [f2].
+ * [fuzzyArrows] indicates whether or not the f1 and f2 should be
+ * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
+ * as bottom).
+ */
+ bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
+ {bool fuzzyArrows: true}) {
+ final r1s = f1.normalParameterTypes;
+ final o1s = f1.optionalParameterTypes;
+ final n1s = f1.namedParameterTypes;
+ final r2s = f2.normalParameterTypes;
+ final o2s = f2.optionalParameterTypes;
+ final n2s = f2.namedParameterTypes;
+ final ret1 = f1.returnType;
+ final ret2 = f2.returnType;
+
+ // A -> B <: C -> D if C <: A and
+ // either D is void or B <: D
+ if (!ret2.isVoid && !isSubtypeOf(ret1, ret2)) {
+ return false;
+ }
+
+ // Reject if one has named and the other has optional
+ if (n1s.length > 0 && o2s.length > 0) {
+ return false;
+ }
+ if (n2s.length > 0 && o1s.length > 0) {
+ return false;
+ }
+
+ // Rebind _isSubtypeOf for convenience
+ _SubtypeChecker<DartType> parameterSubtype = (DartType t1, DartType t2) =>
+ _isSubtypeOf(t1, t2, null, dynamicIsBottom: fuzzyArrows);
+
+ // f2 has named parameters
+ if (n2s.length > 0) {
+ // Check that every named parameter in f2 has a match in f1
+ for (String k2 in n2s.keys) {
+ if (!n1s.containsKey(k2)) {
+ return false;
+ }
+ if (!parameterSubtype(n2s[k2], n1s[k2])) {
+ return false;
+ }
+ }
+ }
+ // If we get here, we either have no named parameters,
+ // or else the named parameters match and we have no optional
+ // parameters
+
+ // If f1 has more required parameters, reject
+ if (r1s.length > r2s.length) {
+ return false;
+ }
+
+ // If f2 has more required + optional parameters, reject
+ if (r2s.length + o2s.length > r1s.length + o1s.length) {
+ return false;
+ }
+
+ // The parameter lists must look like the following at this point
+ // where rrr is a region of required, and ooo is a region of optionals.
+ // f1: rrr ooo ooo ooo
+ // f2: rrr rrr ooo
+ int rr = r1s.length; // required in both
+ int or = r2s.length - r1s.length; // optional in f1, required in f2
+ int oo = o2s.length; // optional in both
+
+ for (int i = 0; i < rr; ++i) {
+ if (!parameterSubtype(r2s[i], r1s[i])) {
+ return false;
+ }
+ }
+ for (int i = 0, j = rr; i < or; ++i, ++j) {
+ if (!parameterSubtype(r2s[j], o1s[i])) {
+ return false;
+ }
+ }
+ for (int i = or, j = 0; i < oo; ++i, ++j) {
+ if (!parameterSubtype(o2s[j], o1s[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool _isInterfaceSubtypeOf(
+ InterfaceType i1, InterfaceType i2, Set<Element> visited) {
+ // Guard recursive calls
+ _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype =
+ _guard(_isInterfaceSubtypeOf);
+
+ if (i1 == i2) {
+ return true;
+ }
+
+ if (i1.element == i2.element) {
+ List<DartType> tArgs1 = i1.typeArguments;
+ List<DartType> tArgs2 = i2.typeArguments;
+
+ assert(tArgs1.length == tArgs2.length);
+
+ for (int i = 0; i < tArgs1.length; i++) {
+ DartType t1 = tArgs1[i];
+ DartType t2 = tArgs2[i];
+ if (!isSubtypeOf(t1, t2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (i2.isDartCoreFunction && i1.element.getMethod("call") != null) {
+ return true;
+ }
+
+ if (i1.isObject) {
+ return false;
+ }
+
+ if (guardedInterfaceSubtype(i1.superclass, i2, visited)) {
+ return true;
+ }
+
+ for (final parent in i1.interfaces) {
+ if (guardedInterfaceSubtype(parent, i2, visited)) {
+ return true;
+ }
+ }
+
+ for (final parent in i1.mixins) {
+ if (guardedInterfaceSubtype(parent, i2, visited)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool _isSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
+ {bool dynamicIsBottom: false}) {
+ // Guard recursive calls
+ _GuardedSubtypeChecker<DartType> guardedSubtype = _guard(_isSubtypeOf);
+
+ if (t1 == t2) {
+ return true;
+ }
+
+ // The types are void, dynamic, bottom, interface types, function types
+ // and type parameters. We proceed by eliminating these different classes
+ // from consideration.
+
+ // Trivially true.
+ if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
+ _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
+ return true;
+ }
+
+ // Trivially false.
+ if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
+ _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
+ return false;
+ }
+
+ // S <: T where S is a type variable
+ // T is not dynamic or object (handled above)
+ // S != T (handled above)
+ // So only true if bound of S is S' and
+ // S' <: T
+ if (t1 is TypeParameterType) {
+ DartType bound = t1.element.bound;
+ if (bound == null) return false;
+ return guardedSubtype(bound, t2, visited);
+ }
+
+ if (t2 is TypeParameterType) {
+ return false;
+ }
+
+ if (t1.isVoid || t2.isVoid) {
+ return false;
+ }
+
+ // We've eliminated void, dynamic, bottom, and type parameters. The only
+ // cases are the combinations of interface type and function type.
+
+ // A function type can only subtype an interface type if
+ // the interface type is Function
+ if (t1 is FunctionType && t2 is InterfaceType) {
+ return t2.isDartCoreFunction;
+ }
+
+ // An interface type can only subtype a function type if
+ // the interface type declares a call method with a type
+ // which is a super type of the function type.
+ if (t1 is InterfaceType && t2 is FunctionType) {
+ var callType = _getCallMethodType(t1);
+ return (callType != null) && _isFunctionSubtypeOf(callType, t2);
+ }
+
+ // Two interface types
+ if (t1 is InterfaceType && t2 is InterfaceType) {
+ return _isInterfaceSubtypeOf(t1, t2, visited);
+ }
+
+ return _isFunctionSubtypeOf(t1 as FunctionType, t2 as FunctionType);
+ }
+
+ // TODO(leafp): Document the rules in play here
+ bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
+ return (t.isDynamic && !dynamicIsBottom) || t.isObject;
+ }
+}
+
+/**
* Instances of this class manage the knowledge of what the set of subtypes are for a given type.
*/
class SubtypeManager {
@@ -13243,13 +13974,13 @@ class TypeProviderImpl implements TypeProvider {
@override
List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
- nullType,
- numType,
- intType,
- doubleType,
- boolType,
- stringType
- ];
+ nullType,
+ numType,
+ intType,
+ doubleType,
+ boolType,
+ stringType
+ ];
@override
DartObjectImpl get nullObject {
@@ -13380,7 +14111,7 @@ class TypeResolverVisitor extends ScopedVisitor {
TypeProvider typeProvider, AnalysisErrorListener errorListener,
{Scope nameScope})
: super(definingLibrary, source, typeProvider, errorListener,
- nameScope: nameScope) {
+ nameScope: nameScope) {
_dynamicType = typeProvider.dynamicType;
_undefinedType = typeProvider.undefinedType;
}
@@ -13585,6 +14316,7 @@ class TypeResolverVisitor extends ScopedVisitor {
DartType type;
TypeName typeName = node.type;
if (typeName == null) {
+ element.hasImplicitType = true;
type = _dynamicType;
if (parameter is FieldFormalParameterElement) {
FieldElement fieldElement =
@@ -13776,13 +14508,15 @@ class TypeResolverVisitor extends ScopedVisitor {
(parent.parent as InstanceCreationExpression).isConst) {
// If, if this is a const expression, then generate a
// CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
- reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE,
+ reportErrorForNode(
+ CompileTimeErrorCode.CONST_WITH_NON_TYPE,
prefixedIdentifier.identifier,
[prefixedIdentifier.identifier.name]);
} else {
// Else, if this expression is a new expression, report a
// NEW_WITH_NON_TYPE warning.
- reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE,
+ reportErrorForNode(
+ StaticWarningCode.NEW_WITH_NON_TYPE,
prefixedIdentifier.identifier,
[prefixedIdentifier.identifier.name]);
}
@@ -13960,11 +14694,8 @@ class TypeResolverVisitor extends ScopedVisitor {
typeArguments[i] = argumentType;
}
} else {
- reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node, [
- typeName.name,
- parameterCount,
- argumentCount
- ]);
+ reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node,
+ [typeName.name, parameterCount, argumentCount]);
for (int i = 0; i < parameterCount; i++) {
typeArguments[i] = _dynamicType;
}
@@ -14328,7 +15059,8 @@ class TypeResolverVisitor extends ScopedVisitor {
void _resolve(ClassElementImpl classElement, WithClause withClause,
ImplementsClause implementsClause) {
if (withClause != null) {
- List<InterfaceType> mixinTypes = _resolveTypes(withClause.mixinTypes,
+ List<InterfaceType> mixinTypes = _resolveTypes(
+ withClause.mixinTypes,
CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
CompileTimeErrorCode.MIXIN_OF_ENUM,
CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
@@ -14340,7 +15072,8 @@ class TypeResolverVisitor extends ScopedVisitor {
}
if (implementsClause != null) {
NodeList<TypeName> interfaces = implementsClause.interfaces;
- List<InterfaceType> interfaceTypes = _resolveTypes(interfaces,
+ List<InterfaceType> interfaceTypes = _resolveTypes(
+ interfaces,
CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
CompileTimeErrorCode.IMPLEMENTS_ENUM,
CompileTimeErrorCode.IMPLEMENTS_DYNAMIC);
@@ -14415,8 +15148,10 @@ class TypeResolverVisitor extends ScopedVisitor {
* @param dynamicTypeError the error to produce if the type name is "dynamic"
* @return an array containing all of the types that were resolved.
*/
- List<InterfaceType> _resolveTypes(NodeList<TypeName> typeNames,
- ErrorCode nonTypeError, ErrorCode enumTypeError,
+ List<InterfaceType> _resolveTypes(
+ NodeList<TypeName> typeNames,
+ ErrorCode nonTypeError,
+ ErrorCode enumTypeError,
ErrorCode dynamicTypeError) {
List<InterfaceType> types = new List<InterfaceType>();
for (TypeName typeName in typeNames) {
@@ -14525,27 +15260,42 @@ class TypeResolverVisitor extends ScopedVisitor {
*/
abstract class TypeSystem {
/**
- * Return the [TypeProvider] associated with this [TypeSystem].
+ * Compute the least upper bound of two types.
*/
- TypeProvider get typeProvider;
+ DartType getLeastUpperBound(
+ TypeProvider typeProvider, DartType type1, DartType type2);
/**
- * Compute the least upper bound of two types.
+ * Return `true` if the [leftType] is assignable to the [rightType] (that is,
+ * if leftType <==> rightType).
+ */
+ bool isAssignableTo(DartType leftType, DartType rightType);
+
+ /**
+ * Return `true` if the [leftType] is a subtype of the [rightType] (that is,
+ * if leftType <: rightType).
+ */
+ bool isSubtypeOf(DartType leftType, DartType rightType);
+
+ /**
+ * Create either a strong mode or regular type system based on context.
*/
- DartType getLeastUpperBound(DartType type1, DartType type2);
+ static TypeSystem create(AnalysisContext context) {
+ return (context.analysisOptions.strongMode)
+ ? new StrongTypeSystemImpl()
+ : new TypeSystemImpl();
+ }
}
/**
* Implementation of [TypeSystem] using the rules in the Dart specification.
*/
class TypeSystemImpl implements TypeSystem {
- @override
- final TypeProvider typeProvider;
-
- TypeSystemImpl(this.typeProvider);
+ TypeSystemImpl();
@override
- DartType getLeastUpperBound(DartType type1, DartType type2) {
+ DartType getLeastUpperBound(
+ TypeProvider typeProvider, DartType type1, DartType type2) {
// The least upper bound relation is reflexive.
if (identical(type1, type2)) {
return type1;
@@ -14622,6 +15372,16 @@ class TypeSystemImpl implements TypeSystem {
return typeProvider.dynamicType;
}
}
+
+ @override
+ bool isAssignableTo(DartType leftType, DartType rightType) {
+ return leftType.isAssignableTo(rightType);
+ }
+
+ @override
+ bool isSubtypeOf(DartType leftType, DartType rightType) {
+ return leftType.isSubtypeOf(rightType);
+ }
}
/**
@@ -14648,10 +15408,8 @@ class UnusedLocalElementsVerifier extends RecursiveElementVisitor {
@override
visitClassElement(ClassElement element) {
if (!_isUsedElement(element)) {
- _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
- element.kind.displayName,
- element.displayName
- ]);
+ _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+ [element.kind.displayName, element.displayName]);
}
super.visitClassElement(element);
}
@@ -14668,10 +15426,8 @@ class UnusedLocalElementsVerifier extends RecursiveElementVisitor {
@override
visitFunctionElement(FunctionElement element) {
if (!_isUsedElement(element)) {
- _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
- element.kind.displayName,
- element.displayName
- ]);
+ _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+ [element.kind.displayName, element.displayName]);
}
super.visitFunctionElement(element);
}
@@ -14679,10 +15435,8 @@ class UnusedLocalElementsVerifier extends RecursiveElementVisitor {
@override
visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
if (!_isUsedElement(element)) {
- _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
- element.kind.displayName,
- element.displayName
- ]);
+ _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+ [element.kind.displayName, element.displayName]);
}
super.visitFunctionTypeAliasElement(element);
}
@@ -14705,10 +15459,8 @@ class UnusedLocalElementsVerifier extends RecursiveElementVisitor {
@override
visitMethodElement(MethodElement element) {
if (!_isUsedMember(element)) {
- _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
- element.kind.displayName,
- element.displayName
- ]);
+ _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+ [element.kind.displayName, element.displayName]);
}
super.visitMethodElement(element);
}
@@ -14716,10 +15468,8 @@ class UnusedLocalElementsVerifier extends RecursiveElementVisitor {
@override
visitPropertyAccessorElement(PropertyAccessorElement element) {
if (!_isUsedMember(element)) {
- _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
- element.kind.displayName,
- element.displayName
- ]);
+ _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+ [element.kind.displayName, element.displayName]);
}
super.visitPropertyAccessorElement(element);
}
@@ -14780,8 +15530,7 @@ class UnusedLocalElementsVerifier extends RecursiveElementVisitor {
ErrorCode errorCode, Element element, List<Object> arguments) {
if (element != null) {
_errorListener.onError(new AnalysisError(element.source,
- element.nameOffset, element.displayName.length, errorCode,
- arguments));
+ element.nameOffset, element.nameLength, errorCode, arguments));
}
}
}
@@ -14908,7 +15657,7 @@ class VariableResolverVisitor extends ScopedVisitor {
TypeProvider typeProvider, AnalysisErrorListener errorListener,
{Scope nameScope})
: super(definingLibrary, source, typeProvider, errorListener,
- nameScope: nameScope);
+ nameScope: nameScope);
/**
* Initialize a newly created visitor to resolve the nodes in a compilation unit.
@@ -14923,8 +15672,8 @@ class VariableResolverVisitor extends ScopedVisitor {
VariableResolverVisitor.con1(
Library library, Source source, TypeProvider typeProvider)
: this(
- library.libraryElement, source, typeProvider, library.errorListener,
- nameScope: library.libraryScope);
+ library.libraryElement, source, typeProvider, library.errorListener,
+ nameScope: library.libraryScope);
@override
Object visitExportDirective(ExportDirective node) => null;
@@ -15033,11 +15782,20 @@ class _ConstantVerifier_validateInitializerExpression extends ConstantVisitor {
List<ParameterElement> parameterElements;
- _ConstantVerifier_validateInitializerExpression(TypeProvider typeProvider,
- ErrorReporter errorReporter, this.verifier, this.parameterElements,
- DeclaredVariables declaredVariables)
- : super(new ConstantEvaluationEngine(typeProvider, declaredVariables),
- errorReporter);
+ TypeSystem _typeSystem;
+
+ _ConstantVerifier_validateInitializerExpression(
+ TypeProvider typeProvider,
+ ErrorReporter errorReporter,
+ this.verifier,
+ this.parameterElements,
+ DeclaredVariables declaredVariables,
+ {TypeSystem typeSystem})
+ : _typeSystem = (typeSystem != null) ? typeSystem : new TypeSystemImpl(),
+ super(
+ new ConstantEvaluationEngine(typeProvider, declaredVariables,
+ typeSystem: typeSystem),
+ errorReporter);
@override
DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
@@ -15049,19 +15807,20 @@ class _ConstantVerifier_validateInitializerExpression extends ConstantVisitor {
if (type.isDynamic) {
return new DartObjectImpl(
verifier._typeProvider.objectType, DynamicState.DYNAMIC_STATE);
- } else if (type.isSubtypeOf(verifier._boolType)) {
+ } else if (_typeSystem.isSubtypeOf(type, verifier._boolType)) {
return new DartObjectImpl(
verifier._typeProvider.boolType, BoolState.UNKNOWN_VALUE);
- } else if (type.isSubtypeOf(verifier._typeProvider.doubleType)) {
+ } else if (_typeSystem.isSubtypeOf(
+ type, verifier._typeProvider.doubleType)) {
return new DartObjectImpl(
verifier._typeProvider.doubleType, DoubleState.UNKNOWN_VALUE);
- } else if (type.isSubtypeOf(verifier._intType)) {
+ } else if (_typeSystem.isSubtypeOf(type, verifier._intType)) {
return new DartObjectImpl(
verifier._typeProvider.intType, IntState.UNKNOWN_VALUE);
- } else if (type.isSubtypeOf(verifier._numType)) {
+ } else if (_typeSystem.isSubtypeOf(type, verifier._numType)) {
return new DartObjectImpl(
verifier._typeProvider.numType, NumState.UNKNOWN_VALUE);
- } else if (type.isSubtypeOf(verifier._stringType)) {
+ } else if (_typeSystem.isSubtypeOf(type, verifier._stringType)) {
return new DartObjectImpl(
verifier._typeProvider.stringType, StringState.UNKNOWN_VALUE);
}
« no previous file with comments | « packages/analyzer/lib/src/generated/parser.dart ('k') | packages/analyzer/lib/src/generated/scanner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698