| Index: pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| diff --git a/pkg/analyzer_experimental/lib/src/generated/resolver.dart b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| index 4305b1abe944478d4e63a3aa2bd437d205d254a7..f641c48ba5dc8a24241a610615df14619f58a5a1 100644
|
| --- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| +++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| @@ -6,12 +6,14 @@ library engine.resolver;
|
| import 'dart:collection';
|
| import 'java_core.dart';
|
| import 'java_engine.dart';
|
| +import 'instrumentation.dart';
|
| import 'source.dart';
|
| import 'error.dart';
|
| import 'scanner.dart' as sc;
|
| import 'utilities_dart.dart';
|
| import 'ast.dart';
|
| -import 'parser.dart' show Parser;
|
| +import 'parser.dart' show Parser, ParserErrorCode;
|
| +import 'sdk.dart' show DartSdk;
|
| import 'element.dart' hide HideCombinator, ShowCombinator;
|
| import 'html.dart' as ht;
|
| import 'engine.dart';
|
| @@ -25,41 +27,29 @@ import 'element.dart' as __imp_combi show HideCombinator, ShowCombinator;
|
| */
|
| class CompilationUnitBuilder {
|
| /**
|
| - * The analysis context in which the element model will be built.
|
| - */
|
| - AnalysisContextImpl _analysisContext;
|
| - /**
|
| * Initialize a newly created compilation unit element builder.
|
| * @param analysisContext the analysis context in which the element model will be built
|
| */
|
| - CompilationUnitBuilder(AnalysisContextImpl analysisContext) {
|
| - this._analysisContext = analysisContext;
|
| + CompilationUnitBuilder() : super() {
|
| }
|
| /**
|
| * Build the compilation unit element for the given source.
|
| * @param source the source describing the compilation unit
|
| - * @return the compilation unit element that was built
|
| - * @throws AnalysisException if the analysis could not be performed
|
| - */
|
| - CompilationUnitElementImpl buildCompilationUnit(Source source) => buildCompilationUnit2(source, _analysisContext.parseCompilationUnit(source));
|
| - /**
|
| - * Build the compilation unit element for the given source.
|
| - * @param source the source describing the compilation unit
|
| * @param unit the AST structure representing the compilation unit
|
| * @return the compilation unit element that was built
|
| * @throws AnalysisException if the analysis could not be performed
|
| */
|
| - CompilationUnitElementImpl buildCompilationUnit2(Source source13, CompilationUnit unit) {
|
| + CompilationUnitElementImpl buildCompilationUnit(Source source18, CompilationUnit unit) {
|
| if (unit == null) {
|
| return null;
|
| }
|
| ElementHolder holder = new ElementHolder();
|
| ElementBuilder builder = new ElementBuilder(holder);
|
| unit.accept(builder);
|
| - CompilationUnitElementImpl element = new CompilationUnitElementImpl(source13.shortName);
|
| + CompilationUnitElementImpl element = new CompilationUnitElementImpl(source18.shortName);
|
| element.accessors = holder.accessors;
|
| element.functions = holder.functions;
|
| - element.source = source13;
|
| + element.source = source18;
|
| element.typeAliases = holder.typeAliases;
|
| element.types = holder.types;
|
| element.topLevelVariables = holder.topLevelVariables;
|
| @@ -96,6 +86,16 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
|
| ElementBuilder(ElementHolder initialHolder) {
|
| _currentHolder = initialHolder;
|
| }
|
| + Object visitBlock(Block node) {
|
| + bool wasInField = _inFieldContext;
|
| + _inFieldContext = false;
|
| + try {
|
| + node.visitChildren(this);
|
| + } finally {
|
| + _inFieldContext = wasInField;
|
| + }
|
| + return null;
|
| + }
|
| Object visitCatchClause(CatchClause node) {
|
| SimpleIdentifier exceptionParameter2 = node.exceptionParameter;
|
| if (exceptionParameter2 != null) {
|
| @@ -160,7 +160,13 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
|
| Object visitConstructorDeclaration(ConstructorDeclaration node) {
|
| _isValidMixin = false;
|
| ElementHolder holder = new ElementHolder();
|
| - visitChildren(holder, node);
|
| + bool wasInFunction = _inFunction;
|
| + _inFunction = true;
|
| + try {
|
| + visitChildren(holder, node);
|
| + } finally {
|
| + _inFunction = wasInFunction;
|
| + }
|
| SimpleIdentifier constructorName = node.name;
|
| ConstructorElementImpl element = new ConstructorElementImpl(constructorName);
|
| if (node.factoryKeyword != null) {
|
| @@ -210,6 +216,8 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
|
| if (node.isConst()) {
|
| parameter = new ConstParameterElementImpl(parameterName);
|
| parameter.const3 = true;
|
| + } else if (node.parameter is FieldFormalParameter) {
|
| + parameter = new FieldFormalParameterElementImpl(parameterName);
|
| } else {
|
| parameter = new ParameterElementImpl(parameterName);
|
| }
|
| @@ -238,7 +246,7 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
|
| Object visitFieldFormalParameter(FieldFormalParameter node) {
|
| if (node.parent is! DefaultFormalParameter) {
|
| SimpleIdentifier parameterName = node.identifier;
|
| - ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
|
| + FieldFormalParameterElementImpl parameter = new FieldFormalParameterElementImpl(parameterName);
|
| parameter.const3 = node.isConst();
|
| parameter.initializingFormal = true;
|
| parameter.final2 = node.isFinal();
|
| @@ -320,8 +328,7 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
|
| } finally {
|
| _inFunction = wasInFunction;
|
| }
|
| - SimpleIdentifier functionName = null;
|
| - FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
|
| + FunctionElementImpl element = new FunctionElementImpl.con2(node.beginToken.offset);
|
| element.functions = holder.functions;
|
| element.labels = holder.labels;
|
| element.localVariables = holder.localVariables;
|
| @@ -344,10 +351,10 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
|
| ElementHolder holder = new ElementHolder();
|
| visitChildren(holder, node);
|
| SimpleIdentifier aliasName = node.name;
|
| - List<ParameterElement> parameters10 = holder.parameters;
|
| + List<ParameterElement> parameters11 = holder.parameters;
|
| List<TypeVariableElement> typeVariables6 = holder.typeVariables;
|
| FunctionTypeAliasElementImpl element = new FunctionTypeAliasElementImpl(aliasName);
|
| - element.parameters = parameters10;
|
| + element.parameters = parameters11;
|
| element.typeVariables = typeVariables6;
|
| FunctionTypeImpl type = new FunctionTypeImpl.con2(element);
|
| type.typeArguments = createTypeVariableTypes(typeVariables6);
|
| @@ -364,7 +371,9 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
|
| _currentHolder.addParameter(parameter);
|
| parameterName.element = parameter;
|
| }
|
| - visitChildren(new ElementHolder(), node);
|
| + ElementHolder holder = new ElementHolder();
|
| + visitChildren(holder, node);
|
| + ((node.element as ParameterElementImpl)).parameters = holder.parameters;
|
| return null;
|
| }
|
| Object visitLabeledStatement(LabeledStatement node) {
|
| @@ -689,8 +698,18 @@ class ElementHolder {
|
| void addTypeVariable(TypeVariableElement element) {
|
| _typeVariables.add(element);
|
| }
|
| - List<PropertyAccessorElement> get accessors => new List.from(_accessors);
|
| - List<ConstructorElement> get constructors => new List.from(_constructors);
|
| + List<PropertyAccessorElement> get accessors {
|
| + if (_accessors.isEmpty) {
|
| + return PropertyAccessorElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_accessors);
|
| + }
|
| + List<ConstructorElement> get constructors {
|
| + if (_constructors.isEmpty) {
|
| + return ConstructorElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_constructors);
|
| + }
|
| FieldElement getField(String fieldName) {
|
| for (FieldElement field in _fields) {
|
| if (field.name == fieldName) {
|
| @@ -699,16 +718,66 @@ class ElementHolder {
|
| }
|
| return null;
|
| }
|
| - List<FieldElement> get fields => new List.from(_fields);
|
| - List<FunctionElement> get functions => new List.from(_functions);
|
| - List<LabelElement> get labels => new List.from(_labels);
|
| - List<LocalVariableElement> get localVariables => new List.from(_localVariables);
|
| - List<MethodElement> get methods => new List.from(_methods);
|
| - List<ParameterElement> get parameters => new List.from(_parameters);
|
| - List<TopLevelVariableElement> get topLevelVariables => new List.from(_topLevelVariables);
|
| - List<FunctionTypeAliasElement> get typeAliases => new List.from(_typeAliases);
|
| - List<ClassElement> get types => new List.from(_types);
|
| - List<TypeVariableElement> get typeVariables => new List.from(_typeVariables);
|
| + List<FieldElement> get fields {
|
| + if (_fields.isEmpty) {
|
| + return FieldElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_fields);
|
| + }
|
| + List<FunctionElement> get functions {
|
| + if (_functions.isEmpty) {
|
| + return FunctionElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_functions);
|
| + }
|
| + List<LabelElement> get labels {
|
| + if (_labels.isEmpty) {
|
| + return LabelElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_labels);
|
| + }
|
| + List<LocalVariableElement> get localVariables {
|
| + if (_localVariables.isEmpty) {
|
| + return LocalVariableElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_localVariables);
|
| + }
|
| + List<MethodElement> get methods {
|
| + if (_methods.isEmpty) {
|
| + return MethodElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_methods);
|
| + }
|
| + List<ParameterElement> get parameters {
|
| + if (_parameters.isEmpty) {
|
| + return ParameterElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_parameters);
|
| + }
|
| + List<TopLevelVariableElement> get topLevelVariables {
|
| + if (_topLevelVariables.isEmpty) {
|
| + return TopLevelVariableElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_topLevelVariables);
|
| + }
|
| + List<FunctionTypeAliasElement> get typeAliases {
|
| + if (_typeAliases.isEmpty) {
|
| + return FunctionTypeAliasElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_typeAliases);
|
| + }
|
| + List<ClassElement> get types {
|
| + if (_types.isEmpty) {
|
| + return ClassElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_types);
|
| + }
|
| + List<TypeVariableElement> get typeVariables {
|
| + if (_typeVariables.isEmpty) {
|
| + return TypeVariableElementImpl.EMPTY_ARRAY;
|
| + }
|
| + return new List.from(_typeVariables);
|
| + }
|
| }
|
| /**
|
| * Instances of the class {@code HtmlUnitBuilder} build an element model for a single HTML unit.
|
| @@ -722,7 +791,7 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| /**
|
| * The analysis context in which the element model will be built.
|
| */
|
| - AnalysisContextImpl _context;
|
| + InternalAnalysisContext _context;
|
| /**
|
| * The HTML element being built.
|
| */
|
| @@ -735,7 +804,7 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| * Initialize a newly created HTML unit builder.
|
| * @param context the analysis context in which the element model will be built
|
| */
|
| - HtmlUnitBuilder(AnalysisContextImpl context) {
|
| + HtmlUnitBuilder(InternalAnalysisContext context) {
|
| this._context = context;
|
| }
|
| /**
|
| @@ -751,9 +820,9 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| * @param unit the AST structure representing the HTML
|
| * @throws AnalysisException if the analysis could not be performed
|
| */
|
| - HtmlElementImpl buildHtmlElement2(Source source14, ht.HtmlUnit unit) {
|
| - HtmlElementImpl result = new HtmlElementImpl(_context, source14.shortName);
|
| - result.source = source14;
|
| + HtmlElementImpl buildHtmlElement2(Source source19, ht.HtmlUnit unit) {
|
| + HtmlElementImpl result = new HtmlElementImpl(_context, source19.shortName);
|
| + result.source = source19;
|
| _htmlElement = result;
|
| unit.accept(this);
|
| _htmlElement = null;
|
| @@ -775,15 +844,15 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath == null) {
|
| EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl(node);
|
| String contents = node.content;
|
| - AnalysisErrorListener errorListener = new AnalysisErrorListener_2();
|
| + AnalysisErrorListener errorListener = new AnalysisErrorListener_5();
|
| sc.StringScanner scanner = new sc.StringScanner(null, contents, errorListener);
|
| sc.Token firstToken = scanner.tokenize();
|
| List<int> lineStarts2 = scanner.lineStarts;
|
| Parser parser = new Parser(null, errorListener);
|
| CompilationUnit unit = parser.parseCompilationUnit(firstToken);
|
| try {
|
| - CompilationUnitBuilder builder = new CompilationUnitBuilder(_context);
|
| - CompilationUnitElementImpl elem = builder.buildCompilationUnit2(htmlSource, unit);
|
| + CompilationUnitBuilder builder = new CompilationUnitBuilder();
|
| + CompilationUnitElementImpl elem = builder.buildCompilationUnit(htmlSource, unit);
|
| LibraryElementImpl library = new LibraryElementImpl(_context, null);
|
| library.definingCompilationUnit = elem;
|
| script.scriptLibrary = library;
|
| @@ -794,7 +863,7 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| } else {
|
| ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl(node);
|
| if (scriptSourcePath != null) {
|
| - script.scriptSource = htmlSource.resolve(scriptSourcePath);
|
| + script.scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
|
| }
|
| _scripts.add(script);
|
| }
|
| @@ -840,11 +909,479 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| return false;
|
| }
|
| }
|
| -class AnalysisErrorListener_2 implements AnalysisErrorListener {
|
| +class AnalysisErrorListener_5 implements AnalysisErrorListener {
|
| void onError(AnalysisError error) {
|
| }
|
| }
|
| /**
|
| + * Instances of the class {@code DeclarationResolver} are used to resolve declarations in an AST
|
| + * structure to already built elements.
|
| + */
|
| +class DeclarationResolver extends RecursiveASTVisitor<Object> {
|
| + /**
|
| + * The compilation unit containing the AST nodes being visited.
|
| + */
|
| + CompilationUnitElement _enclosingUnit;
|
| + /**
|
| + * The function type alias containing the AST nodes being visited, or {@code null} if we are not
|
| + * in the scope of a function type alias.
|
| + */
|
| + FunctionTypeAliasElement _enclosingAlias;
|
| + /**
|
| + * The class containing the AST nodes being visited, or {@code null} if we are not in the scope of
|
| + * a class.
|
| + */
|
| + ClassElement _enclosingClass;
|
| + /**
|
| + * The method or function containing the AST nodes being visited, or {@code null} if we are not in
|
| + * the scope of a method or function.
|
| + */
|
| + ExecutableElement _enclosingExecutable;
|
| + /**
|
| + * The parameter containing the AST nodes being visited, or {@code null} if we are not in the
|
| + * scope of a parameter.
|
| + */
|
| + ParameterElement _enclosingParameter;
|
| + /**
|
| + * Initialize a newly created resolver.
|
| + */
|
| + DeclarationResolver() : super() {
|
| + }
|
| + /**
|
| + * Resolve the declarations within the given compilation unit to the elements rooted at the given
|
| + * element.
|
| + * @param unit the compilation unit to be resolved
|
| + * @param element the root of the element model used to resolve the AST nodes
|
| + */
|
| + void resolve(CompilationUnit unit, CompilationUnitElement element67) {
|
| + _enclosingUnit = element67;
|
| + unit.element = element67;
|
| + unit.accept(this);
|
| + }
|
| + Object visitCatchClause(CatchClause node) {
|
| + SimpleIdentifier exceptionParameter3 = node.exceptionParameter;
|
| + if (exceptionParameter3 != null) {
|
| + List<LocalVariableElement> localVariables3 = _enclosingExecutable.localVariables;
|
| + find3(localVariables3, exceptionParameter3);
|
| + SimpleIdentifier stackTraceParameter3 = node.stackTraceParameter;
|
| + if (stackTraceParameter3 != null) {
|
| + find3(localVariables3, stackTraceParameter3);
|
| + }
|
| + }
|
| + return super.visitCatchClause(node);
|
| + }
|
| + Object visitClassDeclaration(ClassDeclaration node) {
|
| + ClassElement outerClass = _enclosingClass;
|
| + try {
|
| + SimpleIdentifier className = node.name;
|
| + _enclosingClass = find3(_enclosingUnit.types, className);
|
| + return super.visitClassDeclaration(node);
|
| + } finally {
|
| + _enclosingClass = outerClass;
|
| + }
|
| + }
|
| + Object visitClassTypeAlias(ClassTypeAlias node) {
|
| + ClassElement outerClass = _enclosingClass;
|
| + try {
|
| + SimpleIdentifier className = node.name;
|
| + _enclosingClass = find3(_enclosingUnit.types, className);
|
| + return super.visitClassTypeAlias(node);
|
| + } finally {
|
| + _enclosingClass = outerClass;
|
| + }
|
| + }
|
| + Object visitConstructorDeclaration(ConstructorDeclaration node) {
|
| + ExecutableElement outerExecutable = _enclosingExecutable;
|
| + try {
|
| + SimpleIdentifier constructorName = node.name;
|
| + if (constructorName == null) {
|
| + _enclosingExecutable = _enclosingClass.unnamedConstructor;
|
| + } else {
|
| + _enclosingExecutable = _enclosingClass.getNamedConstructor(constructorName.name);
|
| + constructorName.element = _enclosingExecutable;
|
| + }
|
| + node.element = _enclosingExecutable as ConstructorElement;
|
| + return super.visitConstructorDeclaration(node);
|
| + } finally {
|
| + _enclosingExecutable = outerExecutable;
|
| + }
|
| + }
|
| + Object visitDeclaredIdentifier(DeclaredIdentifier node) {
|
| + SimpleIdentifier variableName = node.identifier;
|
| + find3(_enclosingExecutable.localVariables, variableName);
|
| + return super.visitDeclaredIdentifier(node);
|
| + }
|
| + Object visitDefaultFormalParameter(DefaultFormalParameter node) {
|
| + SimpleIdentifier parameterName = node.parameter.identifier;
|
| + ParameterElement element = find3(_enclosingExecutable.parameters, parameterName);
|
| + Expression defaultValue2 = node.defaultValue;
|
| + if (defaultValue2 != null) {
|
| + ExecutableElement outerExecutable = _enclosingExecutable;
|
| + try {
|
| + if (element == null) {
|
| + } else {
|
| + _enclosingExecutable = element.initializer;
|
| + }
|
| + defaultValue2.accept(this);
|
| + } finally {
|
| + _enclosingExecutable = outerExecutable;
|
| + }
|
| + }
|
| + ParameterElement outerParameter = _enclosingParameter;
|
| + try {
|
| + _enclosingParameter = element;
|
| + return super.visitDefaultFormalParameter(node);
|
| + } finally {
|
| + _enclosingParameter = outerParameter;
|
| + }
|
| + }
|
| + Object visitExportDirective(ExportDirective node) {
|
| + String uri3 = getStringValue(node.uri);
|
| + if (uri3 != null) {
|
| + LibraryElement library31 = _enclosingUnit.library;
|
| + ExportElement exportElement = find5(library31.exports, _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri3));
|
| + node.element = exportElement;
|
| + }
|
| + return super.visitExportDirective(node);
|
| + }
|
| + Object visitFieldFormalParameter(FieldFormalParameter node) {
|
| + if (node.parent is! DefaultFormalParameter) {
|
| + SimpleIdentifier parameterName = node.identifier;
|
| + ParameterElement element = find3(_enclosingExecutable.parameters, parameterName);
|
| + ParameterElement outerParameter = _enclosingParameter;
|
| + try {
|
| + _enclosingParameter = element;
|
| + return super.visitFieldFormalParameter(node);
|
| + } finally {
|
| + _enclosingParameter = outerParameter;
|
| + }
|
| + } else {
|
| + return super.visitFieldFormalParameter(node);
|
| + }
|
| + }
|
| + Object visitFunctionDeclaration(FunctionDeclaration node) {
|
| + ExecutableElement outerExecutable = _enclosingExecutable;
|
| + try {
|
| + SimpleIdentifier functionName = node.name;
|
| + sc.Token property = node.propertyKeyword;
|
| + if (property == null) {
|
| + if (_enclosingExecutable != null) {
|
| + _enclosingExecutable = find3(_enclosingExecutable.functions, functionName);
|
| + } else {
|
| + _enclosingExecutable = find3(_enclosingUnit.functions, functionName);
|
| + }
|
| + } else {
|
| + PropertyAccessorElement accessor = find3(_enclosingUnit.accessors, functionName);
|
| + if (identical(((property as sc.KeywordToken)).keyword, sc.Keyword.SET)) {
|
| + accessor = accessor.variable.setter;
|
| + functionName.element = accessor;
|
| + }
|
| + _enclosingExecutable = accessor;
|
| + }
|
| + node.functionExpression.element = _enclosingExecutable;
|
| + return super.visitFunctionDeclaration(node);
|
| + } finally {
|
| + _enclosingExecutable = outerExecutable;
|
| + }
|
| + }
|
| + Object visitFunctionExpression(FunctionExpression node) {
|
| + if (node.parent is! FunctionDeclaration) {
|
| + FunctionElement element = find2(_enclosingExecutable.functions, node.beginToken.offset);
|
| + node.element = element;
|
| + }
|
| + ExecutableElement outerExecutable = _enclosingExecutable;
|
| + try {
|
| + _enclosingExecutable = node.element;
|
| + return super.visitFunctionExpression(node);
|
| + } finally {
|
| + _enclosingExecutable = outerExecutable;
|
| + }
|
| + }
|
| + Object visitFunctionTypeAlias(FunctionTypeAlias node) {
|
| + FunctionTypeAliasElement outerAlias = _enclosingAlias;
|
| + try {
|
| + SimpleIdentifier aliasName = node.name;
|
| + _enclosingAlias = find3(_enclosingUnit.functionTypeAliases, aliasName);
|
| + return super.visitFunctionTypeAlias(node);
|
| + } finally {
|
| + _enclosingAlias = outerAlias;
|
| + }
|
| + }
|
| + Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
|
| + if (node.parent is! DefaultFormalParameter) {
|
| + SimpleIdentifier parameterName = node.identifier;
|
| + ParameterElement element = find3(_enclosingExecutable.parameters, parameterName);
|
| + ParameterElement outerParameter = _enclosingParameter;
|
| + try {
|
| + _enclosingParameter = element;
|
| + return super.visitFunctionTypedFormalParameter(node);
|
| + } finally {
|
| + _enclosingParameter = outerParameter;
|
| + }
|
| + } else {
|
| + return super.visitFunctionTypedFormalParameter(node);
|
| + }
|
| + }
|
| + Object visitImportDirective(ImportDirective node) {
|
| + String uri4 = getStringValue(node.uri);
|
| + if (uri4 != null) {
|
| + LibraryElement library32 = _enclosingUnit.library;
|
| + ImportElement importElement = find6(library32.imports, _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri4), node.prefix);
|
| + node.element = importElement;
|
| + }
|
| + return super.visitImportDirective(node);
|
| + }
|
| + Object visitLabeledStatement(LabeledStatement node) {
|
| + for (Label label in node.labels) {
|
| + SimpleIdentifier labelName = label.label;
|
| + find3(_enclosingExecutable.labels, labelName);
|
| + }
|
| + return super.visitLabeledStatement(node);
|
| + }
|
| + Object visitLibraryDirective(LibraryDirective node) {
|
| + node.element = _enclosingUnit.library;
|
| + return super.visitLibraryDirective(node);
|
| + }
|
| + Object visitMethodDeclaration(MethodDeclaration node) {
|
| + ExecutableElement outerExecutable = _enclosingExecutable;
|
| + try {
|
| + sc.Token property = node.propertyKeyword;
|
| + SimpleIdentifier methodName = node.name;
|
| + String nameOfMethod = methodName.name;
|
| + if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameters.length == 0) {
|
| + nameOfMethod = "unary-";
|
| + }
|
| + if (property == null) {
|
| + _enclosingExecutable = find4(_enclosingClass.methods, nameOfMethod, methodName.offset);
|
| + methodName.element = _enclosingExecutable;
|
| + } else {
|
| + PropertyAccessorElement accessor = find3(_enclosingClass.accessors, methodName);
|
| + if (identical(((property as sc.KeywordToken)).keyword, sc.Keyword.SET)) {
|
| + accessor = accessor.variable.setter;
|
| + methodName.element = accessor;
|
| + }
|
| + _enclosingExecutable = accessor;
|
| + }
|
| + return super.visitMethodDeclaration(node);
|
| + } finally {
|
| + _enclosingExecutable = outerExecutable;
|
| + }
|
| + }
|
| + Object visitPartDirective(PartDirective node) {
|
| + String uri5 = getStringValue(node.uri);
|
| + if (uri5 != null) {
|
| + Source partSource = _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri5);
|
| + node.element = find(_enclosingUnit.library.parts, partSource);
|
| + }
|
| + return super.visitPartDirective(node);
|
| + }
|
| + Object visitPartOfDirective(PartOfDirective node) {
|
| + node.element = _enclosingUnit.library;
|
| + return super.visitPartOfDirective(node);
|
| + }
|
| + Object visitSimpleFormalParameter(SimpleFormalParameter node) {
|
| + if (node.parent is! DefaultFormalParameter) {
|
| + SimpleIdentifier parameterName = node.identifier;
|
| + ParameterElement element = null;
|
| + if (_enclosingParameter != null) {
|
| + element = find3(_enclosingParameter.parameters, parameterName);
|
| + } else if (_enclosingExecutable != null) {
|
| + element = find3(_enclosingExecutable.parameters, parameterName);
|
| + } else if (_enclosingAlias != null) {
|
| + element = find3(_enclosingAlias.parameters, parameterName);
|
| + } else {
|
| + }
|
| + ParameterElement outerParameter = _enclosingParameter;
|
| + try {
|
| + _enclosingParameter = element;
|
| + return super.visitSimpleFormalParameter(node);
|
| + } finally {
|
| + _enclosingParameter = outerParameter;
|
| + }
|
| + } else {
|
| + }
|
| + return super.visitSimpleFormalParameter(node);
|
| + }
|
| + Object visitSwitchCase(SwitchCase node) {
|
| + for (Label label in node.labels) {
|
| + SimpleIdentifier labelName = label.label;
|
| + find3(_enclosingExecutable.labels, labelName);
|
| + }
|
| + return super.visitSwitchCase(node);
|
| + }
|
| + Object visitSwitchDefault(SwitchDefault node) {
|
| + for (Label label in node.labels) {
|
| + SimpleIdentifier labelName = label.label;
|
| + find3(_enclosingExecutable.labels, labelName);
|
| + }
|
| + return super.visitSwitchDefault(node);
|
| + }
|
| + Object visitTypeParameter(TypeParameter node) {
|
| + SimpleIdentifier parameterName = node.name;
|
| + if (_enclosingClass != null) {
|
| + find3(_enclosingClass.typeVariables, parameterName);
|
| + } else if (_enclosingAlias != null) {
|
| + find3(_enclosingAlias.typeVariables, parameterName);
|
| + }
|
| + return super.visitTypeParameter(node);
|
| + }
|
| + Object visitVariableDeclaration(VariableDeclaration node) {
|
| + VariableElement element = null;
|
| + SimpleIdentifier variableName = node.name;
|
| + if (_enclosingExecutable != null) {
|
| + element = find3(_enclosingExecutable.localVariables, variableName);
|
| + }
|
| + if (element == null && _enclosingClass != null) {
|
| + element = find3(_enclosingClass.fields, variableName);
|
| + }
|
| + if (element == null && _enclosingUnit != null) {
|
| + element = find3(_enclosingUnit.topLevelVariables, variableName);
|
| + }
|
| + Expression initializer5 = node.initializer;
|
| + if (initializer5 != null) {
|
| + ExecutableElement outerExecutable = _enclosingExecutable;
|
| + try {
|
| + if (element == null) {
|
| + } else {
|
| + _enclosingExecutable = element.initializer;
|
| + }
|
| + return super.visitVariableDeclaration(node);
|
| + } finally {
|
| + _enclosingExecutable = outerExecutable;
|
| + }
|
| + }
|
| + return super.visitVariableDeclaration(node);
|
| + }
|
| + /**
|
| + * Append the value of the given string literal to the given string builder.
|
| + * @param builder the builder to which the string's value is to be appended
|
| + * @param literal the string literal whose value is to be appended to the builder
|
| + * @throws IllegalArgumentException if the string is not a constant string without any string
|
| + * interpolation
|
| + */
|
| + void appendStringValue(JavaStringBuilder builder, StringLiteral literal) {
|
| + if (literal is SimpleStringLiteral) {
|
| + builder.append(((literal as SimpleStringLiteral)).value);
|
| + } else if (literal is AdjacentStrings) {
|
| + for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings) {
|
| + appendStringValue(builder, stringLiteral);
|
| + }
|
| + } else {
|
| + throw new IllegalArgumentException();
|
| + }
|
| + }
|
| + /**
|
| + * Return the element for the part with the given source, or {@code null} if there is no element
|
| + * for the given source.
|
| + * @param parts the elements for the parts
|
| + * @param partSource the source for the part whose element is to be returned
|
| + * @return the element for the part with the given source
|
| + */
|
| + CompilationUnitElement find(List<CompilationUnitElement> parts, Source partSource) {
|
| + for (CompilationUnitElement part in parts) {
|
| + if (part.source == partSource) {
|
| + return part;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + /**
|
| + * Return the element in the given array of elements that was created for the declaration at the
|
| + * given offset. This method should only be used when there is no name
|
| + * @param elements the elements of the appropriate kind that exist in the current context
|
| + * @param offset the offset of the name of the element to be returned
|
| + * @return the element at the given offset
|
| + */
|
| + Element find2(List<Element> elements, int offset) => find4(elements, "", offset);
|
| + /**
|
| + * Return the element in the given array of elements that was created for the declaration with the
|
| + * given name.
|
| + * @param elements the elements of the appropriate kind that exist in the current context
|
| + * @param identifier the name node in the declaration of the element to be returned
|
| + * @return the element created for the declaration with the given name
|
| + */
|
| + Element find3(List<Element> elements, SimpleIdentifier identifier) {
|
| + Element element = find4(elements, identifier.name, identifier.offset);
|
| + identifier.element = element;
|
| + return element;
|
| + }
|
| + /**
|
| + * Return the element in the given array of elements that was created for the declaration with the
|
| + * given name at the given offset.
|
| + * @param elements the elements of the appropriate kind that exist in the current context
|
| + * @param name the name of the element to be returned
|
| + * @param offset the offset of the name of the element to be returned
|
| + * @return the element with the given name and offset
|
| + */
|
| + Element find4(List<Element> elements, String name30, int offset) {
|
| + for (Element element in elements) {
|
| + if (element.name == name30 && element.nameOffset == offset) {
|
| + return element;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + /**
|
| + * Return the export element from the given array whose library has the given source, or{@code null} if there is no such export.
|
| + * @param exports the export elements being searched
|
| + * @param source the source of the library associated with the export element to being searched
|
| + * for
|
| + * @return the export element whose library has the given source
|
| + */
|
| + ExportElement find5(List<ExportElement> exports, Source source21) {
|
| + for (ExportElement export in exports) {
|
| + if (export.exportedLibrary.source == source21) {
|
| + return export;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + /**
|
| + * Return the import element from the given array whose library has the given source and that has
|
| + * the given prefix, or {@code null} if there is no such import.
|
| + * @param imports the import elements being searched
|
| + * @param source the source of the library associated with the import element to being searched
|
| + * for
|
| + * @param prefix the prefix with which the library was imported
|
| + * @return the import element whose library has the given source and prefix
|
| + */
|
| + ImportElement find6(List<ImportElement> imports, Source source22, SimpleIdentifier prefix12) {
|
| + for (ImportElement element in imports) {
|
| + if (element.importedLibrary.source == source22) {
|
| + PrefixElement prefixElement = element.prefix;
|
| + if (prefix12 == null) {
|
| + if (prefixElement == null) {
|
| + return element;
|
| + }
|
| + } else {
|
| + if (prefixElement != null && prefix12.name == prefixElement.name) {
|
| + return element;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + /**
|
| + * Return the value of the given string literal, or {@code null} if the string is not a constant
|
| + * string without any string interpolation.
|
| + * @param literal the string literal whose value is to be returned
|
| + * @return the value of the given string literal
|
| + */
|
| + String getStringValue(StringLiteral literal) {
|
| + if (literal is StringInterpolation) {
|
| + return null;
|
| + }
|
| + JavaStringBuilder builder = new JavaStringBuilder();
|
| + try {
|
| + appendStringValue(builder, literal);
|
| + } on IllegalArgumentException catch (exception) {
|
| + return null;
|
| + }
|
| + return builder.toString().trim();
|
| + }
|
| +}
|
| +/**
|
| * Instances of the class {@code ElementResolver} are used by instances of {@link ResolverVisitor}to resolve references within the AST structure to the elements being referenced. The requirements
|
| * for the element resolver are:
|
| * <ol>
|
| @@ -911,13 +1448,10 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| if (leftNode != null) {
|
| Type2 leftType = getType(leftNode);
|
| if (leftType != null) {
|
| - Element leftElement = leftType.element;
|
| - if (leftElement != null) {
|
| - MethodElement method = lookUpMethod(leftElement, operator7.lexeme);
|
| - if (method != null) {
|
| - node.element = method;
|
| - } else {
|
| - }
|
| + MethodElement method = lookUpMethod(leftType, operator7.lexeme);
|
| + if (method != null) {
|
| + node.element = method;
|
| + } else {
|
| }
|
| }
|
| }
|
| @@ -928,18 +1462,15 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| sc.Token operator8 = node.operator;
|
| if (operator8.isUserDefinableOperator()) {
|
| Type2 leftType = getType(node.leftOperand);
|
| - Element leftTypeElement;
|
| if (leftType == null || leftType.isDynamic()) {
|
| return null;
|
| } else if (leftType is FunctionType) {
|
| - leftTypeElement = _resolver.typeProvider.functionType.element;
|
| - } else {
|
| - leftTypeElement = leftType.element;
|
| + leftType = _resolver.typeProvider.functionType;
|
| }
|
| String methodName = operator8.lexeme;
|
| - MethodElement member = lookUpMethod(leftTypeElement, methodName);
|
| + MethodElement member = lookUpMethod(leftType, methodName);
|
| if (member == null) {
|
| - _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator8, [methodName]);
|
| + _resolver.reportError3(StaticWarningCode.UNDEFINED_OPERATOR, operator8, [methodName, leftType.name]);
|
| } else {
|
| node.element = member;
|
| }
|
| @@ -954,11 +1485,21 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| }
|
| return null;
|
| }
|
| + Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
|
| + FieldElement fieldElement = null;
|
| + SimpleIdentifier fieldName2 = node.fieldName;
|
| + ClassElement enclosingClass2 = _resolver.enclosingClass;
|
| + fieldElement = ((enclosingClass2 as ClassElementImpl)).getField(fieldName2.name);
|
| + if (fieldElement != null && !fieldElement.isSynthetic()) {
|
| + recordResolution(fieldName2, fieldElement);
|
| + }
|
| + return null;
|
| + }
|
| Object visitConstructorName(ConstructorName node) {
|
| - Type2 type13 = node.type.type;
|
| - if (type13 is DynamicTypeImpl) {
|
| + Type2 type14 = node.type.type;
|
| + if (type14 is DynamicTypeImpl) {
|
| return null;
|
| - } else if (type13 is! InterfaceType) {
|
| + } else if (type14 is! InterfaceType) {
|
| ASTNode parent14 = node.parent;
|
| if (parent14 is InstanceCreationExpression) {
|
| if (((parent14 as InstanceCreationExpression)).isConst()) {
|
| @@ -968,14 +1509,14 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| }
|
| return null;
|
| }
|
| - ClassElement classElement = ((type13 as InterfaceType)).element;
|
| + ClassElement classElement = ((type14 as InterfaceType)).element;
|
| ConstructorElement constructor;
|
| - SimpleIdentifier name15 = node.name;
|
| - if (name15 == null) {
|
| + SimpleIdentifier name17 = node.name;
|
| + if (name17 == null) {
|
| constructor = classElement.unnamedConstructor;
|
| } else {
|
| - constructor = classElement.getNamedConstructor(name15.name);
|
| - name15.element = constructor;
|
| + constructor = classElement.getNamedConstructor(name17.name);
|
| + name17.element = constructor;
|
| }
|
| node.element = constructor;
|
| return null;
|
| @@ -989,12 +1530,33 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| return null;
|
| }
|
| Object visitExportDirective(ExportDirective node) {
|
| - Element element26 = node.element;
|
| - if (element26 is ExportElement) {
|
| - resolveCombinators(((element26 as ExportElement)).exportedLibrary, node.combinators);
|
| + Element element28 = node.element;
|
| + if (element28 is ExportElement) {
|
| + resolveCombinators(((element28 as ExportElement)).exportedLibrary, node.combinators);
|
| }
|
| return null;
|
| }
|
| + Object visitFieldFormalParameter(FieldFormalParameter node) {
|
| + String fieldName = node.identifier.name;
|
| + ClassElement classElement = _resolver.enclosingClass;
|
| + if (classElement != null) {
|
| + FieldElement fieldElement = ((classElement as ClassElementImpl)).getField(fieldName);
|
| + if (fieldElement != null) {
|
| + if (!fieldElement.isSynthetic()) {
|
| + ParameterElement parameterElement = node.element;
|
| + if (parameterElement is FieldFormalParameterElementImpl) {
|
| + ((parameterElement as FieldFormalParameterElementImpl)).field = fieldElement;
|
| + if (fieldElement.isStatic()) {
|
| + _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
|
| + }
|
| + }
|
| + }
|
| + } else {
|
| + _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
|
| + }
|
| + }
|
| + return super.visitFieldFormalParameter(node);
|
| + }
|
| Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => null;
|
| Object visitImportDirective(ImportDirective node) {
|
| SimpleIdentifier prefixNode = node.prefix;
|
| @@ -1007,9 +1569,9 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| }
|
| }
|
| }
|
| - Element element27 = node.element;
|
| - if (element27 is ImportElement) {
|
| - resolveCombinators(((element27 as ImportElement)).importedLibrary, node.combinators);
|
| + Element element29 = node.element;
|
| + if (element29 is ImportElement) {
|
| + resolveCombinators(((element29 as ImportElement)).importedLibrary, node.combinators);
|
| }
|
| return null;
|
| }
|
| @@ -1018,16 +1580,15 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| if (arrayType == null || arrayType.isDynamic()) {
|
| return null;
|
| }
|
| - Element arrayTypeElement = arrayType.element;
|
| String operator;
|
| if (node.inSetterContext()) {
|
| operator = sc.TokenType.INDEX_EQ.lexeme;
|
| } else {
|
| operator = sc.TokenType.INDEX.lexeme;
|
| }
|
| - MethodElement member = lookUpMethod(arrayTypeElement, operator);
|
| + MethodElement member = lookUpMethod(arrayType, operator);
|
| if (member == null) {
|
| - _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, node, [operator]);
|
| + _resolver.reportError(StaticWarningCode.UNDEFINED_OPERATOR, node, [operator, arrayType.name]);
|
| } else {
|
| node.element = member;
|
| }
|
| @@ -1046,31 +1607,35 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| if (target == null) {
|
| element = _resolver.nameScope.lookup(methodName2, _resolver.definingLibrary);
|
| if (element == null) {
|
| - element = lookUpMethod(_resolver.enclosingClass, methodName2.name);
|
| - if (element == null) {
|
| - PropertyAccessorElement getter = lookUpGetter(_resolver.enclosingClass, methodName2.name);
|
| - if (getter != null) {
|
| - FunctionType getterType = getter.type;
|
| - if (getterType != null) {
|
| - Type2 returnType5 = getterType.returnType;
|
| - if (!isExecutableType(returnType5)) {
|
| - _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
|
| + ClassElement enclosingClass3 = _resolver.enclosingClass;
|
| + if (enclosingClass3 != null) {
|
| + InterfaceType enclosingType = enclosingClass3.type;
|
| + element = lookUpMethod(enclosingType, methodName2.name);
|
| + if (element == null) {
|
| + PropertyAccessorElement getter = lookUpGetter(enclosingType, methodName2.name);
|
| + if (getter != null) {
|
| + FunctionType getterType = getter.type;
|
| + if (getterType != null) {
|
| + Type2 returnType5 = getterType.returnType;
|
| + if (!isExecutableType(returnType5)) {
|
| + _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
|
| + }
|
| }
|
| + recordResolution(methodName2, getter);
|
| + return null;
|
| }
|
| - recordResolution(methodName2, getter);
|
| - return null;
|
| }
|
| }
|
| }
|
| } else {
|
| Type2 targetType = getType(target);
|
| if (targetType is InterfaceType) {
|
| - element = lookUpMethod(targetType.element, methodName2.name);
|
| + InterfaceType classType = targetType as InterfaceType;
|
| + element = lookUpMethod(classType, methodName2.name);
|
| if (element == null) {
|
| - ClassElement targetClass = targetType.element as ClassElement;
|
| - PropertyAccessorElement accessor = lookUpGetterInType(targetClass, methodName2.name);
|
| + PropertyAccessorElement accessor = classType.getGetter(methodName2.name);
|
| if (accessor != null) {
|
| - Type2 returnType6 = accessor.type.returnType.substitute2(((targetType as InterfaceType)).typeArguments, TypeVariableTypeImpl.getTypes(targetClass.typeVariables));
|
| + Type2 returnType6 = accessor.type.returnType;
|
| if (!isExecutableType(returnType6)) {
|
| _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
|
| return null;
|
| @@ -1085,8 +1650,8 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| } else if (target is SimpleIdentifier) {
|
| Element targetElement = ((target as SimpleIdentifier)).element;
|
| if (targetElement is PrefixElement) {
|
| - String name9 = "${((target as SimpleIdentifier)).name}.${methodName2}";
|
| - Identifier functionName = new Identifier_5(name9);
|
| + String name10 = "${((target as SimpleIdentifier)).name}.${methodName2}";
|
| + Identifier functionName = new Identifier_8(name10);
|
| element = _resolver.nameScope.lookup(functionName, _resolver.definingLibrary);
|
| } else {
|
| return null;
|
| @@ -1096,29 +1661,60 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| }
|
| }
|
| ExecutableElement invokedMethod = null;
|
| - if (element is ExecutableElement) {
|
| + if (element is PropertyAccessorElement) {
|
| + PropertyAccessorElement getter = element as PropertyAccessorElement;
|
| + FunctionType getterType = getter.type;
|
| + if (getterType != null) {
|
| + Type2 returnType7 = getterType.returnType;
|
| + if (!isExecutableType(returnType7)) {
|
| + _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
|
| + }
|
| + }
|
| + recordResolution(methodName2, element);
|
| + return null;
|
| + } else if (element is ExecutableElement) {
|
| invokedMethod = element as ExecutableElement;
|
| } else {
|
| if (element is PropertyInducingElement) {
|
| PropertyAccessorElement getter3 = ((element as PropertyInducingElement)).getter;
|
| FunctionType getterType = getter3.type;
|
| if (getterType != null) {
|
| - Type2 returnType7 = getterType.returnType;
|
| - if (!isExecutableType(returnType7)) {
|
| + Type2 returnType8 = getterType.returnType;
|
| + if (!isExecutableType(returnType8)) {
|
| _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
|
| }
|
| }
|
| recordResolution(methodName2, element);
|
| return null;
|
| } else if (element is VariableElement) {
|
| - Type2 variableType = ((element as VariableElement)).type;
|
| + Type2 variableType = _resolver.overrideManager.getType(element);
|
| + if (variableType == null) {
|
| + variableType = ((element as VariableElement)).type;
|
| + }
|
| if (!isExecutableType(variableType)) {
|
| _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
|
| }
|
| recordResolution(methodName2, element);
|
| return null;
|
| } else {
|
| - _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
|
| + if (target == null) {
|
| + ClassElement enclosingClass4 = _resolver.enclosingClass;
|
| + if (enclosingClass4 == null) {
|
| + _resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName2, [methodName2.name]);
|
| + } else if (element == null) {
|
| + _resolver.reportError(StaticTypeWarningCode.UNDEFINED_METHOD, methodName2, [methodName2.name, enclosingClass4.name]);
|
| + } else {
|
| + _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
|
| + }
|
| + } else {
|
| + Type2 targetType = getType(target);
|
| + String targetTypeName = targetType == null ? null : targetType.name;
|
| + if (targetTypeName == null) {
|
| + _resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName2, [methodName2.name]);
|
| + } else {
|
| + _resolver.reportError(StaticTypeWarningCode.UNDEFINED_METHOD, methodName2, [methodName2.name, targetTypeName]);
|
| + }
|
| + }
|
| return null;
|
| }
|
| }
|
| @@ -1132,16 +1728,15 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| if (operandType == null || operandType.isDynamic()) {
|
| return null;
|
| }
|
| - Element operandTypeElement = operandType.element;
|
| String methodName;
|
| if (identical(operator9.type, sc.TokenType.PLUS_PLUS)) {
|
| methodName = sc.TokenType.PLUS.lexeme;
|
| } else {
|
| methodName = sc.TokenType.MINUS.lexeme;
|
| }
|
| - MethodElement member = lookUpMethod(operandTypeElement, methodName);
|
| + MethodElement member = lookUpMethod(operandType, methodName);
|
| if (member == null) {
|
| - _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator9, [methodName]);
|
| + _resolver.reportError3(StaticWarningCode.UNDEFINED_OPERATOR, operator9, [methodName, operandType.name]);
|
| } else {
|
| node.element = member;
|
| }
|
| @@ -1149,81 +1744,81 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| }
|
| Object visitPrefixedIdentifier(PrefixedIdentifier node) {
|
| SimpleIdentifier prefix6 = node.prefix;
|
| - SimpleIdentifier identifier13 = node.identifier;
|
| + SimpleIdentifier identifier14 = node.identifier;
|
| Element prefixElement = prefix6.element;
|
| if (prefixElement is PrefixElement) {
|
| Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary);
|
| if (element == null) {
|
| return null;
|
| }
|
| - recordResolution(identifier13, element);
|
| + recordResolution(identifier14, element);
|
| return null;
|
| }
|
| if (prefixElement is ClassElement) {
|
| Element memberElement;
|
| if (node.identifier.inSetterContext()) {
|
| - memberElement = lookUpSetterInType((prefixElement as ClassElement), identifier13.name);
|
| + memberElement = ((prefixElement as ClassElementImpl)).getSetter(identifier14.name);
|
| } else {
|
| - memberElement = lookUpGetterInType((prefixElement as ClassElement), identifier13.name);
|
| + memberElement = ((prefixElement as ClassElementImpl)).getGetter(identifier14.name);
|
| }
|
| if (memberElement == null) {
|
| - MethodElement methodElement = lookUpMethod(prefixElement, identifier13.name);
|
| + MethodElement methodElement = lookUpMethod(((prefixElement as ClassElement)).type, identifier14.name);
|
| if (methodElement != null) {
|
| - recordResolution(identifier13, methodElement);
|
| + recordResolution(identifier14, methodElement);
|
| return null;
|
| }
|
| }
|
| if (memberElement == null) {
|
| - reportGetterOrSetterNotFound(node, identifier13, prefixElement.name);
|
| + reportGetterOrSetterNotFound(node, identifier14, prefixElement.name);
|
| } else {
|
| - recordResolution(identifier13, memberElement);
|
| + recordResolution(identifier14, memberElement);
|
| }
|
| return null;
|
| }
|
| - Element variableTypeElement;
|
| + Type2 variableType;
|
| if (prefixElement is PropertyAccessorElement) {
|
| PropertyAccessorElement accessor = prefixElement as PropertyAccessorElement;
|
| - FunctionType type14 = accessor.type;
|
| - if (type14 == null) {
|
| + FunctionType type15 = accessor.type;
|
| + if (type15 == null) {
|
| return null;
|
| }
|
| - Type2 variableType;
|
| if (accessor.isGetter()) {
|
| - variableType = type14.returnType;
|
| + variableType = type15.returnType;
|
| } else {
|
| - variableType = type14.normalParameterTypes[0];
|
| + variableType = type15.normalParameterTypes[0];
|
| }
|
| if (variableType == null || variableType.isDynamic()) {
|
| return null;
|
| }
|
| - variableTypeElement = variableType.element;
|
| } else if (prefixElement is VariableElement) {
|
| - Type2 prefixType = ((prefixElement as VariableElement)).type;
|
| - if (prefixType == null || prefixType.isDynamic()) {
|
| + variableType = _resolver.overrideManager.getType(prefixElement);
|
| + if (variableType == null) {
|
| + variableType = ((prefixElement as VariableElement)).type;
|
| + }
|
| + if (variableType == null || variableType.isDynamic()) {
|
| return null;
|
| }
|
| - variableTypeElement = prefixType.element;
|
| } else {
|
| return null;
|
| }
|
| PropertyAccessorElement memberElement = null;
|
| if (node.identifier.inSetterContext()) {
|
| - memberElement = lookUpSetter(variableTypeElement, identifier13.name);
|
| + memberElement = lookUpSetter(variableType, identifier14.name);
|
| }
|
| if (memberElement == null && node.identifier.inGetterContext()) {
|
| - memberElement = lookUpGetter(variableTypeElement, identifier13.name);
|
| + memberElement = lookUpGetter(variableType, identifier14.name);
|
| }
|
| if (memberElement == null) {
|
| - MethodElement methodElement = lookUpMethod(variableTypeElement, identifier13.name);
|
| + MethodElement methodElement = lookUpMethod(variableType, identifier14.name);
|
| if (methodElement != null) {
|
| - recordResolution(identifier13, methodElement);
|
| + recordResolution(identifier14, methodElement);
|
| return null;
|
| }
|
| }
|
| if (memberElement == null) {
|
| - reportGetterOrSetterNotFound(node, identifier13, variableTypeElement.name);
|
| + reportGetterOrSetterNotFound(node, identifier14, variableType.element.name);
|
| } else {
|
| - recordResolution(identifier13, memberElement);
|
| + recordResolution(identifier14, memberElement);
|
| }
|
| return null;
|
| }
|
| @@ -1235,7 +1830,6 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| if (operandType == null || operandType.isDynamic()) {
|
| return null;
|
| }
|
| - Element operandTypeElement = operandType.element;
|
| String methodName;
|
| if (identical(operatorType, sc.TokenType.PLUS_PLUS)) {
|
| methodName = sc.TokenType.PLUS.lexeme;
|
| @@ -1246,9 +1840,9 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| } else {
|
| methodName = operator10.lexeme;
|
| }
|
| - MethodElement member = lookUpMethod(operandTypeElement, methodName);
|
| + MethodElement member = lookUpMethod(operandType, methodName);
|
| if (member == null) {
|
| - _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator10, [methodName]);
|
| + _resolver.reportError3(StaticWarningCode.UNDEFINED_OPERATOR, operator10, [methodName, operandType.name]);
|
| } else {
|
| node.element = member;
|
| }
|
| @@ -1260,40 +1854,45 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| if (targetType is! InterfaceType) {
|
| return null;
|
| }
|
| - ClassElement targetElement = ((targetType as InterfaceType)).element;
|
| SimpleIdentifier identifier = node.propertyName;
|
| PropertyAccessorElement memberElement = null;
|
| if (identifier.inSetterContext()) {
|
| - memberElement = lookUpSetter(targetElement, identifier.name);
|
| + memberElement = lookUpSetter(targetType, identifier.name);
|
| }
|
| if (memberElement == null && identifier.inGetterContext()) {
|
| - memberElement = lookUpGetter(targetElement, identifier.name);
|
| + memberElement = lookUpGetter(targetType, identifier.name);
|
| }
|
| if (memberElement == null) {
|
| - MethodElement methodElement = lookUpMethod(targetElement, identifier.name);
|
| + MethodElement methodElement = lookUpMethod(targetType, identifier.name);
|
| if (methodElement != null) {
|
| recordResolution(identifier, methodElement);
|
| return null;
|
| }
|
| }
|
| if (memberElement == null) {
|
| - _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier, [identifier.name]);
|
| + if (identifier.inSetterContext()) {
|
| + _resolver.reportError(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, targetType.name]);
|
| + } else if (identifier.inGetterContext()) {
|
| + _resolver.reportError(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, targetType.name]);
|
| + } else {
|
| + _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, identifier, [identifier.name]);
|
| + }
|
| } else {
|
| recordResolution(identifier, memberElement);
|
| }
|
| return null;
|
| }
|
| Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
|
| - ClassElement enclosingClass2 = _resolver.enclosingClass;
|
| - if (enclosingClass2 == null) {
|
| + ClassElement enclosingClass5 = _resolver.enclosingClass;
|
| + if (enclosingClass5 == null) {
|
| return null;
|
| }
|
| SimpleIdentifier name = node.constructorName;
|
| ConstructorElement element;
|
| if (name == null) {
|
| - element = enclosingClass2.unnamedConstructor;
|
| + element = enclosingClass5.unnamedConstructor;
|
| } else {
|
| - element = enclosingClass2.getNamedConstructor(name.name);
|
| + element = enclosingClass5.getNamedConstructor(name.name);
|
| }
|
| if (element == null) {
|
| return null;
|
| @@ -1311,34 +1910,39 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| }
|
| Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary);
|
| if (element is PropertyAccessorElement && node.inSetterContext()) {
|
| - PropertyInducingElement variable4 = ((element as PropertyAccessorElement)).variable;
|
| - if (variable4 != null) {
|
| - PropertyAccessorElement setter3 = variable4.setter;
|
| + PropertyInducingElement variable5 = ((element as PropertyAccessorElement)).variable;
|
| + if (variable5 != null) {
|
| + PropertyAccessorElement setter3 = variable5.setter;
|
| if (setter3 != null) {
|
| element = setter3;
|
| }
|
| }
|
| }
|
| - if (element == null && node.inSetterContext()) {
|
| - element = lookUpSetter(_resolver.enclosingClass, node.name);
|
| - }
|
| - if (element == null && node.inGetterContext()) {
|
| - element = lookUpGetter(_resolver.enclosingClass, node.name);
|
| - }
|
| - if (element == null) {
|
| - element = lookUpMethod(_resolver.enclosingClass, node.name);
|
| + ClassElement enclosingClass6 = _resolver.enclosingClass;
|
| + if (element == null && enclosingClass6 != null) {
|
| + InterfaceType enclosingType = enclosingClass6.type;
|
| + if (element == null && node.inSetterContext()) {
|
| + element = lookUpSetter(enclosingType, node.name);
|
| + }
|
| + if (element == null && node.inGetterContext()) {
|
| + element = lookUpGetter(enclosingType, node.name);
|
| + }
|
| + if (element == null) {
|
| + element = lookUpMethod(enclosingType, node.name);
|
| + }
|
| }
|
| if (element == null) {
|
| + _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
|
| }
|
| recordResolution(node, element);
|
| return null;
|
| }
|
| Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
|
| - ClassElement enclosingClass3 = _resolver.enclosingClass;
|
| - if (enclosingClass3 == null) {
|
| + ClassElement enclosingClass7 = _resolver.enclosingClass;
|
| + if (enclosingClass7 == null) {
|
| return null;
|
| }
|
| - ClassElement superclass = getSuperclass(enclosingClass3);
|
| + ClassElement superclass = getSuperclass(enclosingClass7);
|
| if (superclass == null) {
|
| return null;
|
| }
|
| @@ -1376,11 +1980,11 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| * @param name the name being searched for
|
| * @return the parameter with the given name
|
| */
|
| - ParameterElement findNamedParameter(List<ParameterElement> parameters, String name26) {
|
| + ParameterElement findNamedParameter(List<ParameterElement> parameters, String name31) {
|
| for (ParameterElement parameter in parameters) {
|
| if (identical(parameter.parameterKind, ParameterKind.NAMED)) {
|
| String parameteName = parameter.name;
|
| - if (parameteName != null && parameteName == name26) {
|
| + if (parameteName != null && parameteName == name31) {
|
| return parameter;
|
| }
|
| }
|
| @@ -1416,74 +2020,65 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| * @param type the type being tested
|
| * @return {@code true} if the given type represents an object that could be invoked
|
| */
|
| - bool isExecutableType(Type2 type) => type.isDynamic() || (type is FunctionType) || type.isDartCoreFunction();
|
| + bool isExecutableType(Type2 type) {
|
| + if (type.isDynamic() || (type is FunctionType) || type.isDartCoreFunction()) {
|
| + return true;
|
| + } else if (type is InterfaceType) {
|
| + ClassElement classElement = ((type as InterfaceType)).element;
|
| + MethodElement methodElement = classElement.lookUpMethod("call", _resolver.definingLibrary);
|
| + return methodElement != null;
|
| + }
|
| + return false;
|
| + }
|
| /**
|
| * Look up the getter with the given name in the given type. Return the element representing the
|
| * getter that was found, or {@code null} if there is no getter with the given name.
|
| - * @param element the element representing the type in which the getter is defined
|
| + * @param type the type in which the getter is defined
|
| * @param getterName the name of the getter being looked up
|
| * @return the element representing the getter that was found
|
| */
|
| - PropertyAccessorElement lookUpGetter(Element element, String getterName) {
|
| - if (identical(element, DynamicTypeImpl.instance)) {
|
| - return null;
|
| - }
|
| - element = resolveTypeVariable(element);
|
| - if (element is ClassElement) {
|
| - ClassElement classElement = element as ClassElement;
|
| - PropertyAccessorElement member = classElement.lookUpGetter(getterName, _resolver.definingLibrary);
|
| - if (member != null) {
|
| - return member;
|
| + PropertyAccessorElement lookUpGetter(Type2 type, String getterName) {
|
| + type = resolveTypeVariable(type);
|
| + if (type is InterfaceType) {
|
| + InterfaceType interfaceType = type as InterfaceType;
|
| + PropertyAccessorElement accessor = interfaceType.lookUpGetter(getterName, _resolver.definingLibrary);
|
| + if (accessor != null) {
|
| + return accessor;
|
| }
|
| - return lookUpGetterInInterfaces((element as ClassElement), getterName, new Set<ClassElement>());
|
| + return lookUpGetterInInterfaces(interfaceType, getterName, new Set<ClassElement>());
|
| }
|
| return null;
|
| }
|
| /**
|
| - * Look up the name of a getter in the interfaces implemented by the given type, either directly
|
| - * or indirectly. Return the element representing the getter that was found, or {@code null} if
|
| - * there is no getter with the given name.
|
| - * @param element the element representing the type in which the getter is defined
|
| - * @param memberName the name of the getter being looked up
|
| + * Look up the getter with the given name in the interfaces implemented by the given type, either
|
| + * directly or indirectly. Return the element representing the getter that was found, or{@code null} if there is no getter with the given name.
|
| + * @param targetType the type in which the getter might be defined
|
| + * @param getterName the name of the getter being looked up
|
| * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
|
| * to prevent infinite recursion and to optimize the search
|
| * @return the element representing the getter that was found
|
| */
|
| - PropertyAccessorElement lookUpGetterInInterfaces(ClassElement targetClass, String memberName, Set<ClassElement> visitedInterfaces) {
|
| + PropertyAccessorElement lookUpGetterInInterfaces(InterfaceType targetType, String getterName, Set<ClassElement> visitedInterfaces) {
|
| + ClassElement targetClass = targetType.element;
|
| if (visitedInterfaces.contains(targetClass)) {
|
| return null;
|
| }
|
| javaSetAdd(visitedInterfaces, targetClass);
|
| - PropertyAccessorElement member = lookUpGetterInType(targetClass, memberName);
|
| - if (member != null) {
|
| - return member;
|
| + PropertyAccessorElement getter = targetType.getGetter(getterName);
|
| + if (getter != null) {
|
| + return getter;
|
| }
|
| - for (InterfaceType interfaceType in targetClass.interfaces) {
|
| - member = lookUpGetterInInterfaces(interfaceType.element, memberName, visitedInterfaces);
|
| - if (member != null) {
|
| - return member;
|
| + for (InterfaceType interfaceType in targetType.interfaces) {
|
| + getter = lookUpGetterInInterfaces(interfaceType, getterName, visitedInterfaces);
|
| + if (getter != null) {
|
| + return getter;
|
| }
|
| }
|
| - ClassElement superclass = getSuperclass(targetClass);
|
| - if (superclass == null) {
|
| + InterfaceType superclass3 = targetType.superclass;
|
| + if (superclass3 == null) {
|
| return null;
|
| }
|
| - return lookUpGetterInInterfaces(superclass, memberName, visitedInterfaces);
|
| - }
|
| - /**
|
| - * Look up the name of a getter in the given type. Return the element representing the getter that
|
| - * was found, or {@code null} if there is no getter with the given name.
|
| - * @param element the element representing the type in which the getter is defined
|
| - * @param memberName the name of the getter being looked up
|
| - * @return the element representing the getter that was found
|
| - */
|
| - PropertyAccessorElement lookUpGetterInType(ClassElement element, String memberName) {
|
| - for (PropertyAccessorElement accessor in element.accessors) {
|
| - if (accessor.isGetter() && accessor.name == memberName) {
|
| - return accessor;
|
| - }
|
| - }
|
| - return null;
|
| + return lookUpGetterInInterfaces(superclass3, getterName, visitedInterfaces);
|
| }
|
| /**
|
| * Find the element corresponding to the given label node in the current label scope.
|
| @@ -1526,138 +2121,102 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| /**
|
| * Look up the method with the given name in the given type. Return the element representing the
|
| * method that was found, or {@code null} if there is no method with the given name.
|
| - * @param element the element representing the type in which the method is defined
|
| + * @param type the type in which the method is defined
|
| * @param methodName the name of the method being looked up
|
| * @return the element representing the method that was found
|
| */
|
| - MethodElement lookUpMethod(Element element, String methodName) {
|
| - if (identical(element, DynamicTypeImpl.instance)) {
|
| - return null;
|
| - }
|
| - element = resolveTypeVariable(element);
|
| - if (element is ClassElement) {
|
| - ClassElement classElement = element as ClassElement;
|
| - MethodElement member = classElement.lookUpMethod(methodName, _resolver.definingLibrary);
|
| - if (member != null) {
|
| - return member;
|
| + MethodElement lookUpMethod(Type2 type, String methodName) {
|
| + type = resolveTypeVariable(type);
|
| + if (type is InterfaceType) {
|
| + InterfaceType interfaceType = type as InterfaceType;
|
| + MethodElement method = interfaceType.lookUpMethod(methodName, _resolver.definingLibrary);
|
| + if (method != null) {
|
| + return method;
|
| }
|
| - return lookUpMethodInInterfaces((element as ClassElement), methodName, new Set<ClassElement>());
|
| + return lookUpMethodInInterfaces(interfaceType, methodName, new Set<ClassElement>());
|
| }
|
| return null;
|
| }
|
| /**
|
| - * Look up the name of a member in the interfaces implemented by the given type, either directly
|
| - * or indirectly. Return the element representing the member that was found, or {@code null} if
|
| - * there is no member with the given name.
|
| - * @param element the element representing the type in which the member is defined
|
| - * @param memberName the name of the member being looked up
|
| + * Look up the method with the given name in the interfaces implemented by the given type, either
|
| + * directly or indirectly. Return the element representing the method that was found, or{@code null} if there is no method with the given name.
|
| + * @param targetType the type in which the member might be defined
|
| + * @param methodName the name of the method being looked up
|
| * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
|
| * to prevent infinite recursion and to optimize the search
|
| - * @return the element representing the member that was found
|
| + * @return the element representing the method that was found
|
| */
|
| - MethodElement lookUpMethodInInterfaces(ClassElement targetClass, String memberName, Set<ClassElement> visitedInterfaces) {
|
| + MethodElement lookUpMethodInInterfaces(InterfaceType targetType, String methodName, Set<ClassElement> visitedInterfaces) {
|
| + ClassElement targetClass = targetType.element;
|
| if (visitedInterfaces.contains(targetClass)) {
|
| return null;
|
| }
|
| javaSetAdd(visitedInterfaces, targetClass);
|
| - MethodElement member = lookUpMethodInType(targetClass, memberName);
|
| - if (member != null) {
|
| - return member;
|
| + MethodElement method = targetType.getMethod(methodName);
|
| + if (method != null) {
|
| + return method;
|
| }
|
| - for (InterfaceType interfaceType in targetClass.interfaces) {
|
| - member = lookUpMethodInInterfaces(interfaceType.element, memberName, visitedInterfaces);
|
| - if (member != null) {
|
| - return member;
|
| + for (InterfaceType interfaceType in targetType.interfaces) {
|
| + method = lookUpMethodInInterfaces(interfaceType, methodName, visitedInterfaces);
|
| + if (method != null) {
|
| + return method;
|
| }
|
| }
|
| - ClassElement superclass = getSuperclass(targetClass);
|
| - if (superclass == null) {
|
| + InterfaceType superclass4 = targetType.superclass;
|
| + if (superclass4 == null) {
|
| return null;
|
| }
|
| - return lookUpMethodInInterfaces(superclass, memberName, visitedInterfaces);
|
| - }
|
| - /**
|
| - * Look up the name of a method in the given type. Return the element representing the method that
|
| - * was found, or {@code null} if there is no method with the given name.
|
| - * @param element the element representing the type in which the method is defined
|
| - * @param memberName the name of the method being looked up
|
| - * @return the element representing the method that was found
|
| - */
|
| - MethodElement lookUpMethodInType(ClassElement element, String memberName) {
|
| - for (MethodElement method in element.methods) {
|
| - if (method.name == memberName) {
|
| - return method;
|
| - }
|
| - }
|
| - return null;
|
| + return lookUpMethodInInterfaces(superclass4, methodName, visitedInterfaces);
|
| }
|
| /**
|
| * Look up the setter with the given name in the given type. Return the element representing the
|
| * setter that was found, or {@code null} if there is no setter with the given name.
|
| - * @param element the element representing the type in which the setter is defined
|
| + * @param type the type in which the setter is defined
|
| * @param setterName the name of the setter being looked up
|
| * @return the element representing the setter that was found
|
| */
|
| - PropertyAccessorElement lookUpSetter(Element element, String setterName) {
|
| - if (identical(element, DynamicTypeImpl.instance)) {
|
| - return null;
|
| - }
|
| - element = resolveTypeVariable(element);
|
| - if (element is ClassElement) {
|
| - ClassElement classElement = element as ClassElement;
|
| - PropertyAccessorElement member = classElement.lookUpSetter(setterName, _resolver.definingLibrary);
|
| - if (member != null) {
|
| - return member;
|
| + PropertyAccessorElement lookUpSetter(Type2 type, String setterName) {
|
| + type = resolveTypeVariable(type);
|
| + if (type is InterfaceType) {
|
| + InterfaceType interfaceType = type as InterfaceType;
|
| + PropertyAccessorElement accessor = interfaceType.lookUpSetter(setterName, _resolver.definingLibrary);
|
| + if (accessor != null) {
|
| + return accessor;
|
| }
|
| - return lookUpSetterInInterfaces((element as ClassElement), setterName, new Set<ClassElement>());
|
| + return lookUpSetterInInterfaces(interfaceType, setterName, new Set<ClassElement>());
|
| }
|
| return null;
|
| }
|
| /**
|
| - * Look up the name of a setter in the interfaces implemented by the given type, either directly
|
| - * or indirectly. Return the element representing the setter that was found, or {@code null} if
|
| - * there is no setter with the given name.
|
| - * @param element the element representing the type in which the setter is defined
|
| - * @param memberName the name of the setter being looked up
|
| + * Look up the setter with the given name in the interfaces implemented by the given type, either
|
| + * directly or indirectly. Return the element representing the setter that was found, or{@code null} if there is no setter with the given name.
|
| + * @param targetType the type in which the setter might be defined
|
| + * @param setterName the name of the setter being looked up
|
| * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
|
| * to prevent infinite recursion and to optimize the search
|
| * @return the element representing the setter that was found
|
| */
|
| - PropertyAccessorElement lookUpSetterInInterfaces(ClassElement targetClass, String memberName, Set<ClassElement> visitedInterfaces) {
|
| + PropertyAccessorElement lookUpSetterInInterfaces(InterfaceType targetType, String setterName, Set<ClassElement> visitedInterfaces) {
|
| + ClassElement targetClass = targetType.element;
|
| if (visitedInterfaces.contains(targetClass)) {
|
| return null;
|
| }
|
| javaSetAdd(visitedInterfaces, targetClass);
|
| - PropertyAccessorElement member = lookUpSetterInType(targetClass, memberName);
|
| - if (member != null) {
|
| - return member;
|
| + PropertyAccessorElement setter = targetType.getGetter(setterName);
|
| + if (setter != null) {
|
| + return setter;
|
| }
|
| - for (InterfaceType interfaceType in targetClass.interfaces) {
|
| - member = lookUpSetterInInterfaces(interfaceType.element, memberName, visitedInterfaces);
|
| - if (member != null) {
|
| - return member;
|
| + for (InterfaceType interfaceType in targetType.interfaces) {
|
| + setter = lookUpSetterInInterfaces(interfaceType, setterName, visitedInterfaces);
|
| + if (setter != null) {
|
| + return setter;
|
| }
|
| }
|
| - ClassElement superclass = getSuperclass(targetClass);
|
| - if (superclass == null) {
|
| - return null;
|
| - }
|
| - return lookUpSetterInInterfaces(superclass, memberName, visitedInterfaces);
|
| - }
|
| - /**
|
| - * Look up the name of a setter in the given type. Return the element representing the setter that
|
| - * was found, or {@code null} if there is no setter with the given name.
|
| - * @param element the element representing the type in which the setter is defined
|
| - * @param memberName the name of the setter being looked up
|
| - * @return the element representing the setter that was found
|
| - */
|
| - PropertyAccessorElement lookUpSetterInType(ClassElement element, String memberName) {
|
| - for (PropertyAccessorElement accessor in element.accessors) {
|
| - if (accessor.isSetter() && accessor.name == memberName) {
|
| - return accessor;
|
| - }
|
| + InterfaceType superclass5 = targetType.superclass;
|
| + if (superclass5 == null) {
|
| + return null;
|
| }
|
| - return null;
|
| + return lookUpSetterInInterfaces(superclass5, setterName, visitedInterfaces);
|
| }
|
| /**
|
| * Return the binary operator that is invoked by the given compound assignment operator.
|
| @@ -1699,9 +2258,9 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| * @param node the AST node that was resolved
|
| * @param element the element to which the AST node was resolved
|
| */
|
| - void recordResolution(SimpleIdentifier node, Element element58) {
|
| - if (element58 != null) {
|
| - node.element = element58;
|
| + void recordResolution(SimpleIdentifier node, Element element68) {
|
| + if (element68 != null) {
|
| + node.element = element68;
|
| }
|
| }
|
| /**
|
| @@ -1712,10 +2271,10 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| * @param identifier the identifier in the passed prefix identifier
|
| * @param typeName the name of the type of the left hand side of the passed prefixed identifier
|
| */
|
| - void reportGetterOrSetterNotFound(PrefixedIdentifier node, SimpleIdentifier identifier30, String typeName) {
|
| + void reportGetterOrSetterNotFound(PrefixedIdentifier node, SimpleIdentifier identifier32, String typeName) {
|
| bool isSetterContext = node.identifier.inSetterContext();
|
| ErrorCode errorCode = isSetterContext ? StaticTypeWarningCode.UNDEFINED_SETTER : StaticTypeWarningCode.UNDEFINED_GETTER;
|
| - _resolver.reportError(errorCode, identifier30, [identifier30.name, typeName]);
|
| + _resolver.reportError(errorCode, identifier32, [identifier32.name, typeName]);
|
| }
|
| /**
|
| * Resolve the names in the given combinators in the scope of the given library.
|
| @@ -1753,43 +2312,43 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| if (invokedMethod == null) {
|
| return;
|
| }
|
| - List<ParameterElement> parameters11 = invokedMethod.parameters;
|
| + List<ParameterElement> parameters13 = invokedMethod.parameters;
|
| for (Expression argument in argumentList.arguments) {
|
| if (argument is NamedExpression) {
|
| - SimpleIdentifier name16 = ((argument as NamedExpression)).name.label;
|
| - ParameterElement parameter = findNamedParameter(parameters11, name16.name);
|
| + SimpleIdentifier name18 = ((argument as NamedExpression)).name.label;
|
| + ParameterElement parameter = findNamedParameter(parameters13, name18.name);
|
| if (parameter != null) {
|
| - recordResolution(name16, parameter);
|
| + recordResolution(name18, parameter);
|
| }
|
| }
|
| }
|
| }
|
| /**
|
| - * If the given element is a type variable, resolve it to the class that should be used when
|
| - * looking up members. Otherwise, return the original element.
|
| - * @param element the element that is to be resolved if it is a type variable
|
| - * @return the class that should be used in place of the argument if it is a type variable, or the
|
| + * If the given type is a type variable, resolve it to the type that should be used when looking
|
| + * up members. Otherwise, return the original type.
|
| + * @param type the type that is to be resolved if it is a type variable
|
| + * @return the type that should be used in place of the argument if it is a type variable, or the
|
| * original argument if it isn't a type variable
|
| */
|
| - Element resolveTypeVariable(Element element59) {
|
| - if (element59 is TypeVariableElement) {
|
| - Type2 bound4 = ((element59 as TypeVariableElement)).bound;
|
| + Type2 resolveTypeVariable(Type2 type) {
|
| + if (type is TypeVariableType) {
|
| + Type2 bound4 = ((type as TypeVariableType)).element.bound;
|
| if (bound4 == null) {
|
| - return _resolver.typeProvider.objectType.element;
|
| + return _resolver.typeProvider.objectType;
|
| }
|
| - return bound4.element;
|
| + return bound4;
|
| }
|
| - return element59;
|
| + return type;
|
| }
|
| }
|
| -class Identifier_5 extends Identifier {
|
| - String name9;
|
| - Identifier_5(this.name9) : super();
|
| +class Identifier_8 extends Identifier {
|
| + String name10;
|
| + Identifier_8(this.name10) : super();
|
| accept(ASTVisitor visitor) => null;
|
| sc.Token get beginToken => null;
|
| Element get element => null;
|
| sc.Token get endToken => null;
|
| - String get name => name9;
|
| + String get name => name10;
|
| void visitChildren(ASTVisitor<Object> visitor) {
|
| }
|
| }
|
| @@ -1803,7 +2362,7 @@ class Library {
|
| /**
|
| * The analysis context in which this library is being analyzed.
|
| */
|
| - AnalysisContextImpl _analysisContext;
|
| + InternalAnalysisContext _analysisContext;
|
| /**
|
| * The listener to which analysis errors will be reported.
|
| */
|
| @@ -1843,7 +2402,7 @@ class Library {
|
| * @param errorListener the listener to which analysis errors will be reported
|
| * @param librarySource the source specifying the defining compilation unit of this library
|
| */
|
| - Library(AnalysisContextImpl analysisContext, AnalysisErrorListener errorListener, Source librarySource) {
|
| + Library(InternalAnalysisContext analysisContext, AnalysisErrorListener errorListener, Source librarySource) {
|
| this._analysisContext = analysisContext;
|
| this._errorListener = errorListener;
|
| this._librarySource = librarySource;
|
| @@ -1872,13 +2431,14 @@ class Library {
|
| CompilationUnit getAST(Source source) {
|
| CompilationUnit unit = _astMap[source];
|
| if (unit == null) {
|
| - unit = _analysisContext.parseCompilationUnit(source);
|
| + unit = _analysisContext.computeResolvableCompilationUnit(source);
|
| _astMap[source] = unit;
|
| }
|
| return unit;
|
| }
|
| /**
|
| - * Return a collection containing the sources for the compilation units in this library.
|
| + * Return a collection containing the sources for the compilation units in this library, including
|
| + * the defining compilation unit.
|
| * @return the sources for the compilation units in this library
|
| */
|
| Set<Source> get compilationUnitSources => _astMap.keys.toSet();
|
| @@ -1975,7 +2535,11 @@ class Library {
|
| _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION, []));
|
| return null;
|
| }
|
| - return getSource2(getStringValue(uriLiteral));
|
| + Source source = getSource2(getStringValue(uriLiteral));
|
| + if (source == null || !source.exists()) {
|
| + _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriLiteral.toSource()]));
|
| + }
|
| + return source;
|
| }
|
| /**
|
| * Set whether this library explicitly imports core to match the given value.
|
| @@ -2020,7 +2584,7 @@ class Library {
|
| if (uri == null) {
|
| return null;
|
| }
|
| - return _librarySource.resolve(uri);
|
| + return _analysisContext.sourceFactory.resolveUri(_librarySource, uri);
|
| }
|
| /**
|
| * Return the value of the given string literal, or {@code null} if the string is not a constant
|
| @@ -2046,16 +2610,12 @@ class LibraryElementBuilder {
|
| /**
|
| * The analysis context in which the element model will be built.
|
| */
|
| - AnalysisContextImpl _analysisContext;
|
| + InternalAnalysisContext _analysisContext;
|
| /**
|
| * The listener to which errors will be reported.
|
| */
|
| AnalysisErrorListener _errorListener;
|
| /**
|
| - * The name of the core library.
|
| - */
|
| - static String CORE_LIBRARY_URI = "dart:core";
|
| - /**
|
| * The name of the function used as an entry point.
|
| */
|
| static String _ENTRY_POINT_NAME = "main";
|
| @@ -2074,10 +2634,10 @@ class LibraryElementBuilder {
|
| * @throws AnalysisException if the analysis could not be performed
|
| */
|
| LibraryElementImpl buildLibrary(Library library) {
|
| - CompilationUnitBuilder builder = new CompilationUnitBuilder(_analysisContext);
|
| + CompilationUnitBuilder builder = new CompilationUnitBuilder();
|
| Source librarySource2 = library.librarySource;
|
| CompilationUnit definingCompilationUnit3 = library.definingCompilationUnit;
|
| - CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCompilationUnit2(librarySource2, definingCompilationUnit3);
|
| + CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCompilationUnit(librarySource2, definingCompilationUnit3);
|
| NodeList<Directive> directives3 = definingCompilationUnit3.directives;
|
| LibraryIdentifier libraryNameNode = null;
|
| bool hasPartDirective = false;
|
| @@ -2095,10 +2655,10 @@ class LibraryElementBuilder {
|
| StringLiteral partUri = ((directive as PartDirective)).uri;
|
| Source partSource = library.getSource(partUri);
|
| if (partSource != null && partSource.exists()) {
|
| - CompilationUnitElementImpl part = builder.buildCompilationUnit(partSource);
|
| + CompilationUnitElementImpl part = builder.buildCompilationUnit(partSource, library.getAST(partSource));
|
| String partLibraryName = getPartLibraryName(library, partSource, directivesToResolve);
|
| if (partLibraryName == null) {
|
| - _errorListener.onError(new AnalysisError.con2(librarySource2, partUri.offset, partUri.length, ResolverErrorCode.MISSING_PART_OF_DIRECTIVE, []));
|
| + _errorListener.onError(new AnalysisError.con2(librarySource2, partUri.offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSource()]));
|
| } else if (libraryNameNode == null) {
|
| } else if (libraryNameNode.name != partLibraryName) {
|
| _errorListener.onError(new AnalysisError.con2(librarySource2, partUri.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryNameNode.name, partLibraryName]));
|
| @@ -2174,7 +2734,7 @@ class LibraryResolver {
|
| /**
|
| * The analysis context in which the libraries are being analyzed.
|
| */
|
| - AnalysisContextImpl _analysisContext;
|
| + InternalAnalysisContext _analysisContext;
|
| /**
|
| * The listener to which analysis errors will be reported, this error listener is either
|
| * references {@link #recordingErrorListener}, or it unions the passed{@link AnalysisErrorListener} with the {@link #recordingErrorListener}.
|
| @@ -2210,35 +2770,35 @@ class LibraryResolver {
|
| * Initialize a newly created library resolver to resolve libraries within the given context.
|
| * @param analysisContext the analysis context in which the library is being analyzed
|
| */
|
| - LibraryResolver.con1(AnalysisContextImpl analysisContext) {
|
| - _jtd_constructor_243_impl(analysisContext);
|
| + LibraryResolver.con1(InternalAnalysisContext analysisContext) {
|
| + _jtd_constructor_263_impl(analysisContext);
|
| }
|
| - _jtd_constructor_243_impl(AnalysisContextImpl analysisContext) {
|
| - _jtd_constructor_244_impl(analysisContext, null);
|
| + _jtd_constructor_263_impl(InternalAnalysisContext analysisContext) {
|
| + _jtd_constructor_264_impl(analysisContext, null);
|
| }
|
| /**
|
| * Initialize a newly created library resolver to resolve libraries within the given context.
|
| * @param analysisContext the analysis context in which the library is being analyzed
|
| * @param errorListener the listener to which analysis errors will be reported
|
| */
|
| - LibraryResolver.con2(AnalysisContextImpl analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
|
| - _jtd_constructor_244_impl(analysisContext2, additionalAnalysisErrorListener);
|
| + LibraryResolver.con2(InternalAnalysisContext analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
|
| + _jtd_constructor_264_impl(analysisContext2, additionalAnalysisErrorListener);
|
| }
|
| - _jtd_constructor_244_impl(AnalysisContextImpl analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
|
| + _jtd_constructor_264_impl(InternalAnalysisContext analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
|
| this._analysisContext = analysisContext2;
|
| this._recordingErrorListener = new RecordingErrorListener();
|
| if (additionalAnalysisErrorListener == null) {
|
| this._errorListener = _recordingErrorListener;
|
| } else {
|
| - this._errorListener = new AnalysisErrorListener_6(this, additionalAnalysisErrorListener);
|
| + this._errorListener = new AnalysisErrorListener_9(this, additionalAnalysisErrorListener);
|
| }
|
| - _coreLibrarySource = analysisContext2.sourceFactory.forUri(LibraryElementBuilder.CORE_LIBRARY_URI);
|
| + _coreLibrarySource = analysisContext2.sourceFactory.forUri(DartSdk.DART_CORE);
|
| }
|
| /**
|
| * Return the analysis context in which the libraries are being analyzed.
|
| * @return the analysis context in which the libraries are being analyzed
|
| */
|
| - AnalysisContextImpl get analysisContext => _analysisContext;
|
| + InternalAnalysisContext get analysisContext => _analysisContext;
|
| /**
|
| * Return the listener to which analysis errors will be reported.
|
| * @return the listener to which analysis errors will be reported
|
| @@ -2257,23 +2817,47 @@ class LibraryResolver {
|
| * @throws AnalysisException if the library could not be resolved for some reason
|
| */
|
| LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) {
|
| - Library targetLibrary = createLibrary(librarySource);
|
| - _coreLibrary = _libraryMap[_coreLibrarySource];
|
| - if (_coreLibrary == null) {
|
| - _coreLibrary = createLibrary(_coreLibrarySource);
|
| - }
|
| - computeLibraryDependencies(targetLibrary);
|
| - _librariesInCycles = computeLibrariesInCycles(targetLibrary);
|
| - buildElementModels();
|
| - buildDirectiveModels();
|
| - _typeProvider = new TypeProviderImpl(_coreLibrary.libraryElement);
|
| - buildTypeHierarchies();
|
| - resolveReferencesAndTypes();
|
| - if (fullAnalysis) {
|
| - runAdditionalAnalyses();
|
| + InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.LibraryResolver.resolveLibrary");
|
| + try {
|
| + instrumentation.metric("fullAnalysis", fullAnalysis);
|
| + instrumentation.data3("fullName", librarySource.fullName);
|
| + Library targetLibrary = createLibrary(librarySource);
|
| + _coreLibrary = _libraryMap[_coreLibrarySource];
|
| + if (_coreLibrary == null) {
|
| + _coreLibrary = createLibrary(_coreLibrarySource);
|
| + }
|
| + instrumentation.metric3("createLibrary", "complete");
|
| + computeLibraryDependencies(targetLibrary);
|
| + _librariesInCycles = computeLibrariesInCycles(targetLibrary);
|
| + buildElementModels();
|
| + instrumentation.metric3("buildElementModels", "complete");
|
| + LibraryElement coreElement = _coreLibrary.libraryElement;
|
| + if (coreElement == null) {
|
| + throw new AnalysisException.con1("Could not resolve dart:core");
|
| + }
|
| + buildDirectiveModels();
|
| + instrumentation.metric3("buildDirectiveModels", "complete");
|
| + _typeProvider = new TypeProviderImpl(coreElement);
|
| + buildTypeHierarchies();
|
| + instrumentation.metric3("buildTypeHierarchies", "complete");
|
| + resolveReferencesAndTypes();
|
| + instrumentation.metric3("resolveReferencesAndTypes", "complete");
|
| + performConstantEvaluation();
|
| + instrumentation.metric3("performConstantEvaluation", "complete");
|
| + if (fullAnalysis) {
|
| + runAdditionalAnalyses();
|
| + instrumentation.metric3("runAdditionalAnalyses", "complete");
|
| + }
|
| + recordResults();
|
| + instrumentation.metric3("recordResults", "complete");
|
| + instrumentation.metric2("librariesInCycles", _librariesInCycles.length);
|
| + for (Library lib in _librariesInCycles) {
|
| + instrumentation.metric2("librariesInCycles-CompilationUnitSources-Size", lib.compilationUnitSources.length);
|
| + }
|
| + return targetLibrary.libraryElement;
|
| + } finally {
|
| + instrumentation.log();
|
| }
|
| - recordResults();
|
| - return targetLibrary.libraryElement;
|
| }
|
| /**
|
| * Add a dependency to the given map from the referencing library to the referenced library.
|
| @@ -2428,7 +3012,7 @@ class LibraryResolver {
|
| void buildTypeHierarchies() {
|
| for (Library library in _librariesInCycles) {
|
| for (Source source in library.compilationUnitSources) {
|
| - TypeResolverVisitor visitor = new TypeResolverVisitor(library, source, _typeProvider);
|
| + TypeResolverVisitor visitor = new TypeResolverVisitor.con1(library, source, _typeProvider);
|
| library.getAST(source).accept(visitor);
|
| }
|
| }
|
| @@ -2487,6 +3071,10 @@ class LibraryResolver {
|
| }
|
| if (importedLibrary != null) {
|
| library.addImport(importDirective, importedLibrary);
|
| + if (doesCompilationUnitHavePartOfDirective(importedLibrary.getAST(importedSource))) {
|
| + StringLiteral uriLiteral = importDirective.uri;
|
| + _errorListener.onError(new AnalysisError.con2(library.librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, [uriLiteral.toSource()]));
|
| + }
|
| }
|
| }
|
| } else if (directive is ExportDirective) {
|
| @@ -2502,6 +3090,10 @@ class LibraryResolver {
|
| }
|
| if (exportedLibrary != null) {
|
| library.addExport(exportDirective, exportedLibrary);
|
| + if (doesCompilationUnitHavePartOfDirective(exportedLibrary.getAST(exportedSource))) {
|
| + StringLiteral uriLiteral = exportDirective.uri;
|
| + _errorListener.onError(new AnalysisError.con2(library.librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, [uriLiteral.toSource()]));
|
| + }
|
| }
|
| }
|
| }
|
| @@ -2551,6 +3143,20 @@ class LibraryResolver {
|
| return library;
|
| }
|
| /**
|
| + * Return {@code true} if and only if the passed {@link CompilationUnit} has a part-of directive.
|
| + * @param node the {@link CompilationUnit} to test
|
| + * @return {@code true} if and only if the passed {@link CompilationUnit} has a part-of directive
|
| + */
|
| + bool doesCompilationUnitHavePartOfDirective(CompilationUnit node) {
|
| + NodeList<Directive> directives4 = node.directives;
|
| + for (Directive directive in directives4) {
|
| + if (directive is PartOfDirective) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| + }
|
| + /**
|
| * Return an array containing the lexical identifiers associated with the nodes in the given list.
|
| * @param names the AST nodes representing the identifiers
|
| * @return the lexical identifiers associated with the nodes in the list
|
| @@ -2564,6 +3170,25 @@ class LibraryResolver {
|
| return identifiers;
|
| }
|
| /**
|
| + * Compute a value for all of the constants in the libraries being analyzed.
|
| + */
|
| + void performConstantEvaluation() {
|
| + ConstantValueComputer computer = new ConstantValueComputer();
|
| + for (Library library in _librariesInCycles) {
|
| + for (Source source in library.compilationUnitSources) {
|
| + try {
|
| + CompilationUnit unit = library.getAST(source);
|
| + if (unit != null) {
|
| + computer.add(unit);
|
| + }
|
| + } on AnalysisException catch (exception) {
|
| + AnalysisEngine.instance.logger.logError2("Internal Error: Could not access AST for ${source.fullName} during constant evaluation", exception);
|
| + }
|
| + }
|
| + }
|
| + computer.computeValues();
|
| + }
|
| + /**
|
| * Record the results of resolution with the analysis context. This includes recording
|
| * <ul>
|
| * <li>the resolved AST associated with each compilation unit,</li>
|
| @@ -2606,7 +3231,7 @@ class LibraryResolver {
|
| */
|
| void resolveReferencesAndTypes2(Library library) {
|
| for (Source source in library.compilationUnitSources) {
|
| - ResolverVisitor visitor = new ResolverVisitor(library, source, _typeProvider);
|
| + ResolverVisitor visitor = new ResolverVisitor.con1(library, source, _typeProvider);
|
| library.getAST(source).accept(visitor);
|
| }
|
| }
|
| @@ -2637,10 +3262,10 @@ class LibraryResolver {
|
| }
|
| }
|
| }
|
| -class AnalysisErrorListener_6 implements AnalysisErrorListener {
|
| +class AnalysisErrorListener_9 implements AnalysisErrorListener {
|
| final LibraryResolver LibraryResolver_this;
|
| AnalysisErrorListener additionalAnalysisErrorListener;
|
| - AnalysisErrorListener_6(this.LibraryResolver_this, this.additionalAnalysisErrorListener);
|
| + AnalysisErrorListener_9(this.LibraryResolver_this, this.additionalAnalysisErrorListener);
|
| void onError(AnalysisError error) {
|
| additionalAnalysisErrorListener.onError(error);
|
| LibraryResolver_this._recordingErrorListener.onError(error);
|
| @@ -2671,15 +3296,67 @@ class ResolverVisitor extends ScopedVisitor {
|
| */
|
| ExecutableElement _enclosingFunction = null;
|
| /**
|
| + * The object keeping track of which elements have had their types overridden.
|
| + */
|
| + TypeOverrideManager _overrideManager = new TypeOverrideManager();
|
| + /**
|
| * Initialize a newly created visitor to resolve the nodes in a compilation unit.
|
| * @param library the library containing the compilation unit being resolved
|
| * @param source the source representing the compilation unit being visited
|
| * @param typeProvider the object used to access the types from the core library
|
| */
|
| - ResolverVisitor(Library library, Source source, TypeProvider typeProvider) : super(library, source, typeProvider) {
|
| + ResolverVisitor.con1(Library library, Source source, TypeProvider typeProvider) : super.con1(library, source, typeProvider) {
|
| + _jtd_constructor_265_impl(library, source, typeProvider);
|
| + }
|
| + _jtd_constructor_265_impl(Library library, Source source, TypeProvider typeProvider) {
|
| + this._elementResolver = new ElementResolver(this);
|
| + this._typeAnalyzer = new StaticTypeAnalyzer(this);
|
| + }
|
| + /**
|
| + * Initialize a newly created visitor to resolve the nodes in a compilation unit.
|
| + * @param definingLibrary the element for the library containing the compilation unit being
|
| + * visited
|
| + * @param source the source representing the compilation unit being visited
|
| + * @param typeProvider the object used to access the types from the core library
|
| + * @param errorListener the error listener that will be informed of any errors that are found
|
| + * during resolution
|
| + */
|
| + ResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) : super.con2(definingLibrary, source, typeProvider, errorListener) {
|
| + _jtd_constructor_266_impl(definingLibrary, source, typeProvider, errorListener);
|
| + }
|
| + _jtd_constructor_266_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
|
| this._elementResolver = new ElementResolver(this);
|
| this._typeAnalyzer = new StaticTypeAnalyzer(this);
|
| }
|
| + /**
|
| + * Return the object keeping track of which elements have had their types overridden.
|
| + * @return the object keeping track of which elements have had their types overridden
|
| + */
|
| + TypeOverrideManager get overrideManager => _overrideManager;
|
| + Object visitAsExpression(AsExpression node) {
|
| + super.visitAsExpression(node);
|
| + if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
|
| + VariableElement element = getOverridableElement(node.expression);
|
| + if (element != null) {
|
| + Type2 type16 = node.type.type;
|
| + if (type16 != null) {
|
| + _overrideManager.setType(element, type16);
|
| + }
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + Object visitAssertStatement(AssertStatement node) {
|
| + Expression condition3 = node.condition;
|
| + condition3.accept(this);
|
| + propagateTrueState(condition3);
|
| + return null;
|
| + }
|
| + Object visitBreakStatement(BreakStatement node) {
|
| + node.accept(_elementResolver);
|
| + node.accept(_typeAnalyzer);
|
| + return null;
|
| + }
|
| Object visitClassDeclaration(ClassDeclaration node) {
|
| ClassElement outerType = _enclosingClass;
|
| try {
|
| @@ -2692,6 +3369,120 @@ class ResolverVisitor extends ScopedVisitor {
|
| }
|
| return null;
|
| }
|
| + Object visitComment(Comment node) => null;
|
| + Object visitCompilationUnit(CompilationUnit node) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + for (Directive directive in node.directives) {
|
| + directive.accept(this);
|
| + }
|
| + List<CompilationUnitMember> classes = new List<CompilationUnitMember>();
|
| + for (CompilationUnitMember declaration in node.declarations) {
|
| + if (declaration is ClassDeclaration) {
|
| + classes.add(declaration);
|
| + } else {
|
| + declaration.accept(this);
|
| + }
|
| + }
|
| + for (CompilationUnitMember declaration in classes) {
|
| + declaration.accept(this);
|
| + }
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + return null;
|
| + }
|
| + Object visitConditionalExpression(ConditionalExpression node) {
|
| + Expression condition4 = node.condition;
|
| + condition4.accept(this);
|
| + Expression thenExpression2 = node.thenExpression;
|
| + if (thenExpression2 != null) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + propagateTrueState(condition4);
|
| + thenExpression2.accept(this);
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + }
|
| + Expression elseExpression2 = node.elseExpression;
|
| + if (elseExpression2 != null) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + propagateFalseState(condition4);
|
| + elseExpression2.accept(this);
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + }
|
| + if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
|
| + bool thenIsAbrupt = thenExpression2 != null && isAbruptTermination(thenExpression2);
|
| + bool elseIsAbrupt = elseExpression2 != null && isAbruptTermination(elseExpression2);
|
| + if (elseIsAbrupt && !thenIsAbrupt) {
|
| + propagateTrueState(condition4);
|
| + } else if (thenIsAbrupt && !elseIsAbrupt) {
|
| + propagateFalseState(condition4);
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + Object visitConstructorDeclaration(ConstructorDeclaration node) {
|
| + ExecutableElement outerFunction = _enclosingFunction;
|
| + try {
|
| + _enclosingFunction = node.element;
|
| + super.visitConstructorDeclaration(node);
|
| + } finally {
|
| + _enclosingFunction = outerFunction;
|
| + }
|
| + return null;
|
| + }
|
| + Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
|
| + safelyVisit(node.expression);
|
| + node.accept(_elementResolver);
|
| + node.accept(_typeAnalyzer);
|
| + return null;
|
| + }
|
| + Object visitConstructorName(ConstructorName node) {
|
| + node.accept(_elementResolver);
|
| + node.accept(_typeAnalyzer);
|
| + return null;
|
| + }
|
| + Object visitContinueStatement(ContinueStatement node) {
|
| + node.accept(_elementResolver);
|
| + node.accept(_typeAnalyzer);
|
| + return null;
|
| + }
|
| + Object visitFieldDeclaration(FieldDeclaration node) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + super.visitFieldDeclaration(node);
|
| + } finally {
|
| + Map<Element, Type2> overrides = captureOverrides(node.fields);
|
| + _overrideManager.exitScope();
|
| + for (MapEntry<Element, Type2> entry in getMapEntrySet(overrides)) {
|
| + _overrideManager.setType(entry.getKey(), entry.getValue());
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + Object visitForStatement(ForStatement node) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + super.visitForStatement(node);
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + return null;
|
| + }
|
| + Object visitFunctionBody(FunctionBody node) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + super.visitFunctionBody(node);
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + return null;
|
| + }
|
| Object visitFunctionDeclaration(FunctionDeclaration node) {
|
| ExecutableElement outerFunction = _enclosingFunction;
|
| try {
|
| @@ -2707,12 +3498,49 @@ class ResolverVisitor extends ScopedVisitor {
|
| ExecutableElement outerFunction = _enclosingFunction;
|
| try {
|
| _enclosingFunction = node.element;
|
| + _overrideManager.enterScope();
|
| super.visitFunctionExpression(node);
|
| } finally {
|
| + _overrideManager.exitScope();
|
| _enclosingFunction = outerFunction;
|
| }
|
| return null;
|
| }
|
| + Object visitHideCombinator(HideCombinator node) => null;
|
| + Object visitIfStatement(IfStatement node) {
|
| + Expression condition5 = node.condition;
|
| + condition5.accept(this);
|
| + Statement thenStatement2 = node.thenStatement;
|
| + if (thenStatement2 != null) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + propagateTrueState(condition5);
|
| + thenStatement2.accept(this);
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + }
|
| + Statement elseStatement2 = node.elseStatement;
|
| + if (elseStatement2 != null) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + propagateFalseState(condition5);
|
| + elseStatement2.accept(this);
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + }
|
| + if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
|
| + bool thenIsAbrupt = thenStatement2 != null && isAbruptTermination2(thenStatement2);
|
| + bool elseIsAbrupt = elseStatement2 != null && isAbruptTermination2(elseStatement2);
|
| + if (elseIsAbrupt && !thenIsAbrupt) {
|
| + propagateTrueState(condition5);
|
| + } else if (thenIsAbrupt && !elseIsAbrupt) {
|
| + propagateFalseState(condition5);
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| Object visitLabel(Label node) => null;
|
| Object visitLibraryIdentifier(LibraryIdentifier node) => null;
|
| Object visitMethodDeclaration(MethodDeclaration node) {
|
| @@ -2725,6 +3553,13 @@ class ResolverVisitor extends ScopedVisitor {
|
| }
|
| return null;
|
| }
|
| + Object visitMethodInvocation(MethodInvocation node) {
|
| + safelyVisit(node.target);
|
| + safelyVisit(node.argumentList);
|
| + node.accept(_elementResolver);
|
| + node.accept(_typeAnalyzer);
|
| + return null;
|
| + }
|
| Object visitNode(ASTNode node) {
|
| node.visitChildren(this);
|
| node.accept(_elementResolver);
|
| @@ -2732,41 +3567,61 @@ class ResolverVisitor extends ScopedVisitor {
|
| return null;
|
| }
|
| Object visitPrefixedIdentifier(PrefixedIdentifier node) {
|
| - SimpleIdentifier prefix7 = node.prefix;
|
| - if (prefix7 != null) {
|
| - prefix7.accept(this);
|
| - }
|
| + safelyVisit(node.prefix);
|
| node.accept(_elementResolver);
|
| node.accept(_typeAnalyzer);
|
| return null;
|
| }
|
| Object visitPropertyAccess(PropertyAccess node) {
|
| - Expression target4 = node.target;
|
| - if (target4 != null) {
|
| - target4.accept(this);
|
| - }
|
| + safelyVisit(node.target);
|
| node.accept(_elementResolver);
|
| node.accept(_typeAnalyzer);
|
| return null;
|
| }
|
| Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
|
| - ArgumentList argumentList10 = node.argumentList;
|
| - if (argumentList10 != null) {
|
| - argumentList10.accept(this);
|
| - }
|
| + safelyVisit(node.argumentList);
|
| node.accept(_elementResolver);
|
| node.accept(_typeAnalyzer);
|
| return null;
|
| }
|
| + Object visitShowCombinator(ShowCombinator node) => null;
|
| Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
|
| - ArgumentList argumentList11 = node.argumentList;
|
| - if (argumentList11 != null) {
|
| - argumentList11.accept(this);
|
| - }
|
| + safelyVisit(node.argumentList);
|
| node.accept(_elementResolver);
|
| node.accept(_typeAnalyzer);
|
| return null;
|
| }
|
| + Object visitSwitchCase(SwitchCase node) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + super.visitSwitchCase(node);
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + return null;
|
| + }
|
| + Object visitSwitchDefault(SwitchDefault node) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + super.visitSwitchDefault(node);
|
| + } finally {
|
| + _overrideManager.exitScope();
|
| + }
|
| + return null;
|
| + }
|
| + Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
|
| + try {
|
| + _overrideManager.enterScope();
|
| + super.visitTopLevelVariableDeclaration(node);
|
| + } finally {
|
| + Map<Element, Type2> overrides = captureOverrides(node.variables);
|
| + _overrideManager.exitScope();
|
| + for (MapEntry<Element, Type2> entry in getMapEntrySet(overrides)) {
|
| + _overrideManager.setType(entry.getKey(), entry.getValue());
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| Object visitTypeName(TypeName node) => null;
|
| /**
|
| * Return the class element representing the class containing the current node, or {@code null} if
|
| @@ -2780,6 +3635,141 @@ class ResolverVisitor extends ScopedVisitor {
|
| * @return the element representing the function containing the current node
|
| */
|
| ExecutableElement get enclosingFunction => _enclosingFunction;
|
| + /**
|
| + * Return the element associated with the given expression whose type can be overridden, or{@code null} if there is no element whose type can be overridden.
|
| + * @param expression the expression with which the element is associated
|
| + * @return the element associated with the given expression
|
| + */
|
| + VariableElement getOverridableElement(Expression expression) {
|
| + if (expression is SimpleIdentifier) {
|
| + Element element30 = ((expression as SimpleIdentifier)).element;
|
| + if (element30 is VariableElement) {
|
| + return element30 as VariableElement;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + /**
|
| + * Return a map from the elements for the variables in the given list that have their types
|
| + * overridden to the overriding type.
|
| + * @param variableList the list of variables whose overriding types are to be captured
|
| + * @return a table mapping elements to their overriding types
|
| + */
|
| + Map<Element, Type2> captureOverrides(VariableDeclarationList variableList) {
|
| + Map<Element, Type2> overrides = new Map<Element, Type2>();
|
| + if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
|
| + if (variableList.isConst() || variableList.isFinal()) {
|
| + for (VariableDeclaration variable in variableList.variables) {
|
| + Element element31 = variable.element;
|
| + if (element31 != null) {
|
| + Type2 type = _overrideManager.getType(element31);
|
| + if (type != null) {
|
| + overrides[element31] = type;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return overrides;
|
| + }
|
| + /**
|
| + * Return {@code true} if the given expression terminates abruptly (that is, if any expression
|
| + * following the given expression will not be reached).
|
| + * @param expression the expression being tested
|
| + * @return {@code true} if the given expression terminates abruptly
|
| + */
|
| + bool isAbruptTermination(Expression expression18) {
|
| + while (expression18 is ParenthesizedExpression) {
|
| + expression18 = ((expression18 as ParenthesizedExpression)).expression;
|
| + }
|
| + return expression18 is ThrowExpression || expression18 is RethrowExpression;
|
| + }
|
| + /**
|
| + * Return {@code true} if the given statement terminates abruptly (that is, if any statement
|
| + * following the given statement will not be reached).
|
| + * @param statement the statement being tested
|
| + * @return {@code true} if the given statement terminates abruptly
|
| + */
|
| + bool isAbruptTermination2(Statement statement) {
|
| + if (statement is ReturnStatement) {
|
| + return true;
|
| + } else if (statement is ExpressionStatement) {
|
| + return isAbruptTermination(((statement as ExpressionStatement)).expression);
|
| + } else if (statement is Block) {
|
| + NodeList<Statement> statements2 = ((statement as Block)).statements;
|
| + int size6 = statements2.length;
|
| + if (size6 == 0) {
|
| + return false;
|
| + }
|
| + return isAbruptTermination2(statements2[size6 - 1]);
|
| + }
|
| + return false;
|
| + }
|
| + /**
|
| + * Propagate any type information that results from knowing that the given condition will have
|
| + * evaluated to 'false'.
|
| + * @param condition the condition that will have evaluated to 'false'
|
| + */
|
| + void propagateFalseState(Expression condition) {
|
| + while (condition is ParenthesizedExpression) {
|
| + condition = ((condition as ParenthesizedExpression)).expression;
|
| + }
|
| + if (condition is IsExpression) {
|
| + IsExpression is2 = condition as IsExpression;
|
| + if (is2.notOperator != null) {
|
| + Element element = getOverridableElement(is2.expression);
|
| + if (element != null) {
|
| + Type2 type17 = is2.type.type;
|
| + if (type17 != null) {
|
| + _overrideManager.setType(element, type17);
|
| + }
|
| + }
|
| + }
|
| + } else if (condition is BinaryExpression) {
|
| + BinaryExpression binary = condition as BinaryExpression;
|
| + if (identical(binary.operator.type, sc.TokenType.BAR_BAR)) {
|
| + propagateFalseState(binary.leftOperand);
|
| + propagateFalseState(binary.rightOperand);
|
| + }
|
| + }
|
| + }
|
| + /**
|
| + * Propagate any type information that results from knowing that the given condition will have
|
| + * evaluated to 'true'.
|
| + * @param condition the condition that will have evaluated to 'true'
|
| + */
|
| + void propagateTrueState(Expression condition) {
|
| + while (condition is ParenthesizedExpression) {
|
| + condition = ((condition as ParenthesizedExpression)).expression;
|
| + }
|
| + if (condition is IsExpression) {
|
| + IsExpression is3 = condition as IsExpression;
|
| + if (is3.notOperator == null) {
|
| + Element element = getOverridableElement(is3.expression);
|
| + if (element != null) {
|
| + Type2 type18 = is3.type.type;
|
| + if (type18 != null) {
|
| + _overrideManager.setType(element, type18);
|
| + }
|
| + }
|
| + }
|
| + } else if (condition is BinaryExpression) {
|
| + BinaryExpression binary = condition as BinaryExpression;
|
| + if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) {
|
| + propagateTrueState(binary.leftOperand);
|
| + propagateTrueState(binary.rightOperand);
|
| + }
|
| + }
|
| + }
|
| + /**
|
| + * Visit the given AST node if it is not null.
|
| + * @param node the node to be visited
|
| + */
|
| + void safelyVisit(ASTNode node) {
|
| + if (node != null) {
|
| + node.accept(this);
|
| + }
|
| + }
|
| get elementResolver_J2DAccessor => _elementResolver;
|
| set elementResolver_J2DAccessor(__v) => _elementResolver = __v;
|
| get labelScope_J2DAccessor => _labelScope;
|
| @@ -2827,13 +3817,35 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
|
| * @param source the source representing the compilation unit being visited
|
| * @param typeProvider the object used to access the types from the core library
|
| */
|
| - ScopedVisitor(Library library, Source source, TypeProvider typeProvider) {
|
| + ScopedVisitor.con1(Library library, Source source8, TypeProvider typeProvider2) {
|
| + _jtd_constructor_267_impl(library, source8, typeProvider2);
|
| + }
|
| + _jtd_constructor_267_impl(Library library, Source source8, TypeProvider typeProvider2) {
|
| this._definingLibrary = library.libraryElement;
|
| - this._source = source;
|
| + this._source = source8;
|
| LibraryScope libraryScope2 = library.libraryScope;
|
| this._errorListener = libraryScope2.errorListener;
|
| this._nameScope = libraryScope2;
|
| - this._typeProvider = typeProvider;
|
| + this._typeProvider = typeProvider2;
|
| + }
|
| + /**
|
| + * Initialize a newly created visitor to resolve the nodes in a compilation unit.
|
| + * @param definingLibrary the element for the library containing the compilation unit being
|
| + * visited
|
| + * @param source the source representing the compilation unit being visited
|
| + * @param typeProvider the object used to access the types from the core library
|
| + * @param errorListener the error listener that will be informed of any errors that are found
|
| + * during resolution
|
| + */
|
| + ScopedVisitor.con2(LibraryElement definingLibrary2, Source source9, TypeProvider typeProvider3, AnalysisErrorListener errorListener2) {
|
| + _jtd_constructor_268_impl(definingLibrary2, source9, typeProvider3, errorListener2);
|
| + }
|
| + _jtd_constructor_268_impl(LibraryElement definingLibrary2, Source source9, TypeProvider typeProvider3, AnalysisErrorListener errorListener2) {
|
| + this._definingLibrary = definingLibrary2;
|
| + this._source = source9;
|
| + this._errorListener = errorListener2;
|
| + this._nameScope = new LibraryScope(definingLibrary2, errorListener2);
|
| + this._typeProvider = typeProvider3;
|
| }
|
| /**
|
| * Return the library element for the library containing the compilation unit being resolved.
|
| @@ -2855,6 +3867,24 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
|
| }
|
| return null;
|
| }
|
| + Object visitCatchClause(CatchClause node) {
|
| + SimpleIdentifier exception = node.exceptionParameter;
|
| + if (exception != null) {
|
| + Scope outerScope = _nameScope;
|
| + _nameScope = new EnclosedScope(_nameScope);
|
| + try {
|
| + _nameScope.define(exception.element);
|
| + SimpleIdentifier stackTrace = node.stackTraceParameter;
|
| + if (stackTrace != null) {
|
| + _nameScope.define(stackTrace.element);
|
| + }
|
| + super.visitCatchClause(node);
|
| + } finally {
|
| + _nameScope = outerScope;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| Object visitClassDeclaration(ClassDeclaration node) {
|
| Scope outerScope = _nameScope;
|
| try {
|
| @@ -2885,6 +3915,14 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
|
| }
|
| return null;
|
| }
|
| + Object visitDeclaredIdentifier(DeclaredIdentifier node) {
|
| + VariableElement element32 = node.element;
|
| + if (element32 != null) {
|
| + _nameScope.define(element32);
|
| + }
|
| + super.visitDeclaredIdentifier(node);
|
| + return null;
|
| + }
|
| Object visitDoStatement(DoStatement node) {
|
| LabelScope outerScope = _labelScope;
|
| _labelScope = new LabelScope.con1(outerScope, false, false);
|
| @@ -3022,9 +4060,9 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
|
| }
|
| Object visitVariableDeclaration(VariableDeclaration node) {
|
| if (node.parent.parent is! TopLevelVariableDeclaration && node.parent.parent is! FieldDeclaration) {
|
| - VariableElement element28 = node.element;
|
| - if (element28 != null) {
|
| - _nameScope.define(element28);
|
| + VariableElement element33 = node.element;
|
| + if (element33 != null) {
|
| + _nameScope.define(element33);
|
| }
|
| }
|
| super.visitVariableDeclaration(node);
|
| @@ -3096,6 +4134,77 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
|
| */
|
| class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| /**
|
| + * Create a table mapping HTML tag names to the names of the classes (in 'dart:html') that
|
| + * implement those tags.
|
| + * @return the table that was created
|
| + */
|
| + static Map<String, String> createHtmlTagToClassMap() {
|
| + Map<String, String> map = new Map<String, String>();
|
| + map["a"] = "AnchorElement";
|
| + map["area"] = "AreaElement";
|
| + map["br"] = "BRElement";
|
| + map["base"] = "BaseElement";
|
| + map["body"] = "BodyElement";
|
| + map["button"] = "ButtonElement";
|
| + map["canvas"] = "CanvasElement";
|
| + map["content"] = "ContentElement";
|
| + map["dl"] = "DListElement";
|
| + map["datalist"] = "DataListElement";
|
| + map["details"] = "DetailsElement";
|
| + map["div"] = "DivElement";
|
| + map["embed"] = "EmbedElement";
|
| + map["fieldset"] = "FieldSetElement";
|
| + map["form"] = "FormElement";
|
| + map["hr"] = "HRElement";
|
| + map["head"] = "HeadElement";
|
| + map["h1"] = "HeadingElement";
|
| + map["h2"] = "HeadingElement";
|
| + map["h3"] = "HeadingElement";
|
| + map["h4"] = "HeadingElement";
|
| + map["h5"] = "HeadingElement";
|
| + map["h6"] = "HeadingElement";
|
| + map["html"] = "HtmlElement";
|
| + map["iframe"] = "IFrameElement";
|
| + map["img"] = "ImageElement";
|
| + map["input"] = "InputElement";
|
| + map["keygen"] = "KeygenElement";
|
| + map["li"] = "LIElement";
|
| + map["label"] = "LabelElement";
|
| + map["legend"] = "LegendElement";
|
| + map["link"] = "LinkElement";
|
| + map["map"] = "MapElement";
|
| + map["menu"] = "MenuElement";
|
| + map["meter"] = "MeterElement";
|
| + map["ol"] = "OListElement";
|
| + map["object"] = "ObjectElement";
|
| + map["optgroup"] = "OptGroupElement";
|
| + map["output"] = "OutputElement";
|
| + map["p"] = "ParagraphElement";
|
| + map["param"] = "ParamElement";
|
| + map["pre"] = "PreElement";
|
| + map["progress"] = "ProgressElement";
|
| + map["script"] = "ScriptElement";
|
| + map["select"] = "SelectElement";
|
| + map["source"] = "SourceElement";
|
| + map["span"] = "SpanElement";
|
| + map["style"] = "StyleElement";
|
| + map["caption"] = "TableCaptionElement";
|
| + map["td"] = "TableCellElement";
|
| + map["col"] = "TableColElement";
|
| + map["table"] = "TableElement";
|
| + map["tr"] = "TableRowElement";
|
| + map["textarea"] = "TextAreaElement";
|
| + map["title"] = "TitleElement";
|
| + map["track"] = "TrackElement";
|
| + map["ul"] = "UListElement";
|
| + map["video"] = "VideoElement";
|
| + return map;
|
| + }
|
| + /**
|
| + * The resolver driving the resolution and type analysis.
|
| + */
|
| + ResolverVisitor _resolver;
|
| + /**
|
| * The object providing access to the types defined by the language.
|
| */
|
| TypeProvider _typeProvider;
|
| @@ -3109,12 +4218,27 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| */
|
| InterfaceType _thisType;
|
| /**
|
| + * The object keeping track of which elements have had their types overridden.
|
| + */
|
| + TypeOverrideManager _overrideManager;
|
| + /**
|
| + * A flag indicating whether type propagation should be enabled.
|
| + */
|
| + static bool USE_TYPE_PROPAGATION = true;
|
| + /**
|
| + * A table mapping HTML tag names to the names of the classes (in 'dart:html') that implement
|
| + * those tags.
|
| + */
|
| + static Map<String, String> _HTML_ELEMENT_TO_CLASS_MAP = createHtmlTagToClassMap();
|
| + /**
|
| * Initialize a newly created type analyzer.
|
| * @param resolver the resolver driving this participant
|
| */
|
| StaticTypeAnalyzer(ResolverVisitor resolver) {
|
| + this._resolver = resolver;
|
| _typeProvider = resolver.typeProvider;
|
| _dynamicType = _typeProvider.dynamicType;
|
| + _overrideManager = resolver.overrideManager;
|
| }
|
| /**
|
| * Set the type of the class being analyzed to the given type.
|
| @@ -3140,7 +4264,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * <p>
|
| * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
|
| */
|
| - Object visitAsExpression(AsExpression node) => recordType(node, getType3(node.type));
|
| + Object visitAsExpression(AsExpression node) => recordType(node, getType4(node.type));
|
| /**
|
| * The Dart Language Specification, 12.18: <blockquote> ... an assignment <i>a</i> of the form
|
| * <i>v = e</i> ...
|
| @@ -3183,9 +4307,16 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| Object visitAssignmentExpression(AssignmentExpression node) {
|
| sc.TokenType operator11 = node.operator.type;
|
| if (operator11 != sc.TokenType.EQ) {
|
| - return recordReturnType(node, node.element, null);
|
| + return recordReturnType(node, node.element);
|
| + }
|
| + Type2 rightType = getType2(node.rightHandSide);
|
| + if (USE_TYPE_PROPAGATION) {
|
| + VariableElement element = _resolver.getOverridableElement(node.leftHandSide);
|
| + if (element != null) {
|
| + override(element, getType(element), rightType);
|
| + }
|
| }
|
| - return recordType(node, getType(node.rightHandSide));
|
| + return recordType(node, rightType);
|
| }
|
| /**
|
| * The Dart Language Specification, 12.20: <blockquote>The static type of a logical boolean
|
| @@ -3229,10 +4360,20 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| while (true) {
|
| if (operator12 == sc.TokenType.AMPERSAND_AMPERSAND || operator12 == sc.TokenType.BAR_BAR || operator12 == sc.TokenType.EQ_EQ || operator12 == sc.TokenType.BANG_EQ) {
|
| return recordType(node, _typeProvider.boolType);
|
| + } else if (operator12 == sc.TokenType.MINUS || operator12 == sc.TokenType.PERCENT || operator12 == sc.TokenType.PLUS || operator12 == sc.TokenType.STAR || operator12 == sc.TokenType.TILDE_SLASH) {
|
| + Type2 intType2 = _typeProvider.intType;
|
| + if (identical(getType2(node.leftOperand), intType2) && identical(getType2(node.rightOperand), intType2)) {
|
| + return recordType(node, intType2);
|
| + }
|
| + } else if (operator12 == sc.TokenType.SLASH) {
|
| + Type2 doubleType2 = _typeProvider.doubleType;
|
| + if (identical(getType2(node.leftOperand), doubleType2) || identical(getType2(node.rightOperand), doubleType2)) {
|
| + return recordType(node, doubleType2);
|
| + }
|
| }
|
| break;
|
| }
|
| - return recordReturnType(node, node.element, null);
|
| + return recordReturnType(node, node.element);
|
| }
|
| /**
|
| * The Dart Language Specification, 12.4: <blockquote>The static type of a boolean literal is{@code bool}.</blockquote>
|
| @@ -3243,7 +4384,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suffix; return
|
| * t;}(e)</i>.</blockquote>
|
| */
|
| - Object visitCascadeExpression(CascadeExpression node) => recordType(node, getType(node.target));
|
| + Object visitCascadeExpression(CascadeExpression node) => recordType(node, getType2(node.target));
|
| /**
|
| * The Dart Language Specification, 12.19: <blockquote> ... a conditional expression <i>c</i> of
|
| * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ...
|
| @@ -3254,8 +4395,8 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * and the static type of <i>e<sub>3</sub></i>.</blockquote>
|
| */
|
| Object visitConditionalExpression(ConditionalExpression node) {
|
| - Type2 thenType = getType(node.thenExpression);
|
| - Type2 elseType = getType(node.elseExpression);
|
| + Type2 thenType = getType2(node.thenExpression);
|
| + Type2 elseType = getType2(node.elseExpression);
|
| if (thenType == null) {
|
| return recordType(node, _dynamicType);
|
| }
|
| @@ -3322,22 +4463,17 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the
|
| * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquote>
|
| */
|
| - Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => recordReturnType(node, node.element, null);
|
| + Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => recordReturnType(node, node.element);
|
| /**
|
| * The Dart Language Specification, 12.29: <blockquote>An assignable expression of the form
|
| * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of the operator method
|
| * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</blockquote>
|
| */
|
| Object visitIndexExpression(IndexExpression node) {
|
| - Type2 type = getType(node.realTarget);
|
| - List<Type2> typeArgs = null;
|
| - if (type is InterfaceType) {
|
| - typeArgs = ((type as InterfaceType)).typeArguments;
|
| - }
|
| if (node.inSetterContext()) {
|
| - return recordArgumentType(node, node.element, typeArgs);
|
| + return recordArgumentType(node, node.element);
|
| }
|
| - return recordReturnType(node, node.element, typeArgs);
|
| + return recordReturnType(node, node.element);
|
| }
|
| /**
|
| * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
|
| @@ -3348,7 +4484,21 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * expression of either the form <i>const T.id(a<sub>1</sub>, …, a<sub>n</sub>)</i> or the
|
| * form <i>const T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>. </blockquote>
|
| */
|
| - Object visitInstanceCreationExpression(InstanceCreationExpression node) => recordType(node, node.constructorName.type.type);
|
| + Object visitInstanceCreationExpression(InstanceCreationExpression node) {
|
| + if (USE_TYPE_PROPAGATION) {
|
| + ConstructorElement element34 = node.element;
|
| + if (element34 != null && "Element" == element34.enclosingElement.name && "tag" == element34.name) {
|
| + LibraryElement library33 = element34.library;
|
| + if (isHtmlLibrary(library33)) {
|
| + Type2 returnType = getFirstArgumentAsType2(library33, node.argumentList, _HTML_ELEMENT_TO_CLASS_MAP);
|
| + if (returnType != null) {
|
| + return recordType(node, returnType);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return recordType(node, node.constructorName.type.type);
|
| + }
|
| /**
|
| * The Dart Language Specification, 12.3: <blockquote>The static type of an integer literal is{@code int}.</blockquote>
|
| */
|
| @@ -3373,7 +4523,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| NodeList<TypeName> arguments4 = typeArguments8.arguments;
|
| if (arguments4 != null && arguments4.length == 1) {
|
| TypeName argumentType = arguments4[0];
|
| - return recordType(node, _typeProvider.listType.substitute5(<Type2> [getType3(argumentType)]));
|
| + return recordType(node, _typeProvider.listType.substitute5(<Type2> [getType4(argumentType)]));
|
| }
|
| }
|
| return recordType(node, _typeProvider.listType.substitute5(<Type2> [_dynamicType]));
|
| @@ -3399,7 +4549,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| if (keyType != _typeProvider.stringType) {
|
| }
|
| TypeName valueType = arguments5[1];
|
| - return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, getType3(valueType)]));
|
| + return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, getType4(valueType)]));
|
| }
|
| }
|
| return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, _dynamicType]));
|
| @@ -3440,14 +4590,39 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
|
| * <i>F</i>.</blockquote>
|
| */
|
| - Object visitMethodInvocation(MethodInvocation node) => recordReturnType(node, node.methodName.element, null);
|
| - Object visitNamedExpression(NamedExpression node) => recordType(node, getType(node.expression));
|
| + Object visitMethodInvocation(MethodInvocation node) {
|
| + if (USE_TYPE_PROPAGATION) {
|
| + String methodName3 = node.methodName.name;
|
| + if (methodName3 == "\$dom_createEvent") {
|
| + Expression target = node.realTarget;
|
| + if (target != null) {
|
| + Type2 targetType = getType2(target);
|
| + if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
|
| + LibraryElement library34 = targetType.element.library;
|
| + if (isHtmlLibrary(library34)) {
|
| + Type2 returnType = getFirstArgumentAsType(library34, node.argumentList);
|
| + if (returnType != null) {
|
| + return recordType(node, returnType);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + } else if (methodName3 == "JS") {
|
| + Type2 returnType = getFirstArgumentAsType(_typeProvider.objectType.element.library, node.argumentList);
|
| + if (returnType != null) {
|
| + return recordType(node, returnType);
|
| + }
|
| + }
|
| + }
|
| + return recordReturnType(node, node.methodName.element);
|
| + }
|
| + Object visitNamedExpression(NamedExpression node) => recordType(node, getType2(node.expression));
|
| /**
|
| * The Dart Language Specification, 12.2: <blockquote>The static type of {@code null} is bottom.
|
| * </blockquote>
|
| */
|
| Object visitNullLiteral(NullLiteral node) => recordType(node, _typeProvider.bottomType);
|
| - Object visitParenthesizedExpression(ParenthesizedExpression node) => recordType(node, getType(node.expression));
|
| + Object visitParenthesizedExpression(ParenthesizedExpression node) => recordType(node, getType2(node.expression));
|
| /**
|
| * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form
|
| * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1;
|
| @@ -3474,29 +4649,46 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
|
| * = r - 1; return r}(e1, e2)</i></blockquote>
|
| */
|
| - Object visitPostfixExpression(PostfixExpression node) => recordType(node, getType(node.operand));
|
| + Object visitPostfixExpression(PostfixExpression node) => recordType(node, getType2(node.operand));
|
| /**
|
| * See {@link #visitSimpleIdentifier(SimpleIdentifier)}.
|
| */
|
| Object visitPrefixedIdentifier(PrefixedIdentifier node) {
|
| SimpleIdentifier prefixedIdentifier = node.identifier;
|
| - Element element29 = prefixedIdentifier.element;
|
| - if (element29 is VariableElement) {
|
| - Type2 variableType = ((element29 as VariableElement)).type;
|
| - recordType(prefixedIdentifier, variableType);
|
| - return recordType(node, variableType);
|
| - } else if (element29 is PropertyAccessorElement) {
|
| - Type2 propertyType = getType2((element29 as PropertyAccessorElement));
|
| - recordType(prefixedIdentifier, propertyType);
|
| - return recordType(node, propertyType);
|
| - } else if (element29 is MethodElement) {
|
| - Type2 returnType = ((element29 as MethodElement)).type;
|
| - recordType(prefixedIdentifier, returnType);
|
| - return recordType(node, returnType);
|
| + Element element35 = prefixedIdentifier.element;
|
| + if (element35 == null) {
|
| + return recordType(node, _dynamicType);
|
| + }
|
| + if (USE_TYPE_PROPAGATION) {
|
| + Type2 type = _overrideManager.getType(element35);
|
| + if (type != null) {
|
| + return recordType(node, type);
|
| + }
|
| + }
|
| + Type2 type;
|
| + if (element35 is ClassElement) {
|
| + if (isNotTypeLiteral(node)) {
|
| + type = ((element35 as ClassElement)).type;
|
| + } else {
|
| + type = _typeProvider.typeType;
|
| + }
|
| + } else if (element35 is FunctionTypeAliasElement) {
|
| + type = ((element35 as FunctionTypeAliasElement)).type;
|
| + } else if (element35 is MethodElement) {
|
| + type = ((element35 as MethodElement)).type;
|
| + } else if (element35 is PropertyAccessorElement) {
|
| + type = getType3((element35 as PropertyAccessorElement), node.prefix.staticType);
|
| + } else if (element35 is ExecutableElement) {
|
| + type = ((element35 as ExecutableElement)).type;
|
| + } else if (element35 is TypeVariableElement) {
|
| + type = ((element35 as TypeVariableElement)).type;
|
| + } else if (element35 is VariableElement) {
|
| + type = ((element35 as VariableElement)).type;
|
| } else {
|
| + type = _dynamicType;
|
| }
|
| - recordType(prefixedIdentifier, _dynamicType);
|
| - return recordType(node, _dynamicType);
|
| + recordType(prefixedIdentifier, type);
|
| + return recordType(node, type);
|
| }
|
| /**
|
| * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u</i> of the form
|
| @@ -3508,7 +4700,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| if (identical(operator13, sc.TokenType.BANG)) {
|
| return recordType(node, _typeProvider.boolType);
|
| }
|
| - return recordReturnType(node, node.element, null);
|
| + return recordReturnType(node, node.element);
|
| }
|
| /**
|
| * The Dart Language Specification, 12.13: <blockquote> Property extraction allows for a member of
|
| @@ -3555,13 +4747,19 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| */
|
| Object visitPropertyAccess(PropertyAccess node) {
|
| SimpleIdentifier propertyName2 = node.propertyName;
|
| - Element element30 = propertyName2.element;
|
| - if (element30 is MethodElement) {
|
| - FunctionType type15 = ((element30 as MethodElement)).type;
|
| - recordType(propertyName2, type15);
|
| - return recordType(node, type15);
|
| - } else if (element30 is PropertyAccessorElement) {
|
| - Type2 propertyType = getType2((element30 as PropertyAccessorElement));
|
| + Element element36 = propertyName2.element;
|
| + if (USE_TYPE_PROPAGATION) {
|
| + Type2 type = _overrideManager.getType(element36);
|
| + if (type != null) {
|
| + return recordType(node, type);
|
| + }
|
| + }
|
| + if (element36 is MethodElement) {
|
| + FunctionType type19 = ((element36 as MethodElement)).type;
|
| + recordType(propertyName2, type19);
|
| + return recordType(node, type19);
|
| + } else if (element36 is PropertyAccessorElement) {
|
| + Type2 propertyType = getType3((element36 as PropertyAccessorElement), node.target != null ? node.target.staticType : null);
|
| recordType(propertyName2, propertyType);
|
| return recordType(node, propertyType);
|
| } else {
|
| @@ -3617,31 +4815,41 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * </blockquote>
|
| */
|
| Object visitSimpleIdentifier(SimpleIdentifier node) {
|
| - Element element31 = node.element;
|
| - if (element31 == null) {
|
| + Element element37 = node.element;
|
| + if (element37 == null) {
|
| return recordType(node, _dynamicType);
|
| - } else if (element31 is ClassElement) {
|
| + }
|
| + if (USE_TYPE_PROPAGATION) {
|
| + Type2 type = _overrideManager.getType(element37);
|
| + if (type != null) {
|
| + return recordType(node, type);
|
| + }
|
| + }
|
| + Type2 type;
|
| + if (element37 is ClassElement) {
|
| if (isNotTypeLiteral(node)) {
|
| - return recordType(node, ((element31 as ClassElement)).type);
|
| - }
|
| - return recordType(node, _typeProvider.typeType);
|
| - } else if (element31 is TypeVariableElement) {
|
| - return recordType(node, ((element31 as TypeVariableElement)).type);
|
| - } else if (element31 is FunctionTypeAliasElement) {
|
| - return recordType(node, ((element31 as FunctionTypeAliasElement)).type);
|
| - } else if (element31 is VariableElement) {
|
| - return recordType(node, ((element31 as VariableElement)).type);
|
| - } else if (element31 is MethodElement) {
|
| - return recordType(node, ((element31 as MethodElement)).type);
|
| - } else if (element31 is PropertyAccessorElement) {
|
| - return recordType(node, getType2((element31 as PropertyAccessorElement)));
|
| - } else if (element31 is ExecutableElement) {
|
| - return recordType(node, ((element31 as ExecutableElement)).type);
|
| - } else if (element31 is PrefixElement) {
|
| + type = ((element37 as ClassElement)).type;
|
| + } else {
|
| + type = _typeProvider.typeType;
|
| + }
|
| + } else if (element37 is FunctionTypeAliasElement) {
|
| + type = ((element37 as FunctionTypeAliasElement)).type;
|
| + } else if (element37 is MethodElement) {
|
| + type = ((element37 as MethodElement)).type;
|
| + } else if (element37 is PropertyAccessorElement) {
|
| + type = getType3((element37 as PropertyAccessorElement), null);
|
| + } else if (element37 is ExecutableElement) {
|
| + type = ((element37 as ExecutableElement)).type;
|
| + } else if (element37 is TypeVariableElement) {
|
| + type = ((element37 as TypeVariableElement)).type;
|
| + } else if (element37 is VariableElement) {
|
| + type = ((element37 as VariableElement)).type;
|
| + } else if (element37 is PrefixElement) {
|
| return null;
|
| } else {
|
| - return recordType(node, _dynamicType);
|
| + type = _dynamicType;
|
| }
|
| + return recordType(node, type);
|
| }
|
| /**
|
| * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is{@code String}.</blockquote>
|
| @@ -3674,6 +4882,19 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * bottom.</blockquote>
|
| */
|
| Object visitThrowExpression(ThrowExpression node) => recordType(node, _typeProvider.bottomType);
|
| + Object visitVariableDeclaration(VariableDeclaration node) {
|
| + if (USE_TYPE_PROPAGATION) {
|
| + Expression initializer6 = node.initializer;
|
| + if (initializer6 != null) {
|
| + Type2 rightType = getType2(initializer6);
|
| + VariableElement element38 = node.name.element as VariableElement;
|
| + if (element38 != null) {
|
| + override(element38, getType(element38), rightType);
|
| + }
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| /**
|
| * Given a function declaration, compute the return type of the function. The return type of
|
| * functions with a block body is {@code dynamicType}, with an expression body it is the type of
|
| @@ -3682,11 +4903,11 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * @return the return type that was computed
|
| */
|
| Type2 computeReturnType(FunctionDeclaration node) {
|
| - TypeName returnType8 = node.returnType;
|
| - if (returnType8 == null) {
|
| + TypeName returnType9 = node.returnType;
|
| + if (returnType9 == null) {
|
| return computeReturnType2(node.functionExpression);
|
| }
|
| - return returnType8.type;
|
| + return returnType9.type;
|
| }
|
| /**
|
| * Given a function expression, compute the return type of the function. The return type of
|
| @@ -3698,16 +4919,60 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| Type2 computeReturnType2(FunctionExpression node) {
|
| FunctionBody body4 = node.body;
|
| if (body4 is ExpressionFunctionBody) {
|
| - return getType(((body4 as ExpressionFunctionBody)).expression);
|
| + return getType2(((body4 as ExpressionFunctionBody)).expression);
|
| }
|
| return _dynamicType;
|
| }
|
| /**
|
| + * If the given argument list contains at least one argument, and if the argument is a simple
|
| + * string literal, and if the value of the argument is the name of a class defined within the
|
| + * given library, return the type specified by the argument.
|
| + * @param library the library in which the specified type would be defined
|
| + * @param argumentList the list of arguments from which a type is to be extracted
|
| + * @return the type specified by the first argument in the argument list
|
| + */
|
| + Type2 getFirstArgumentAsType(LibraryElement library, ArgumentList argumentList) => getFirstArgumentAsType2(library, argumentList, null);
|
| + /**
|
| + * If the given argument list contains at least one argument, and if the argument is a simple
|
| + * string literal, and if the value of the argument is the name of a class defined within the
|
| + * given library, return the type specified by the argument.
|
| + * @param library the library in which the specified type would be defined
|
| + * @param argumentList the list of arguments from which a type is to be extracted
|
| + * @return the type specified by the first argument in the argument list
|
| + */
|
| + Type2 getFirstArgumentAsType2(LibraryElement library, ArgumentList argumentList, Map<String, String> nameMap) {
|
| + NodeList<Expression> arguments6 = argumentList.arguments;
|
| + if (arguments6.length > 0) {
|
| + Expression argument = arguments6[0];
|
| + if (argument is SimpleStringLiteral) {
|
| + String argumentValue = ((argument as SimpleStringLiteral)).value;
|
| + if (argumentValue != null) {
|
| + if (nameMap != null) {
|
| + argumentValue = nameMap[argumentValue.toLowerCase()];
|
| + }
|
| + ClassElement returnType = library.getType(argumentValue);
|
| + if (returnType != null) {
|
| + return returnType.type;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| + Type2 getType(Element element) {
|
| + if (element is LocalVariableElement) {
|
| + return ((element as LocalVariableElement)).type;
|
| + } else if (element is ParameterElement) {
|
| + return ((element as ParameterElement)).type;
|
| + }
|
| + return null;
|
| + }
|
| + /**
|
| * Return the type of the given expression that is to be used for type analysis.
|
| * @param expression the expression whose type is to be returned
|
| * @return the type of the given expression
|
| */
|
| - Type2 getType(Expression expression) {
|
| + Type2 getType2(Expression expression) {
|
| Type2 type = expression.staticType;
|
| if (type == null) {
|
| return _dynamicType;
|
| @@ -3717,9 +4982,12 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| /**
|
| * Return the type that should be recorded for a node that resolved to the given accessor.
|
| * @param accessor the accessor that the node resolved to
|
| + * @param context if the accessor element has context [by being the RHS of a{@link PrefixedIdentifier} or {@link PropertyAccess}], and the return type of the
|
| + * accessor is a parameter type, then the type of the LHS can be used to get more
|
| + * specific type information
|
| * @return the type that should be recorded for a node that resolved to the given accessor
|
| */
|
| - Type2 getType2(PropertyAccessorElement accessor) {
|
| + Type2 getType3(PropertyAccessorElement accessor, Type2 context) {
|
| FunctionType functionType = accessor.type;
|
| if (functionType == null) {
|
| return _dynamicType;
|
| @@ -3738,48 +5006,80 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| }
|
| return _dynamicType;
|
| }
|
| - return functionType.returnType;
|
| + Type2 returnType10 = functionType.returnType;
|
| + if (returnType10 is TypeVariableType && context is InterfaceType) {
|
| + InterfaceType interfaceTypeContext = (context as InterfaceType);
|
| + List<TypeVariableElement> parameterElements = interfaceTypeContext.element != null ? interfaceTypeContext.element.typeVariables : null;
|
| + if (parameterElements != null) {
|
| + for (int i = 0; i < parameterElements.length; i++) {
|
| + TypeVariableElement varElt = parameterElements[i];
|
| + if (returnType10.name == varElt.name) {
|
| + return interfaceTypeContext.typeArguments[i];
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return returnType10;
|
| }
|
| /**
|
| * Return the type represented by the given type name.
|
| * @param typeName the type name representing the type to be returned
|
| * @return the type represented by the type name
|
| */
|
| - Type2 getType3(TypeName typeName) {
|
| - Type2 type16 = typeName.type;
|
| - if (type16 == null) {
|
| + Type2 getType4(TypeName typeName) {
|
| + Type2 type20 = typeName.type;
|
| + if (type20 == null) {
|
| return _dynamicType;
|
| }
|
| - return type16;
|
| + return type20;
|
| }
|
| /**
|
| + * Return {@code true} if the given library is the 'dart:html' library.
|
| + * @param library the library being tested
|
| + * @return {@code true} if the library is 'dart:html'
|
| + */
|
| + bool isHtmlLibrary(LibraryElement library) => library.name == "dart.dom.html";
|
| + /**
|
| * Return {@code true} if the given node is not a type literal.
|
| * @param node the node being tested
|
| * @return {@code true} if the given node is not a type literal
|
| */
|
| - bool isNotTypeLiteral(SimpleIdentifier node) {
|
| + bool isNotTypeLiteral(Identifier node) {
|
| ASTNode parent15 = node.parent;
|
| return parent15 is TypeName || (parent15 is PrefixedIdentifier && (parent15.parent is TypeName || identical(((parent15 as PrefixedIdentifier)).prefix, node))) || (parent15 is PropertyAccess && identical(((parent15 as PropertyAccess)).target, node)) || (parent15 is MethodInvocation && identical(node, ((parent15 as MethodInvocation)).target));
|
| }
|
| /**
|
| + * If it is appropriate to do so, override the type of the given element. Use the static type and
|
| + * inferred type of the element to determine whether or not it is appropriate.
|
| + * @param element the element whose type might be overridden
|
| + * @param staticType the static type of the element
|
| + * @param inferredType the inferred type of the element
|
| + */
|
| + void override(VariableElement element, Type2 staticType, Type2 inferredType) {
|
| + if (identical(inferredType, BottomTypeImpl.instance) || element is! VariableElement) {
|
| + return;
|
| + }
|
| + if (element is PropertyInducingElement) {
|
| + PropertyInducingElement variable = element as PropertyInducingElement;
|
| + if (!variable.isConst() && !variable.isFinal()) {
|
| + return;
|
| + }
|
| + }
|
| + if (staticType == null || (inferredType != null && inferredType.isMoreSpecificThan(staticType))) {
|
| + _overrideManager.setType(element, inferredType);
|
| + }
|
| + }
|
| + /**
|
| * Record that the static type of the given node is the type of the second argument to the method
|
| * represented by the given element.
|
| * @param expression the node whose type is to be recorded
|
| * @param element the element representing the method invoked by the given node
|
| - * @param typeArguments the array of {@link Type}s to perform a substitution on the parameter
|
| - * types from the type in the passed {@link Element}, or <code>null</code>
|
| */
|
| - Object recordArgumentType(IndexExpression expression, MethodElement element, List<Type2> typeArguments10) {
|
| + Object recordArgumentType(IndexExpression expression, MethodElement element) {
|
| if (element != null) {
|
| - List<ParameterElement> parameters12 = element.parameters;
|
| - if (parameters12 != null && parameters12.length == 2) {
|
| - ClassElement classElement = parameters12[1].getAncestor(ClassElement);
|
| - List<Type2> typeParameters = classElement == null ? null : classElement.type.typeArguments;
|
| - if (typeArguments10 == null || typeParameters == null || typeArguments10.length != typeParameters.length) {
|
| - return recordType(expression, parameters12[1].type);
|
| - } else {
|
| - return recordType(expression, parameters12[1].type.substitute2(typeArguments10, typeParameters));
|
| - }
|
| + List<ParameterElement> parameters14 = element.parameters;
|
| + if (parameters14 != null && parameters14.length == 2) {
|
| + return recordType(expression, parameters14[1].type);
|
| }
|
| }
|
| return recordType(expression, _dynamicType);
|
| @@ -3789,34 +5089,28 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * represented by the given element.
|
| * @param expression the node whose type is to be recorded
|
| * @param element the element representing the method or function invoked by the given node
|
| - * @param typeArguments the array of {@link Type}s to perform a substitution on the parameter
|
| - * types from the type in the passed {@link Element}, or <code>null</code>
|
| */
|
| - Object recordReturnType(Expression expression, Element element, List<Type2> typeArguments11) {
|
| + Object recordReturnType(Expression expression, Element element) {
|
| if (element is PropertyAccessorElement) {
|
| FunctionType propertyType = ((element as PropertyAccessorElement)).type;
|
| if (propertyType != null) {
|
| - Type2 returnType9 = propertyType.returnType;
|
| - if (returnType9 is FunctionType) {
|
| - Type2 innerReturnType = ((returnType9 as FunctionType)).returnType;
|
| + Type2 returnType11 = propertyType.returnType;
|
| + if (returnType11 is FunctionType) {
|
| + Type2 innerReturnType = ((returnType11 as FunctionType)).returnType;
|
| if (innerReturnType != null) {
|
| return recordType(expression, innerReturnType);
|
| }
|
| + } else if (returnType11.isDartCoreFunction()) {
|
| + return recordType(expression, _dynamicType);
|
| }
|
| - if (returnType9 != null) {
|
| - return recordType(expression, returnType9);
|
| + if (returnType11 != null) {
|
| + return recordType(expression, returnType11);
|
| }
|
| }
|
| } else if (element is ExecutableElement) {
|
| - FunctionType type17 = ((element as ExecutableElement)).type;
|
| - if (type17 != null) {
|
| - ClassElement classElement = element.getAncestor(ClassElement);
|
| - List<Type2> typeParameters = classElement == null ? null : classElement.type.typeArguments;
|
| - if (typeArguments11 == null || typeParameters == null || typeArguments11.length != typeParameters.length) {
|
| - return recordType(expression, type17.returnType);
|
| - } else {
|
| - return recordType(expression, type17.returnType.substitute2(typeArguments11, typeParameters));
|
| - }
|
| + FunctionType type21 = ((element as ExecutableElement)).type;
|
| + if (type21 != null) {
|
| + return recordType(expression, type21.returnType);
|
| }
|
| } else if (element is VariableElement) {
|
| Type2 variableType = ((element as VariableElement)).type;
|
| @@ -3846,7 +5140,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| * @param returnType the return type of the function, or {@code null} if no type was declared
|
| * @param parameters the elements representing the parameters to the function
|
| */
|
| - void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType12, FormalParameterList parameterList) {
|
| + void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType14, FormalParameterList parameterList) {
|
| List<Type2> normalParameterTypes = new List<Type2>();
|
| List<Type2> optionalParameterTypes = new List<Type2>();
|
| LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
|
| @@ -3867,12 +5161,112 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
|
| functionType.normalParameterTypes = new List.from(normalParameterTypes);
|
| functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
|
| functionType.namedParameterTypes = namedParameterTypes;
|
| - functionType.returnType = returnType12;
|
| + functionType.returnType = returnType14;
|
| }
|
| get thisType_J2DAccessor => _thisType;
|
| set thisType_J2DAccessor(__v) => _thisType = __v;
|
| }
|
| /**
|
| + * Instances of the class {@code TypeOverrideManager} manage the ability to override the type of an
|
| + * element within a given context.
|
| + */
|
| +class TypeOverrideManager {
|
| + /**
|
| + * The current override scope, or {@code null} if no scope has been entered.
|
| + */
|
| + TypeOverrideManager_TypeOverrideScope _currentScope;
|
| + /**
|
| + * Initialize a newly created override manager to not be in any scope.
|
| + */
|
| + TypeOverrideManager() : super() {
|
| + }
|
| + /**
|
| + * Enter a new override scope.
|
| + */
|
| + void enterScope() {
|
| + _currentScope = new TypeOverrideManager_TypeOverrideScope(_currentScope);
|
| + }
|
| + /**
|
| + * Exit the current override scope.
|
| + */
|
| + void exitScope() {
|
| + if (_currentScope == null) {
|
| + throw new IllegalStateException("No scope to exit");
|
| + }
|
| + _currentScope = _currentScope._outerScope;
|
| + }
|
| + /**
|
| + * Return the overridden type of the given element, or {@code null} if the type of the element has
|
| + * not been overridden.
|
| + * @param element the element whose type might have been overridden
|
| + * @return the overridden type of the given element
|
| + */
|
| + Type2 getType(Element element) {
|
| + if (_currentScope == null) {
|
| + return null;
|
| + }
|
| + return _currentScope.getType(element);
|
| + }
|
| + /**
|
| + * Set the overridden type of the given element to the given type
|
| + * @param element the element whose type might have been overridden
|
| + * @param type the overridden type of the given element
|
| + */
|
| + void setType(Element element, Type2 type) {
|
| + if (_currentScope == null) {
|
| + throw new IllegalStateException("Cannot override without a scope");
|
| + }
|
| + _currentScope.setType(element, type);
|
| + }
|
| +}
|
| +/**
|
| + * Instances of the class {@code TypeOverrideScope} represent a scope in which the types of
|
| + * elements can be overridden.
|
| + */
|
| +class TypeOverrideManager_TypeOverrideScope {
|
| + /**
|
| + * The outer scope in which types might be overridden.
|
| + */
|
| + TypeOverrideManager_TypeOverrideScope _outerScope;
|
| + /**
|
| + * A table mapping elements to the overridden type of that element.
|
| + */
|
| + Map<Element, Type2> _overridenTypes = new Map<Element, Type2>();
|
| + /**
|
| + * Initialize a newly created scope to be an empty child of the given scope.
|
| + * @param outerScope the outer scope in which types might be overridden
|
| + */
|
| + TypeOverrideManager_TypeOverrideScope(TypeOverrideManager_TypeOverrideScope outerScope) {
|
| + this._outerScope = outerScope;
|
| + }
|
| + /**
|
| + * Return the overridden type of the given element, or {@code null} if the type of the element
|
| + * has not been overridden.
|
| + * @param element the element whose type might have been overridden
|
| + * @return the overridden type of the given element
|
| + */
|
| + Type2 getType(Element element) {
|
| + Type2 type = _overridenTypes[element];
|
| + if (type == null && element is PropertyAccessorElement) {
|
| + type = _overridenTypes[((element as PropertyAccessorElement)).variable];
|
| + }
|
| + if (type != null) {
|
| + return type;
|
| + } else if (_outerScope != null) {
|
| + return _outerScope.getType(element);
|
| + }
|
| + return null;
|
| + }
|
| + /**
|
| + * Set the overridden type of the given element to the given type
|
| + * @param element the element whose type might have been overridden
|
| + * @param type the overridden type of the given element
|
| + */
|
| + void setType(Element element, Type2 type) {
|
| + _overridenTypes[element] = type;
|
| + }
|
| +}
|
| +/**
|
| * The interface {@code TypeProvider} defines the behavior of objects that provide access to types
|
| * defined by the language.
|
| * @coverage dart.engine.resolver
|
| @@ -4076,7 +5470,25 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| * @param source the source representing the compilation unit being visited
|
| * @param typeProvider the object used to access the types from the core library
|
| */
|
| - TypeResolverVisitor(Library library, Source source, TypeProvider typeProvider) : super(library, source, typeProvider) {
|
| + TypeResolverVisitor.con1(Library library, Source source, TypeProvider typeProvider) : super.con1(library, source, typeProvider) {
|
| + _jtd_constructor_273_impl(library, source, typeProvider);
|
| + }
|
| + _jtd_constructor_273_impl(Library library, Source source, TypeProvider typeProvider) {
|
| + _dynamicType = typeProvider.dynamicType;
|
| + }
|
| + /**
|
| + * Initialize a newly created visitor to resolve the nodes in a compilation unit.
|
| + * @param definingLibrary the element for the library containing the compilation unit being
|
| + * visited
|
| + * @param source the source representing the compilation unit being visited
|
| + * @param typeProvider the object used to access the types from the core library
|
| + * @param errorListener the error listener that will be informed of any errors that are found
|
| + * during resolution
|
| + */
|
| + TypeResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) : super.con2(definingLibrary, source, typeProvider, errorListener) {
|
| + _jtd_constructor_274_impl(definingLibrary, source, typeProvider, errorListener);
|
| + }
|
| + _jtd_constructor_274_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
|
| _dynamicType = typeProvider.dynamicType;
|
| }
|
| Object visitCatchClause(CatchClause node) {
|
| @@ -4088,12 +5500,12 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| if (exceptionTypeName == null) {
|
| exceptionType = typeProvider.objectType;
|
| } else {
|
| - exceptionType = getType4(exceptionTypeName);
|
| + exceptionType = getType5(exceptionTypeName);
|
| }
|
| recordType(exception, exceptionType);
|
| - Element element32 = exception.element;
|
| - if (element32 is VariableElementImpl) {
|
| - ((element32 as VariableElementImpl)).type = exceptionType;
|
| + Element element39 = exception.element;
|
| + if (element39 is VariableElementImpl) {
|
| + ((element39 as VariableElementImpl)).type = exceptionType;
|
| } else {
|
| }
|
| }
|
| @@ -4109,7 +5521,7 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| InterfaceType superclassType = null;
|
| ExtendsClause extendsClause4 = node.extendsClause;
|
| if (extendsClause4 != null) {
|
| - superclassType = resolveType(extendsClause4.superclass, CompileTimeErrorCode.EXTENDS_NON_CLASS, CompileTimeErrorCode.EXTENDS_NON_CLASS, null);
|
| + superclassType = resolveType(extendsClause4.superclass, CompileTimeErrorCode.EXTENDS_NON_CLASS);
|
| if (superclassType != typeProvider.objectType) {
|
| classElement.validMixin = false;
|
| }
|
| @@ -4129,7 +5541,7 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| Object visitClassTypeAlias(ClassTypeAlias node) {
|
| super.visitClassTypeAlias(node);
|
| ClassElementImpl classElement = getClassElement(node.name);
|
| - InterfaceType superclassType = resolveType(node.superclass, CompileTimeErrorCode.EXTENDS_NON_CLASS, CompileTimeErrorCode.EXTENDS_NON_CLASS, null);
|
| + InterfaceType superclassType = resolveType(node.superclass, CompileTimeErrorCode.EXTENDS_NON_CLASS);
|
| if (superclassType == null) {
|
| superclassType = typeProvider.objectType;
|
| }
|
| @@ -4141,11 +5553,11 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| }
|
| Object visitConstructorDeclaration(ConstructorDeclaration node) {
|
| super.visitConstructorDeclaration(node);
|
| - ExecutableElementImpl element33 = node.element as ExecutableElementImpl;
|
| - FunctionTypeImpl type = new FunctionTypeImpl.con1(element33);
|
| - setTypeInformation(type, null, element33.parameters);
|
| - type.returnType = ((element33.enclosingElement as ClassElement)).type;
|
| - element33.type = type;
|
| + ExecutableElementImpl element40 = node.element as ExecutableElementImpl;
|
| + FunctionTypeImpl type = new FunctionTypeImpl.con1(element40);
|
| + setTypeInformation(type, null, element40.parameters);
|
| + type.returnType = ((element40.enclosingElement as ClassElement)).type;
|
| + element40.type = type;
|
| return null;
|
| }
|
| Object visitDeclaredIdentifier(DeclaredIdentifier node) {
|
| @@ -4155,10 +5567,10 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| if (typeName == null) {
|
| declaredType = _dynamicType;
|
| } else {
|
| - declaredType = getType4(typeName);
|
| + declaredType = getType5(typeName);
|
| }
|
| - LocalVariableElementImpl element34 = node.element as LocalVariableElementImpl;
|
| - element34.type = declaredType;
|
| + LocalVariableElementImpl element41 = node.element as LocalVariableElementImpl;
|
| + element41.type = declaredType;
|
| return null;
|
| }
|
| Object visitDefaultFormalParameter(DefaultFormalParameter node) {
|
| @@ -4167,15 +5579,15 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| }
|
| Object visitFieldFormalParameter(FieldFormalParameter node) {
|
| super.visitFieldFormalParameter(node);
|
| - Element element35 = node.identifier.element;
|
| - if (element35 is ParameterElementImpl) {
|
| - ParameterElementImpl parameter = element35 as ParameterElementImpl;
|
| + Element element42 = node.identifier.element;
|
| + if (element42 is ParameterElementImpl) {
|
| + ParameterElementImpl parameter = element42 as ParameterElementImpl;
|
| Type2 type;
|
| TypeName typeName = node.type;
|
| if (typeName == null) {
|
| type = _dynamicType;
|
| } else {
|
| - type = getType4(typeName);
|
| + type = getType5(typeName);
|
| }
|
| parameter.type = type;
|
| } else {
|
| @@ -4184,42 +5596,42 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| }
|
| Object visitFunctionDeclaration(FunctionDeclaration node) {
|
| super.visitFunctionDeclaration(node);
|
| - ExecutableElementImpl element36 = node.element as ExecutableElementImpl;
|
| - FunctionTypeImpl type = new FunctionTypeImpl.con1(element36);
|
| - setTypeInformation(type, node.returnType, element36.parameters);
|
| - element36.type = type;
|
| + ExecutableElementImpl element43 = node.element as ExecutableElementImpl;
|
| + FunctionTypeImpl type = new FunctionTypeImpl.con1(element43);
|
| + setTypeInformation(type, node.returnType, element43.parameters);
|
| + element43.type = type;
|
| return null;
|
| }
|
| Object visitFunctionTypeAlias(FunctionTypeAlias node) {
|
| super.visitFunctionTypeAlias(node);
|
| - FunctionTypeAliasElementImpl element37 = node.element as FunctionTypeAliasElementImpl;
|
| - FunctionTypeImpl type18 = element37.type as FunctionTypeImpl;
|
| - setTypeInformation(type18, node.returnType, element37.parameters);
|
| + FunctionTypeAliasElementImpl element44 = node.element as FunctionTypeAliasElementImpl;
|
| + FunctionTypeImpl type22 = element44.type as FunctionTypeImpl;
|
| + setTypeInformation(type22, node.returnType, element44.parameters);
|
| return null;
|
| }
|
| Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
|
| super.visitFunctionTypedFormalParameter(node);
|
| - ParameterElementImpl element38 = node.identifier.element as ParameterElementImpl;
|
| + ParameterElementImpl element45 = node.identifier.element as ParameterElementImpl;
|
| FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement));
|
| setTypeInformation(type, node.returnType, getElements(node.parameters));
|
| - element38.type = type;
|
| + element45.type = type;
|
| return null;
|
| }
|
| Object visitMethodDeclaration(MethodDeclaration node) {
|
| super.visitMethodDeclaration(node);
|
| - ExecutableElementImpl element39 = node.element as ExecutableElementImpl;
|
| - FunctionTypeImpl type = new FunctionTypeImpl.con1(element39);
|
| - setTypeInformation(type, node.returnType, element39.parameters);
|
| - element39.type = type;
|
| - if (element39 is PropertyAccessorElementImpl) {
|
| - PropertyAccessorElementImpl accessor = element39 as PropertyAccessorElementImpl;
|
| - PropertyInducingElementImpl variable5 = accessor.variable as PropertyInducingElementImpl;
|
| + ExecutableElementImpl element46 = node.element as ExecutableElementImpl;
|
| + FunctionTypeImpl type = new FunctionTypeImpl.con1(element46);
|
| + setTypeInformation(type, node.returnType, element46.parameters);
|
| + element46.type = type;
|
| + if (element46 is PropertyAccessorElement) {
|
| + PropertyAccessorElement accessor = element46 as PropertyAccessorElement;
|
| + PropertyInducingElementImpl variable6 = accessor.variable as PropertyInducingElementImpl;
|
| if (accessor.isGetter()) {
|
| - variable5.type = type.returnType;
|
| - } else if (variable5.type == null) {
|
| + variable6.type = type.returnType;
|
| + } else if (variable6.type == null) {
|
| List<Type2> parameterTypes = type.normalParameterTypes;
|
| if (parameterTypes != null && parameterTypes.length > 0) {
|
| - variable5.type = parameterTypes[0];
|
| + variable6.type = parameterTypes[0];
|
| }
|
| }
|
| }
|
| @@ -4232,11 +5644,11 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| if (typeName == null) {
|
| declaredType = _dynamicType;
|
| } else {
|
| - declaredType = getType4(typeName);
|
| + declaredType = getType5(typeName);
|
| }
|
| - Element element40 = node.identifier.element;
|
| - if (element40 is ParameterElement) {
|
| - ((element40 as ParameterElementImpl)).type = declaredType;
|
| + Element element47 = node.identifier.element;
|
| + if (element47 is ParameterElement) {
|
| + ((element47 as ParameterElementImpl)).type = declaredType;
|
| } else {
|
| }
|
| return null;
|
| @@ -4267,20 +5679,27 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| if (typeName is PrefixedIdentifier && parent16 is ConstructorName && argumentList == null) {
|
| ConstructorName name = parent16 as ConstructorName;
|
| if (name.name == null) {
|
| - SimpleIdentifier prefix8 = ((typeName as PrefixedIdentifier)).prefix;
|
| - element = nameScope.lookup(prefix8, definingLibrary);
|
| + SimpleIdentifier prefix7 = ((typeName as PrefixedIdentifier)).prefix;
|
| + element = nameScope.lookup(prefix7, definingLibrary);
|
| if (element is PrefixElement) {
|
| return null;
|
| } else if (element != null) {
|
| name.name = ((typeName as PrefixedIdentifier)).identifier;
|
| name.period = ((typeName as PrefixedIdentifier)).period;
|
| - node.name = prefix8;
|
| - typeName = prefix8;
|
| + node.name = prefix7;
|
| + typeName = prefix7;
|
| }
|
| }
|
| }
|
| }
|
| if (element == null) {
|
| + Identifier simpleIdentifier;
|
| + if (typeName is SimpleIdentifier) {
|
| + simpleIdentifier = typeName;
|
| + } else {
|
| + simpleIdentifier = ((typeName as PrefixedIdentifier)).prefix;
|
| + }
|
| + reportError(StaticWarningCode.UNDEFINED_CLASS, simpleIdentifier, [simpleIdentifier.name]);
|
| setElement(typeName, _dynamicType.element);
|
| typeName.staticType = _dynamicType;
|
| node.type = _dynamicType;
|
| @@ -4298,6 +5717,12 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| type = ((element as TypeVariableElement)).type;
|
| if (argumentList != null) {
|
| }
|
| + } else if (element is MultiplyDefinedElement) {
|
| + List<Element> elements = ((element as MultiplyDefinedElement)).conflictingElements;
|
| + type = getType(elements);
|
| + if (type != null) {
|
| + node.type = type;
|
| + }
|
| } else {
|
| setElement(typeName, _dynamicType.element);
|
| typeName.staticType = _dynamicType;
|
| @@ -4305,20 +5730,20 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| return null;
|
| }
|
| if (argumentList != null) {
|
| - NodeList<TypeName> arguments6 = argumentList.arguments;
|
| - int argumentCount = arguments6.length;
|
| + NodeList<TypeName> arguments7 = argumentList.arguments;
|
| + int argumentCount = arguments7.length;
|
| List<Type2> parameters = getTypeArguments(type);
|
| int parameterCount = parameters.length;
|
| int count = Math.min(argumentCount, parameterCount);
|
| List<Type2> typeArguments = new List<Type2>();
|
| for (int i = 0; i < count; i++) {
|
| - Type2 argumentType = getType4(arguments6[i]);
|
| + Type2 argumentType = getType5(arguments7[i]);
|
| if (argumentType != null) {
|
| typeArguments.add(argumentType);
|
| }
|
| }
|
| if (argumentCount != parameterCount) {
|
| - reportError(getInvalidTypeParametersErrorCode(node), node, [typeName.name, argumentCount, parameterCount]);
|
| + reportError(getInvalidTypeParametersErrorCode(node), node, [typeName.name, parameterCount, argumentCount]);
|
| }
|
| argumentCount = typeArguments.length;
|
| if (argumentCount < parameterCount) {
|
| @@ -4357,18 +5782,18 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| if (typeName == null) {
|
| declaredType = _dynamicType;
|
| } else {
|
| - declaredType = getType4(typeName);
|
| - }
|
| - Element element41 = node.name.element;
|
| - if (element41 is VariableElement) {
|
| - ((element41 as VariableElementImpl)).type = declaredType;
|
| - if (element41 is FieldElement) {
|
| - FieldElement field = element41 as FieldElement;
|
| - PropertyAccessorElementImpl getter5 = field.getter as PropertyAccessorElementImpl;
|
| + declaredType = getType5(typeName);
|
| + }
|
| + Element element48 = node.name.element;
|
| + if (element48 is VariableElement) {
|
| + ((element48 as VariableElementImpl)).type = declaredType;
|
| + if (element48 is PropertyInducingElement) {
|
| + PropertyInducingElement variableElement = element48 as PropertyInducingElement;
|
| + PropertyAccessorElementImpl getter5 = variableElement.getter as PropertyAccessorElementImpl;
|
| FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter5);
|
| getterType.returnType = declaredType;
|
| getter5.type = getterType;
|
| - PropertyAccessorElementImpl setter4 = field.setter as PropertyAccessorElementImpl;
|
| + PropertyAccessorElementImpl setter4 = variableElement.setter as PropertyAccessorElementImpl;
|
| if (setter4 != null) {
|
| FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter4);
|
| setterType.returnType = VoidTypeImpl.instance;
|
| @@ -4389,11 +5814,11 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| if (identifier == null) {
|
| return null;
|
| }
|
| - Element element42 = identifier.element;
|
| - if (element42 is! ClassElementImpl) {
|
| + Element element49 = identifier.element;
|
| + if (element49 is! ClassElementImpl) {
|
| return null;
|
| }
|
| - return element42 as ClassElementImpl;
|
| + return element49 as ClassElementImpl;
|
| }
|
| /**
|
| * Return an array containing all of the elements associated with the parameters in the given
|
| @@ -4404,9 +5829,9 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| List<ParameterElement> getElements(FormalParameterList parameterList) {
|
| List<ParameterElement> elements = new List<ParameterElement>();
|
| for (FormalParameter parameter in parameterList.parameters) {
|
| - ParameterElement element43 = parameter.identifier.element as ParameterElement;
|
| - if (element43 != null) {
|
| - elements.add(element43);
|
| + ParameterElement element50 = parameter.identifier.element as ParameterElement;
|
| + if (element50 != null) {
|
| + elements.add(element50);
|
| }
|
| }
|
| return new List.from(elements);
|
| @@ -4456,12 +5881,12 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| * @param typeName the type name representing the type to be returned
|
| * @return the type represented by the type name
|
| */
|
| - Type2 getType4(TypeName typeName) {
|
| - Type2 type19 = typeName.type;
|
| - if (type19 == null) {
|
| + Type2 getType5(TypeName typeName) {
|
| + Type2 type23 = typeName.type;
|
| + if (type23 == null) {
|
| return _dynamicType;
|
| }
|
| - return type19;
|
| + return type23;
|
| }
|
| /**
|
| * Return the type arguments associated with the given type.
|
| @@ -4499,13 +5924,45 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| */
|
| void resolve(ClassElementImpl classElement, WithClause withClause, ImplementsClause implementsClause) {
|
| if (withClause != null) {
|
| - List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, CompileTimeErrorCode.MIXIN_OF_NON_CLASS, CompileTimeErrorCode.MIXIN_OF_NON_CLASS, null);
|
| + List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
|
| if (classElement != null) {
|
| classElement.mixins = mixinTypes2;
|
| }
|
| }
|
| if (implementsClause != null) {
|
| - List<InterfaceType> interfaceTypes = resolveTypes(implementsClause.interfaces, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, null);
|
| + NodeList<TypeName> interfaces3 = implementsClause.interfaces;
|
| + List<InterfaceType> interfaceTypes = resolveTypes(interfaces3, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS);
|
| + List<TypeName> typeNames = new List.from(interfaces3);
|
| + String dynamicKeyword = sc.Keyword.DYNAMIC.syntax;
|
| + List<bool> detectedRepeatOnIndex = new List<bool>.filled(typeNames.length, false);
|
| + for (int i = 0; i < detectedRepeatOnIndex.length; i++) {
|
| + detectedRepeatOnIndex[i] = false;
|
| + }
|
| + for (int i = 0; i < typeNames.length; i++) {
|
| + TypeName typeName = typeNames[i];
|
| + String name19 = typeName.name.name;
|
| + if (name19 == dynamicKeyword) {
|
| + reportError(CompileTimeErrorCode.IMPLEMENTS_DYNAMIC, typeName, []);
|
| + } else {
|
| + Element element51 = typeName.name.element;
|
| + if (element51 != null && element51 == classElement) {
|
| + reportError(CompileTimeErrorCode.IMPLEMENTS_SELF, typeName, [name19]);
|
| + }
|
| + }
|
| + if (!detectedRepeatOnIndex[i]) {
|
| + for (int j = i + 1; j < typeNames.length; j++) {
|
| + Element element52 = typeName.name.element;
|
| + TypeName typeName2 = typeNames[j];
|
| + Identifier identifier2 = typeName2.name;
|
| + String name2 = identifier2.name;
|
| + Element element2 = identifier2.element;
|
| + if (element52 != null && element52 == element2) {
|
| + detectedRepeatOnIndex[j] = true;
|
| + reportError(CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [name2]);
|
| + }
|
| + }
|
| + }
|
| + }
|
| if (classElement != null) {
|
| classElement.interfaces = interfaceTypes;
|
| }
|
| @@ -4514,65 +5971,49 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| /**
|
| * Return the type specified by the given name.
|
| * @param typeName the type name specifying the type to be returned
|
| - * @param undefinedError the error to produce if the type name is not defined
|
| * @param nonTypeError the error to produce if the type name is defined to be something other than
|
| * a type
|
| - * @param nonInterfaceType the error to produce if the type is not an interface type
|
| * @return the type specified by the type name
|
| */
|
| - InterfaceType resolveType(TypeName typeName, ErrorCode undefinedError, ErrorCode nonTypeError, ErrorCode nonInterfaceType) {
|
| - Identifier name17 = typeName.name;
|
| - Element element = nameScope.lookup(name17, definingLibrary);
|
| - if (element == null) {
|
| - reportError(undefinedError, name17, [name17.name]);
|
| - } else if (element is ClassElement) {
|
| - Type2 classType = ((element as ClassElement)).type;
|
| - typeName.type = classType;
|
| - if (classType is InterfaceType) {
|
| - return classType as InterfaceType;
|
| - }
|
| - reportError(nonInterfaceType, name17, [name17.name]);
|
| - } else if (element is MultiplyDefinedElement) {
|
| - List<Element> elements = ((element as MultiplyDefinedElement)).conflictingElements;
|
| - InterfaceType type = getType(elements);
|
| - if (type != null) {
|
| - typeName.type = type;
|
| - }
|
| - } else {
|
| - reportError(nonTypeError, name17, [name17.name]);
|
| + InterfaceType resolveType(TypeName typeName, ErrorCode nonTypeError) {
|
| + Type2 type24 = typeName.type;
|
| + if (type24 is InterfaceType) {
|
| + return type24 as InterfaceType;
|
| + }
|
| + Identifier name20 = typeName.name;
|
| + if (name20.name != sc.Keyword.DYNAMIC.syntax) {
|
| + reportError(nonTypeError, name20, [name20.name]);
|
| }
|
| return null;
|
| }
|
| /**
|
| * Resolve the types in the given list of type names.
|
| * @param typeNames the type names to be resolved
|
| - * @param undefinedError the error to produce if the type name is not defined
|
| * @param nonTypeError the error to produce if the type name is defined to be something other than
|
| * a type
|
| - * @param nonInterfaceType the error to produce if the type is not an interface type
|
| * @return an array containing all of the types that were resolved.
|
| */
|
| - List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ErrorCode undefinedError, ErrorCode nonTypeError, ErrorCode nonInterfaceType) {
|
| + List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ErrorCode nonTypeError) {
|
| List<InterfaceType> types = new List<InterfaceType>();
|
| for (TypeName typeName in typeNames) {
|
| - InterfaceType type = resolveType(typeName, undefinedError, nonTypeError, nonInterfaceType);
|
| + InterfaceType type = resolveType(typeName, nonTypeError);
|
| if (type != null) {
|
| types.add(type);
|
| }
|
| }
|
| return new List.from(types);
|
| }
|
| - void setElement(Identifier typeName, Element element60) {
|
| - if (element60 != null) {
|
| + void setElement(Identifier typeName, Element element69) {
|
| + if (element69 != null) {
|
| if (typeName is SimpleIdentifier) {
|
| - ((typeName as SimpleIdentifier)).element = element60;
|
| + ((typeName as SimpleIdentifier)).element = element69;
|
| } else if (typeName is PrefixedIdentifier) {
|
| PrefixedIdentifier identifier = typeName as PrefixedIdentifier;
|
| - identifier.identifier.element = element60;
|
| - SimpleIdentifier prefix9 = identifier.prefix;
|
| - Element prefixElement = nameScope.lookup(prefix9, definingLibrary);
|
| + identifier.identifier.element = element69;
|
| + SimpleIdentifier prefix8 = identifier.prefix;
|
| + Element prefixElement = nameScope.lookup(prefix8, definingLibrary);
|
| if (prefixElement != null) {
|
| - prefix9.element = prefixElement;
|
| + prefix8.element = prefixElement;
|
| }
|
| }
|
| }
|
| @@ -4584,7 +6025,7 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| * @param returnType the return type of the function, or {@code null} if no type was declared
|
| * @param parameters the elements representing the parameters to the function
|
| */
|
| - void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType13, List<ParameterElement> parameters) {
|
| + void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType15, List<ParameterElement> parameters) {
|
| List<Type2> normalParameterTypes = new List<Type2>();
|
| List<Type2> optionalParameterTypes = new List<Type2>();
|
| LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
|
| @@ -4609,10 +6050,10 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| if (!namedParameterTypes.isEmpty) {
|
| functionType.namedParameterTypes = namedParameterTypes;
|
| }
|
| - if (returnType13 == null) {
|
| + if (returnType15 == null) {
|
| functionType.returnType = _dynamicType;
|
| } else {
|
| - functionType.returnType = returnType13.type;
|
| + functionType.returnType = returnType15.type;
|
| }
|
| }
|
| }
|
| @@ -4705,8 +6146,8 @@ class FunctionScope extends EnclosedScope {
|
| void defineParameters(ExecutableElement functionElement) {
|
| Scope parameterScope = enclosingScope;
|
| if (functionElement.enclosingElement is ExecutableElement) {
|
| - String name18 = functionElement.name;
|
| - if (name18 != null && !name18.isEmpty) {
|
| + String name21 = functionElement.name;
|
| + if (name21 != null && !name21.isEmpty) {
|
| parameterScope.define(functionElement);
|
| }
|
| }
|
| @@ -4774,10 +6215,10 @@ class LabelScope {
|
| * @param onSwitchMember {@code true} if this label is associated with a {@code switch} member
|
| */
|
| LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
|
| - _jtd_constructor_254_impl(outerScope, onSwitchStatement, onSwitchMember);
|
| + _jtd_constructor_279_impl(outerScope, onSwitchStatement, onSwitchMember);
|
| }
|
| - _jtd_constructor_254_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
|
| - _jtd_constructor_255_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
|
| + _jtd_constructor_279_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
|
| + _jtd_constructor_280_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
|
| }
|
| /**
|
| * Initialize a newly created scope to represent the given label.
|
| @@ -4786,9 +6227,9 @@ class LabelScope {
|
| * @param element the element to which the label resolves
|
| */
|
| LabelScope.con2(LabelScope outerScope2, String label4, LabelElement element21) {
|
| - _jtd_constructor_255_impl(outerScope2, label4, element21);
|
| + _jtd_constructor_280_impl(outerScope2, label4, element21);
|
| }
|
| - _jtd_constructor_255_impl(LabelScope outerScope2, String label4, LabelElement element21) {
|
| + _jtd_constructor_280_impl(LabelScope outerScope2, String label4, LabelElement element21) {
|
| this._outerScope = outerScope2;
|
| this._label = label4;
|
| this._element = element21;
|
| @@ -4854,9 +6295,6 @@ class LibraryImportScope extends Scope {
|
| LibraryElement get definingLibrary => _definingLibrary;
|
| AnalysisErrorListener get errorListener => _errorListener;
|
| Element lookup3(String name, LibraryElement referencingLibrary) {
|
| - if (Scope.isPrivateName(name)) {
|
| - return null;
|
| - }
|
| Element foundElement = localLookup(name, referencingLibrary);
|
| if (foundElement != null) {
|
| return foundElement;
|
| @@ -5047,9 +6485,9 @@ class NamespaceBuilder {
|
| * @param element the element to be added
|
| */
|
| void addIfPublic(Map<String, Element> definedNames, Element element) {
|
| - String name19 = element.name;
|
| - if (name19 != null && !Scope.isPrivateName(name19)) {
|
| - definedNames[name19] = element;
|
| + String name22 = element.name;
|
| + if (name22 != null && !Scope.isPrivateName(name22)) {
|
| + definedNames[name22] = element;
|
| }
|
| }
|
| /**
|
| @@ -5130,7 +6568,7 @@ class NamespaceBuilder {
|
| addAll(definedNames, exportedNames);
|
| }
|
| }
|
| - addAll2(definedNames, ((library.context as AnalysisContextImpl)).getPublicNamespace(library));
|
| + addAll2(definedNames, ((library.context as InternalAnalysisContext)).getPublicNamespace(library));
|
| return definedNames;
|
| } finally {
|
| visitedElements.remove(library);
|
| @@ -5208,10 +6646,12 @@ abstract class Scope {
|
| */
|
| void define(Element element) {
|
| String name = getName(element);
|
| - if (_definedNames.containsKey(name)) {
|
| - errorListener.onError(getErrorForDuplicate(_definedNames[name], element));
|
| - } else {
|
| - _definedNames[name] = element;
|
| + if (name != null && !name.isEmpty) {
|
| + if (_definedNames.containsKey(name)) {
|
| + errorListener.onError(getErrorForDuplicate(_definedNames[name], element));
|
| + } else {
|
| + _definedNames[name] = element;
|
| + }
|
| }
|
| }
|
| /**
|
| @@ -5242,7 +6682,13 @@ abstract class Scope {
|
| * @param duplicate another element declared with the conflicting name
|
| * @return the error code used to report duplicate names within a scope
|
| */
|
| - AnalysisError getErrorForDuplicate(Element existing, Element duplicate) => new AnalysisError.con2(source, duplicate.nameOffset, duplicate.name.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.name]);
|
| + AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
|
| + Source source15 = duplicate.source;
|
| + if (source15 == null) {
|
| + source15 = source;
|
| + }
|
| + return new AnalysisError.con2(source15, duplicate.nameOffset, duplicate.name.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.name]);
|
| + }
|
| /**
|
| * Return the listener that is to be informed when an error is encountered.
|
| * @return the listener that is to be informed when an error is encountered
|
| @@ -5333,11 +6779,11 @@ class ConstantVerifier extends RecursiveASTVisitor<Object> {
|
| StringLiteral key4 = entry.key;
|
| EvaluationResultImpl result = validate(key4, CompileTimeErrorCode.NON_CONSTANT_MAP_KEY);
|
| if (result is ValidResult && ((result as ValidResult)).value is String) {
|
| - String value10 = ((result as ValidResult)).value as String;
|
| - if (keys.contains(value10)) {
|
| + String value11 = ((result as ValidResult)).value as String;
|
| + if (keys.contains(value11)) {
|
| _errorReporter.reportError(StaticWarningCode.EQUAL_KEYS_IN_MAP, key4, []);
|
| } else {
|
| - javaSetAdd(keys, value10);
|
| + javaSetAdd(keys, value11);
|
| }
|
| }
|
| if (isConst) {
|
| @@ -5358,32 +6804,42 @@ class ConstantVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| Object visitVariableDeclaration(VariableDeclaration node) {
|
| super.visitVariableDeclaration(node);
|
| - Expression initializer4 = node.initializer;
|
| - if (initializer4 != null && node.isConst()) {
|
| - EvaluationResultImpl result = validate(initializer4, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
|
| - VariableElementImpl element49 = node.element as VariableElementImpl;
|
| - element49.evaluationResult = result;
|
| + Expression initializer7 = node.initializer;
|
| + if (initializer7 != null && node.isConst()) {
|
| + VariableElementImpl element58 = node.element as VariableElementImpl;
|
| + EvaluationResultImpl result = element58.evaluationResult;
|
| + if (result == null) {
|
| + result = validate(initializer7, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
|
| + element58.evaluationResult = result;
|
| + } else if (result is ErrorResult) {
|
| + reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
|
| + }
|
| }
|
| return null;
|
| }
|
| /**
|
| + * If the given result represents one or more errors, report those errors. Except for special
|
| + * cases, use the given error code rather than the one reported in the error.
|
| + * @param result the result containing any errors that need to be reported
|
| + * @param errorCode the error code to be used if the result represents an error
|
| + */
|
| + void reportErrors(EvaluationResultImpl result, ErrorCode errorCode) {
|
| + if (result is ErrorResult) {
|
| + for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
|
| + _errorReporter.reportError(errorCode, data.node, []);
|
| + }
|
| + }
|
| + }
|
| + /**
|
| * Validate that the given expression is a compile time constant. Return the value of the compile
|
| * time constant, or {@code null} if the expression is not a compile time constant.
|
| * @param expression the expression to be validated
|
| * @param errorCode the error code to be used if the expression is not a compile time constant
|
| * @return the value of the compile time constant
|
| */
|
| - EvaluationResultImpl validate(Expression expression, ErrorCode errorCode4) {
|
| + EvaluationResultImpl validate(Expression expression, ErrorCode errorCode) {
|
| EvaluationResultImpl result = expression.accept(new ConstantVisitor());
|
| - if (result is ErrorResult) {
|
| - for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
|
| - if (identical(data.errorCode, CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO)) {
|
| - _errorReporter.reportError(data.errorCode, data.node, []);
|
| - } else {
|
| - _errorReporter.reportError(errorCode4, data.node, []);
|
| - }
|
| - }
|
| - }
|
| + reportErrors(result, errorCode);
|
| return result;
|
| }
|
| /**
|
| @@ -5391,19 +6847,19 @@ class ConstantVerifier extends RecursiveASTVisitor<Object> {
|
| * compile time constant.
|
| * @param parameters the list of parameters to be validated
|
| */
|
| - void validateDefaultValues(FormalParameterList parameters15) {
|
| - if (parameters15 == null) {
|
| + void validateDefaultValues(FormalParameterList parameters17) {
|
| + if (parameters17 == null) {
|
| return;
|
| }
|
| - for (FormalParameter parameter in parameters15.parameters) {
|
| + for (FormalParameter parameter in parameters17.parameters) {
|
| if (parameter is DefaultFormalParameter) {
|
| DefaultFormalParameter defaultParameter = parameter as DefaultFormalParameter;
|
| - Expression defaultValue2 = defaultParameter.defaultValue;
|
| - if (defaultValue2 != null) {
|
| - EvaluationResultImpl result = validate(defaultValue2, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE);
|
| + Expression defaultValue3 = defaultParameter.defaultValue;
|
| + if (defaultValue3 != null) {
|
| + EvaluationResultImpl result = validate(defaultValue3, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE);
|
| if (defaultParameter.isConst()) {
|
| - VariableElementImpl element50 = parameter.element as VariableElementImpl;
|
| - element50.evaluationResult = result;
|
| + VariableElementImpl element59 = parameter.element as VariableElementImpl;
|
| + element59.evaluationResult = result;
|
| }
|
| }
|
| }
|
| @@ -5433,20 +6889,36 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| */
|
| TypeProvider _typeProvider;
|
| /**
|
| - * This is set to <code>true</code> iff the visitor is currently visiting children nodes of a{@link ConstructorDeclaration} and the constructor is 'const'.
|
| + * This is set to {@code true} iff the visitor is currently visiting children nodes of a{@link ConstructorDeclaration} and the constructor is 'const'.
|
| * @see #visitConstructorDeclaration(ConstructorDeclaration)
|
| */
|
| bool _isEnclosingConstructorConst = false;
|
| /**
|
| - * This is set to <code>true</code> iff the visitor is currently visiting children nodes of a{@link CatchClause}.
|
| + * This is set to {@code true} iff the visitor is currently visiting children nodes of a{@link CatchClause}.
|
| * @see #visitCatchClause(CatchClause)
|
| */
|
| bool _isInCatchClause = false;
|
| /**
|
| - * The method or function that we are currently visiting, or <code>null</code> if we are not
|
| - * inside a method or function.
|
| + * This is set to {@code true} iff the visitor is currently visiting code in the SDK.
|
| + */
|
| + bool _isInSystemLibrary = false;
|
| + /**
|
| + * The method or function that we are currently visiting, or {@code null} if we are not inside a
|
| + * method or function.
|
| + */
|
| + ExecutableElement _enclosingFunction;
|
| + /**
|
| + * This map is initialized when visiting the contents of a class declaration. If the visitor is
|
| + * not in an enclosing class declaration, then the map is set to {@code null}.
|
| + * <p>
|
| + * When set the map maps the set of {@link FieldElement}s in the class to an{@link INIT_STATE#NOT_INIT} or {@link INIT_STATE#INIT_IN_DECLARATION}. <code>checkFor*</code>
|
| + * methods, specifically {@link #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)},
|
| + * can make a copy of the map to compute error code states. <code>checkFor*</code> methods should
|
| + * only ever make a copy, or read from this map after it has been set in{@link #visitClassDeclaration(ClassDeclaration)}.
|
| + * @see #visitClassDeclaration(ClassDeclaration)
|
| + * @see #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)
|
| */
|
| - ExecutableElement _currentFunction;
|
| + Map<FieldElement, INIT_STATE> _initialFieldElementsMap;
|
| /**
|
| * A list of types used by the {@link CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS} and{@link CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS} error codes.
|
| */
|
| @@ -5454,6 +6926,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| ErrorVerifier(ErrorReporter errorReporter, LibraryElement currentLibrary, TypeProvider typeProvider) {
|
| this._errorReporter = errorReporter;
|
| this._currentLibrary = currentLibrary;
|
| + this._isInSystemLibrary = currentLibrary.source.isInSystemLibrary();
|
| this._typeProvider = typeProvider;
|
| _isEnclosingConstructorConst = false;
|
| _isInCatchClause = false;
|
| @@ -5482,8 +6955,23 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| }
|
| Object visitClassDeclaration(ClassDeclaration node) {
|
| - checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
|
| - return super.visitClassDeclaration(node);
|
| + try {
|
| + checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
|
| + ClassElement classElement = node.element;
|
| + if (classElement != null) {
|
| + List<FieldElement> fieldElements = classElement.fields;
|
| + _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>();
|
| + for (FieldElement fieldElement in fieldElements) {
|
| + if (!fieldElement.isSynthetic()) {
|
| + _initialFieldElementsMap[fieldElement] = fieldElement.initializer == null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION;
|
| + }
|
| + }
|
| + }
|
| + checkForFinalNotInitialized(node);
|
| + return super.visitClassDeclaration(node);
|
| + } finally {
|
| + _initialFieldElementsMap = null;
|
| + }
|
| }
|
| Object visitClassTypeAlias(ClassTypeAlias node) {
|
| checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
|
| @@ -5494,23 +6982,19 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| return super.visitConditionalExpression(node);
|
| }
|
| Object visitConstructorDeclaration(ConstructorDeclaration node) {
|
| - ExecutableElement previousFunction = _currentFunction;
|
| + ExecutableElement outerFunction = _enclosingFunction;
|
| try {
|
| - _currentFunction = node.element;
|
| + _enclosingFunction = node.element;
|
| _isEnclosingConstructorConst = node.constKeyword != null;
|
| checkForConstConstructorWithNonFinalField(node);
|
| checkForConflictingConstructorNameAndMember(node);
|
| + checkForAllFinalInitializedErrorCodes(node);
|
| return super.visitConstructorDeclaration(node);
|
| } finally {
|
| _isEnclosingConstructorConst = false;
|
| - _currentFunction = previousFunction;
|
| + _enclosingFunction = outerFunction;
|
| }
|
| }
|
| - Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
|
| - checkForFieldInitializedInInitializerAndDeclaration(node);
|
| - checkForFieldInitializedInParameterAndInitializer(node);
|
| - return super.visitConstructorFieldInitializer(node);
|
| - }
|
| Object visitDoStatement(DoStatement node) {
|
| checkForNonBoolCondition(node.condition);
|
| return super.visitDoStatement(node);
|
| @@ -5525,21 +7009,21 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| return super.visitFieldFormalParameter(node);
|
| }
|
| Object visitFunctionDeclaration(FunctionDeclaration node) {
|
| - ExecutableElement previousFunction = _currentFunction;
|
| + ExecutableElement outerFunction = _enclosingFunction;
|
| try {
|
| - _currentFunction = node.element;
|
| + _enclosingFunction = node.element;
|
| return super.visitFunctionDeclaration(node);
|
| } finally {
|
| - _currentFunction = previousFunction;
|
| + _enclosingFunction = outerFunction;
|
| }
|
| }
|
| Object visitFunctionExpression(FunctionExpression node) {
|
| - ExecutableElement previousFunction = _currentFunction;
|
| + ExecutableElement outerFunction = _enclosingFunction;
|
| try {
|
| - _currentFunction = node.element;
|
| + _enclosingFunction = node.element;
|
| return super.visitFunctionExpression(node);
|
| } finally {
|
| - _currentFunction = previousFunction;
|
| + _enclosingFunction = outerFunction;
|
| }
|
| }
|
| Object visitFunctionTypeAlias(FunctionTypeAlias node) {
|
| @@ -5558,9 +7042,9 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| Object visitInstanceCreationExpression(InstanceCreationExpression node) {
|
| ConstructorName constructorName4 = node.constructorName;
|
| TypeName typeName = constructorName4.type;
|
| - Type2 type20 = typeName.type;
|
| - if (type20 is InterfaceType) {
|
| - InterfaceType interfaceType = type20 as InterfaceType;
|
| + Type2 type25 = typeName.type;
|
| + if (type25 is InterfaceType) {
|
| + InterfaceType interfaceType = type25 as InterfaceType;
|
| checkForConstWithNonConst(node);
|
| checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
|
| checkForTypeArgumentNotMatchingBounds(node, constructorName4.element, typeName);
|
| @@ -5568,14 +7052,18 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| return super.visitInstanceCreationExpression(node);
|
| }
|
| Object visitMethodDeclaration(MethodDeclaration node) {
|
| - ExecutableElement previousFunction = _currentFunction;
|
| + ExecutableElement previousFunction = _enclosingFunction;
|
| try {
|
| - _currentFunction = node.element;
|
| + _enclosingFunction = node.element;
|
| return super.visitMethodDeclaration(node);
|
| } finally {
|
| - _currentFunction = previousFunction;
|
| + _enclosingFunction = previousFunction;
|
| }
|
| }
|
| + Object visitNativeFunctionBody(NativeFunctionBody node) {
|
| + checkForNativeFunctionBodyInNonSDKCode(node);
|
| + return super.visitNativeFunctionBody(node);
|
| + }
|
| Object visitRethrowExpression(RethrowExpression node) {
|
| checkForRethrowOutsideCatch(node);
|
| return super.visitRethrowExpression(node);
|
| @@ -5596,6 +7084,10 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| checkForConstEvalThrowsException(node);
|
| return super.visitThrowExpression(node);
|
| }
|
| + Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
|
| + checkForFinalNotInitialized2(node.variables);
|
| + return super.visitTopLevelVariableDeclaration(node);
|
| + }
|
| Object visitTypeParameter(TypeParameter node) {
|
| checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME);
|
| return super.visitTypeParameter(node);
|
| @@ -5604,21 +7096,92 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| checkForBuiltInIdentifierAsName2(node);
|
| return super.visitVariableDeclarationList(node);
|
| }
|
| + Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
|
| + checkForFinalNotInitialized2(node.variables);
|
| + return super.visitVariableDeclarationStatement(node);
|
| + }
|
| Object visitWhileStatement(WhileStatement node) {
|
| checkForNonBoolCondition(node.condition);
|
| return super.visitWhileStatement(node);
|
| }
|
| /**
|
| + * This verifies that the passed constructor declaration does not violate any of the error codes
|
| + * relating to the initialization of fields in the enclosing class.
|
| + * @param node the {@link ConstructorDeclaration} to evaluate
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| + * @see #initialFieldElementsMap
|
| + * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
|
| + * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES
|
| + */
|
| + bool checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) {
|
| + if (node.factoryKeyword != null || node.redirectedConstructor != null || node.externalKeyword != null) {
|
| + return false;
|
| + }
|
| + bool foundError = false;
|
| + Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_STATE>.from(_initialFieldElementsMap);
|
| + NodeList<FormalParameter> formalParameters = node.parameters.parameters;
|
| + for (FormalParameter formalParameter in formalParameters) {
|
| + FormalParameter parameter = formalParameter;
|
| + if (parameter is DefaultFormalParameter) {
|
| + parameter = ((parameter as DefaultFormalParameter)).parameter;
|
| + }
|
| + if (parameter is FieldFormalParameter) {
|
| + FieldElement fieldElement = ((parameter.element as FieldFormalParameterElementImpl)).field;
|
| + INIT_STATE state = fieldElementsMap[fieldElement];
|
| + if (identical(state, INIT_STATE.NOT_INIT)) {
|
| + fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL;
|
| + } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) {
|
| + if (fieldElement.isFinal() || fieldElement.isConst()) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.name]);
|
| + foundError = true;
|
| + }
|
| + } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) {
|
| + if (fieldElement.isFinal() || fieldElement.isConst()) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, formalParameter.identifier, [fieldElement.name]);
|
| + foundError = true;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + NodeList<ConstructorInitializer> initializers2 = node.initializers;
|
| + for (ConstructorInitializer constructorInitializer in initializers2) {
|
| + if (constructorInitializer is ConstructorFieldInitializer) {
|
| + ConstructorFieldInitializer constructorFieldInitializer = constructorInitializer as ConstructorFieldInitializer;
|
| + SimpleIdentifier fieldName3 = constructorFieldInitializer.fieldName;
|
| + Element element60 = fieldName3.element;
|
| + if (element60 is FieldElement) {
|
| + FieldElement fieldElement = element60 as FieldElement;
|
| + INIT_STATE state = fieldElementsMap[fieldElement];
|
| + if (identical(state, INIT_STATE.NOT_INIT)) {
|
| + fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS;
|
| + } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) {
|
| + if (fieldElement.isFinal() || fieldElement.isConst()) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, fieldName3, []);
|
| + foundError = true;
|
| + }
|
| + } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, fieldName3, []);
|
| + foundError = true;
|
| + } else if (identical(state, INIT_STATE.INIT_IN_INITIALIZERS)) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, fieldName3, [fieldElement.name]);
|
| + foundError = true;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return foundError;
|
| + }
|
| + /**
|
| * This verifies that the passed argument definition test identifier is a parameter.
|
| * @param node the {@link ArgumentDefinitionTest} to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#ARGUMENT_DEFINITION_TEST_NON_PARAMETER
|
| */
|
| bool checkForArgumentDefinitionTestNonParameter(ArgumentDefinitionTest node) {
|
| - SimpleIdentifier identifier14 = node.identifier;
|
| - Element element51 = identifier14.element;
|
| - if (element51 != null && element51 is! ParameterElement) {
|
| - _errorReporter.reportError(CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER, identifier14, [identifier14.name]);
|
| + SimpleIdentifier identifier15 = node.identifier;
|
| + Element element61 = identifier15.element;
|
| + if (element61 != null && element61 is! ParameterElement) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER, identifier15, [identifier15.name]);
|
| return true;
|
| }
|
| return false;
|
| @@ -5629,14 +7192,14 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * @param identifier the identifier to check to ensure that it is not a keyword
|
| * @param errorCode if the passed identifier is a keyword then this error code is created on the
|
| * identifier, the error code will be one of{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME},{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME} or{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME}
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME
|
| * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME
|
| * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME
|
| */
|
| bool checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode errorCode) {
|
| - sc.Token token13 = identifier.token;
|
| - if (identical(token13.type, sc.TokenType.KEYWORD)) {
|
| + sc.Token token18 = identifier.token;
|
| + if (identical(token18.type, sc.TokenType.KEYWORD)) {
|
| _errorReporter.reportError(errorCode, identifier, [identifier.name]);
|
| return true;
|
| }
|
| @@ -5645,7 +7208,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| /**
|
| * This verifies that the passed variable declaration list does not have a built-in identifier.
|
| * @param node the variable declaration list to check
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE
|
| */
|
| bool checkForBuiltInIdentifierAsName2(VariableDeclarationList node) {
|
| @@ -5654,9 +7217,9 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| Identifier identifier = typeName.name;
|
| if (identifier is SimpleIdentifier) {
|
| SimpleIdentifier simpleIdentifier = identifier as SimpleIdentifier;
|
| - sc.Token token14 = simpleIdentifier.token;
|
| - if (identical(token14.type, sc.TokenType.KEYWORD)) {
|
| - if (((token14 as sc.KeywordToken)).keyword != sc.Keyword.DYNAMIC) {
|
| + sc.Token token19 = simpleIdentifier.token;
|
| + if (identical(token19.type, sc.TokenType.KEYWORD)) {
|
| + if (((token19 as sc.KeywordToken)).keyword != sc.Keyword.DYNAMIC) {
|
| _errorReporter.reportError(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, identifier, [identifier.name]);
|
| return true;
|
| }
|
| @@ -5669,19 +7232,19 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * This verifies that the passed switch statement does not have a case expression with the
|
| * operator '==' overridden.
|
| * @param node the switch statement to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
|
| */
|
| bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node) {
|
| Expression expression16 = node.expression;
|
| Type2 type = expression16.staticType;
|
| if (type != null && type != _typeProvider.intType && type != _typeProvider.stringType) {
|
| - Element element52 = type.element;
|
| - if (element52 is ClassElement) {
|
| - ClassElement classElement = element52 as ClassElement;
|
| + Element element62 = type.element;
|
| + if (element62 is ClassElement) {
|
| + ClassElement classElement = element62 as ClassElement;
|
| MethodElement method = classElement.lookUpMethod("==", _currentLibrary);
|
| if (method != null && method.enclosingElement.type != _typeProvider.objectType) {
|
| - _errorReporter.reportError(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, expression16, [element52.name]);
|
| + _errorReporter.reportError(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, expression16, [element62.name]);
|
| return true;
|
| }
|
| }
|
| @@ -5692,19 +7255,19 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| ConstructorElement constructorElement = node.element;
|
| SimpleIdentifier constructorName = node.name;
|
| if (constructorName != null && constructorElement != null && !constructorName.isSynthetic()) {
|
| - String name21 = constructorName.name;
|
| + String name24 = constructorName.name;
|
| ClassElement classElement = constructorElement.enclosingElement;
|
| List<FieldElement> fields3 = classElement.fields;
|
| for (FieldElement field in fields3) {
|
| - if (field.name == name21) {
|
| - _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [name21]);
|
| + if (field.name == name24) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [name24]);
|
| return true;
|
| }
|
| }
|
| List<MethodElement> methods3 = classElement.methods;
|
| for (MethodElement method in methods3) {
|
| - if (method.name == name21) {
|
| - _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, [name21]);
|
| + if (method.name == name24) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, [name24]);
|
| return true;
|
| }
|
| }
|
| @@ -5715,7 +7278,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * This verifies that the passed constructor declaration is not 'const' if it has a non-final
|
| * instance variable.
|
| * @param node the instance creation expression to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
|
| */
|
| bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) {
|
| @@ -5727,7 +7290,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| ClassElement classElement = constructorElement.enclosingElement;
|
| List<FieldElement> elements = classElement.fields;
|
| for (FieldElement field in elements) {
|
| - if (!field.isFinal() && !field.isConst() && !field.isSynthetic()) {
|
| + if (!field.isFinal() && !field.isConst() && !field.isStatic() && !field.isSynthetic()) {
|
| _errorReporter.reportError(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node, []);
|
| return true;
|
| }
|
| @@ -5739,7 +7302,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * This verifies that the passed throw expression is not enclosed in a 'const' constructor
|
| * declaration.
|
| * @param node the throw expression expression to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#CONST_EVAL_THROWS_EXCEPTION
|
| */
|
| bool checkForConstEvalThrowsException(ThrowExpression node) {
|
| @@ -5752,7 +7315,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| /**
|
| * This verifies that the passed normal formal parameter is not 'const'.
|
| * @param node the normal formal parameter to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER
|
| */
|
| bool checkForConstFormalParameter(NormalFormalParameter node) {
|
| @@ -5768,14 +7331,14 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * @param node the instance creation expression to evaluate
|
| * @param typeName the {@link TypeName} of the {@link ConstructorName} from the{@link InstanceCreationExpression}, this is the AST node that the error is attached to
|
| * @param type the type being constructed with this {@link InstanceCreationExpression}
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS
|
| * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS
|
| */
|
| bool checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
|
| if (type.element.isAbstract()) {
|
| - ConstructorElement element53 = node.element;
|
| - if (element53 != null && !element53.isFactory()) {
|
| + ConstructorElement element63 = node.element;
|
| + if (element63 != null && !element63.isFactory()) {
|
| if (identical(((node.keyword as sc.KeywordToken)).keyword, sc.Keyword.CONST)) {
|
| _errorReporter.reportError(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName, []);
|
| } else {
|
| @@ -5790,7 +7353,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * This verifies that if the passed instance creation expression is 'const', then it is not being
|
| * invoked on a constructor that is not 'const'.
|
| * @param node the instance creation expression to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#CONST_WITH_NON_CONST
|
| */
|
| bool checkForConstWithNonConst(InstanceCreationExpression node) {
|
| @@ -5804,14 +7367,14 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| /**
|
| * This verifies that there are no default parameters in the passed function type alias.
|
| * @param node the function type alias to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS
|
| */
|
| bool checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) {
|
| bool result = false;
|
| FormalParameterList formalParameterList = node.parameters;
|
| - NodeList<FormalParameter> parameters13 = formalParameterList.parameters;
|
| - for (FormalParameter formalParameter in parameters13) {
|
| + NodeList<FormalParameter> parameters15 = formalParameterList.parameters;
|
| + for (FormalParameter formalParameter in parameters15) {
|
| if (formalParameter is DefaultFormalParameter) {
|
| DefaultFormalParameter defaultFormalParameter = formalParameter as DefaultFormalParameter;
|
| if (defaultFormalParameter.defaultValue != null) {
|
| @@ -5825,7 +7388,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| /**
|
| * This verifies that the passed extends clause does not extend classes such as num or String.
|
| * @param node the extends clause to test
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
|
| */
|
| bool checkForExtendsDisallowedClass(ExtendsClause extendsClause) => checkForExtendsOrImplementsDisallowedClass(extendsClause.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
|
| @@ -5833,7 +7396,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * This verifies that the passed type name does not extend or implement classes such as 'num' or
|
| * 'String'.
|
| * @param node the type name to test
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see #checkForExtendsDisallowedClass(ExtendsClause)
|
| * @see #checkForImplementsDisallowedClass(ImplementsClause)
|
| * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
|
| @@ -5845,7 +7408,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| Type2 superType = typeName.type;
|
| for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT) {
|
| - if (superType == disallowedType) {
|
| + if (superType != null && superType == disallowedType) {
|
| if (superType == _typeProvider.numType) {
|
| ASTNode grandParent = typeName.parent.parent;
|
| if (grandParent is ClassDeclaration) {
|
| @@ -5863,96 +7426,107 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| return false;
|
| }
|
| /**
|
| - * This verifies that the passed constructor field initializer is not also a final variable that
|
| - * already included an initialization.
|
| - * @param node the constructor field initializer to test
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| - * @see CompileTimeErrorCode#FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
|
| - */
|
| - bool checkForFieldInitializedInInitializerAndDeclaration(ConstructorFieldInitializer node) {
|
| - SimpleIdentifier identifier = node.fieldName;
|
| - Element element54 = identifier.element;
|
| - if (element54 is PropertyAccessorElement) {
|
| - PropertyAccessorElement propertyAccessorElement = element54 as PropertyAccessorElement;
|
| - PropertyInducingElement propertyInducingElement = propertyAccessorElement.variable;
|
| - if (propertyInducingElement.initializer != null && (propertyInducingElement.isFinal() || propertyInducingElement.isConst())) {
|
| - _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, node, []);
|
| + * This verifies that the passed field formal parameter is in a constructor declaration.
|
| + * @param node the field formal parameter to test
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| + * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
|
| + */
|
| + bool checkForFieldInitializerOutsideConstructor(FieldFormalParameter node) {
|
| + ASTNode parent18 = node.parent;
|
| + if (parent18 != null) {
|
| + ASTNode grandparent = parent18.parent;
|
| + if (grandparent != null && grandparent is! ConstructorDeclaration && grandparent.parent is! ConstructorDeclaration) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node, []);
|
| return true;
|
| }
|
| }
|
| return false;
|
| }
|
| /**
|
| - * This verifies that the passed constructor field initializer is not also a field formal
|
| - * parameter in the constructor declaration.
|
| - * @param node the constructor field initializer to test
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| - * @see CompileTimeErrorCode#FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER
|
| + * This verifies that final fields that are declared, without any constructors in the enclosing
|
| + * class, are initialized. Cases in which there is at least one constructor are handled at the end
|
| + * of {@link #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)}.
|
| + * @param node the class declaration to test
|
| + * @return {@code true} if and only if an error code is generated on the passed node
|
| + * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED
|
| */
|
| - bool checkForFieldInitializedInParameterAndInitializer(ConstructorFieldInitializer node) {
|
| - SimpleIdentifier identifier = node.fieldName;
|
| - Element element55 = identifier.element;
|
| - ASTNode parent18 = node.parent;
|
| - if (element55 != null && parent18 is ConstructorDeclaration) {
|
| - ConstructorDeclaration constructorDeclaration = parent18 as ConstructorDeclaration;
|
| - NodeList<FormalParameter> formalParameters = constructorDeclaration.parameters.parameters;
|
| - for (FormalParameter formalParameter in formalParameters) {
|
| - if (formalParameter is FieldFormalParameter) {
|
| - FieldFormalParameter fieldFormalParameter = formalParameter as FieldFormalParameter;
|
| - if (fieldFormalParameter.identifier.name == element55.name) {
|
| - _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, node, []);
|
| - return true;
|
| - }
|
| - }
|
| + bool checkForFinalNotInitialized(ClassDeclaration node) {
|
| + NodeList<ClassMember> classMembers = node.members;
|
| + for (ClassMember classMember in classMembers) {
|
| + if (classMember is ConstructorDeclaration) {
|
| + return false;
|
| }
|
| }
|
| - return false;
|
| + bool foundError = false;
|
| + for (ClassMember classMember in classMembers) {
|
| + if (classMember is FieldDeclaration) {
|
| + FieldDeclaration field = classMember as FieldDeclaration;
|
| + foundError = javaBooleanOr(foundError, checkForFinalNotInitialized2(field.fields));
|
| + }
|
| + }
|
| + return foundError;
|
| }
|
| /**
|
| - * This verifies that the passed field formal parameter is in a constructor declaration.
|
| - * @param node the field formal parameter to test
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| - * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
|
| + * This verifies that the passed variable declaration list has only initialized variables if the
|
| + * list is final or const. This method is called by{@link #checkForFinalNotInitialized(ClassDeclaration)},{@link #visitTopLevelVariableDeclaration(TopLevelVariableDeclaration)} and{@link #visitVariableDeclarationStatement(VariableDeclarationStatement)}.
|
| + * @param node the class declaration to test
|
| + * @return {@code true} if and only if an error code is generated on the passed node
|
| + * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED
|
| */
|
| - bool checkForFieldInitializerOutsideConstructor(FieldFormalParameter node) {
|
| - ASTNode parent19 = node.parent;
|
| - if (parent19 != null) {
|
| - ASTNode grandparent = parent19.parent;
|
| - if (grandparent != null && grandparent is! ConstructorDeclaration && grandparent.parent is! ConstructorDeclaration) {
|
| - _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node, []);
|
| - return true;
|
| + bool checkForFinalNotInitialized2(VariableDeclarationList node) {
|
| + bool foundError = false;
|
| + if (!node.isSynthetic() && (node.isConst() || node.isFinal())) {
|
| + NodeList<VariableDeclaration> variables3 = node.variables;
|
| + for (VariableDeclaration variable in variables3) {
|
| + if (variable.initializer == null) {
|
| + _errorReporter.reportError(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, variable, [variable.name.name]);
|
| + foundError = true;
|
| + }
|
| }
|
| }
|
| - return false;
|
| + return foundError;
|
| }
|
| /**
|
| * This verifies that the passed implements clause does not implement classes such as 'num' or
|
| * 'String'.
|
| * @param node the implements clause to test
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
|
| */
|
| bool checkForImplementsDisallowedClass(ImplementsClause implementsClause) {
|
| - bool result = false;
|
| + bool foundError = false;
|
| for (TypeName type in implementsClause.interfaces) {
|
| - result = javaBooleanOr(result, checkForExtendsOrImplementsDisallowedClass(type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS));
|
| - ;
|
| + foundError = javaBooleanOr(foundError, checkForExtendsOrImplementsDisallowedClass(type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS));
|
| }
|
| - return result;
|
| + return foundError;
|
| }
|
| /**
|
| * This verifies that the passed assignment expression represents a valid assignment.
|
| * @param node the assignment expression to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
|
| */
|
| bool checkForInvalidAssignment(AssignmentExpression node) {
|
| Expression lhs = node.leftHandSide;
|
| Expression rhs = node.rightHandSide;
|
| - Type2 leftType = getType(lhs);
|
| + VariableElement leftElement = getVariableElement(lhs);
|
| + Type2 leftType = (leftElement == null) ? getType(lhs) : leftElement.type;
|
| Type2 rightType = getType(rhs);
|
| if (!rightType.isAssignableTo(leftType)) {
|
| - _errorReporter.reportError(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [leftType.name, rightType.name]);
|
| + _errorReporter.reportError(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType.name, leftType.name]);
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| + /**
|
| + * Checks to ensure that native function bodies can only in SDK code.
|
| + * @param node the native function body to test
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| + * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
|
| + */
|
| + bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) {
|
| + if (!_isInSystemLibrary) {
|
| + _errorReporter.reportError(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node, []);
|
| return true;
|
| }
|
| return false;
|
| @@ -5961,7 +7535,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * Checks to ensure that the expressions that need to be of type bool, are. Otherwise an error is
|
| * reported on the expression.
|
| * @param condition the conditional expression to test
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see StaticTypeWarningCode#NON_BOOL_CONDITION
|
| */
|
| bool checkForNonBoolCondition(Expression condition) {
|
| @@ -5975,7 +7549,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| /**
|
| * This verifies that the passed assert statement has either a 'bool' or '() -> bool' input.
|
| * @param node the assert statement to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION
|
| */
|
| bool checkForNonBoolExpression(AssertStatement node) {
|
| @@ -5998,7 +7572,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| /**
|
| * This checks that the rethrow is inside of a catch clause.
|
| * @param node the rethrow expression to evaluate
|
| - * @return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH
|
| */
|
| bool checkForRethrowOutsideCatch(RethrowExpression node) {
|
| @@ -6012,17 +7586,17 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * This checks that the return type matches the type of the declared return type in the enclosing
|
| * method or function.
|
| * @param node the return statement to evaluate
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
|
| */
|
| bool checkForReturnOfInvalidType(ReturnStatement node) {
|
| - FunctionType functionType = _currentFunction == null ? null : _currentFunction.type;
|
| + FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
|
| Type2 expectedReturnType = functionType == null ? null : functionType.returnType;
|
| Expression returnExpression = node.expression;
|
| if (expectedReturnType != null && !expectedReturnType.isVoid() && returnExpression != null) {
|
| Type2 actualReturnType = getType(returnExpression);
|
| if (!actualReturnType.isAssignableTo(expectedReturnType)) {
|
| - _errorReporter.reportError(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [actualReturnType.name, expectedReturnType.name]);
|
| + _errorReporter.reportError(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [actualReturnType.name, expectedReturnType.name, _enclosingFunction.name]);
|
| return true;
|
| }
|
| }
|
| @@ -6035,7 +7609,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * @param node the instance creation expression to evaluate
|
| * @param typeName the {@link TypeName} of the {@link ConstructorName} from the{@link InstanceCreationExpression}, this is the AST node that the error is attached to
|
| * @param constructorElement the {@link ConstructorElement} from the instance creation expression
|
| - * @return return <code>true</code> if and only if an error code is generated on the passed node
|
| + * @return return {@code true} if and only if an error code is generated on the passed node
|
| * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
|
| */
|
| bool checkForTypeArgumentNotMatchingBounds(InstanceCreationExpression node, ConstructorElement constructorElement, TypeName typeName) {
|
| @@ -6066,6 +7640,41 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| Type2 type = expression.staticType;
|
| return type == null ? _dynamicType : type;
|
| }
|
| + /**
|
| + * Return the variable element represented by the given expression, or {@code null} if there is no
|
| + * such element.
|
| + * @param expression the expression whose element is to be returned
|
| + * @return the variable element represented by the expression
|
| + */
|
| + VariableElement getVariableElement(Expression expression) {
|
| + if (expression is Identifier) {
|
| + Element element64 = ((expression as Identifier)).element;
|
| + if (element64 is VariableElement) {
|
| + return element64 as VariableElement;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +}
|
| +/**
|
| + * This enum holds one of four states of a field initialization state through a constructor
|
| + * signature, not initialized, initialized in the field declaration, initialized in the field
|
| + * formal, and finally, initialized in the initializers list.
|
| + */
|
| +class INIT_STATE implements Comparable<INIT_STATE> {
|
| + static final INIT_STATE NOT_INIT = new INIT_STATE('NOT_INIT', 0);
|
| + static final INIT_STATE INIT_IN_DECLARATION = new INIT_STATE('INIT_IN_DECLARATION', 1);
|
| + static final INIT_STATE INIT_IN_FIELD_FORMAL = new INIT_STATE('INIT_IN_FIELD_FORMAL', 2);
|
| + static final INIT_STATE INIT_IN_DEFAULT_VALUE = new INIT_STATE('INIT_IN_DEFAULT_VALUE', 3);
|
| + static final INIT_STATE INIT_IN_INITIALIZERS = new INIT_STATE('INIT_IN_INITIALIZERS', 4);
|
| + static final List<INIT_STATE> values = [NOT_INIT, INIT_IN_DECLARATION, INIT_IN_FIELD_FORMAL, INIT_IN_DEFAULT_VALUE, INIT_IN_INITIALIZERS];
|
| + final String __name;
|
| + final int __ordinal;
|
| + int get ordinal => __ordinal;
|
| + INIT_STATE(this.__name, this.__ordinal) {
|
| + }
|
| + int compareTo(INIT_STATE other) => __ordinal - other.__ordinal;
|
| + String toString() => __name;
|
| }
|
| /**
|
| * The enumeration {@code ResolverErrorCode} defines the error codes used for errors detected by the
|
| @@ -6074,13 +7683,11 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * when appropriate, how the problem can be corrected.
|
| * @coverage dart.engine.resolver
|
| */
|
| -class ResolverErrorCode implements ErrorCode {
|
| +class ResolverErrorCode implements Comparable<ResolverErrorCode>, ErrorCode {
|
| static final ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = new ResolverErrorCode('BREAK_LABEL_ON_SWITCH_MEMBER', 0, ErrorType.COMPILE_TIME_ERROR, "Break label resolves to case or default statement");
|
| - static final ResolverErrorCode CANNOT_BE_RESOLVED = new ResolverErrorCode('CANNOT_BE_RESOLVED', 1, ErrorType.STATIC_WARNING, "Cannot resolve the name '%s'");
|
| - static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCode('CONTINUE_LABEL_ON_SWITCH', 2, ErrorType.COMPILE_TIME_ERROR, "A continue label resolves to switch, must be loop or switch member");
|
| - static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new ResolverErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 3, ErrorType.COMPILE_TIME_ERROR, "Libraries that have parts must have a library directive");
|
| - static final ResolverErrorCode MISSING_PART_OF_DIRECTIVE = new ResolverErrorCode('MISSING_PART_OF_DIRECTIVE', 4, ErrorType.COMPILE_TIME_ERROR, "The included part must have a part-of directive");
|
| - static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, CANNOT_BE_RESOLVED, CONTINUE_LABEL_ON_SWITCH, MISSING_LIBRARY_DIRECTIVE_WITH_PART, MISSING_PART_OF_DIRECTIVE];
|
| + static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCode('CONTINUE_LABEL_ON_SWITCH', 1, ErrorType.COMPILE_TIME_ERROR, "A continue label resolves to switch, must be loop or switch member");
|
| + static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new ResolverErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 2, ErrorType.COMPILE_TIME_ERROR, "Libraries that have parts must have a library directive");
|
| + static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, CONTINUE_LABEL_ON_SWITCH, MISSING_LIBRARY_DIRECTIVE_WITH_PART];
|
| final String __name;
|
| final int __ordinal;
|
| int get ordinal => __ordinal;
|
| @@ -6105,5 +7712,6 @@ class ResolverErrorCode implements ErrorCode {
|
| String get message => _message;
|
| ErrorType get type => _type;
|
| bool needsRecompilation() => true;
|
| + int compareTo(ResolverErrorCode other) => __ordinal - other.__ordinal;
|
| String toString() => __name;
|
| }
|
|
|