| 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 2b056f4fb0cc30321c426187bce518ed4102dd63..339a518ca6c59f0291059384e00a9b12951dff75 100644
|
| --- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| +++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| @@ -602,7 +602,7 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
|
| if (element is PropertyInducingElementImpl) {
|
| PropertyInducingElementImpl variable = element as PropertyInducingElementImpl;
|
| if (_inFieldContext) {
|
| - ((variable as FieldElementImpl)).static = matches(((node.parent.parent as FieldDeclaration)).keyword, sc.Keyword.STATIC);
|
| + ((variable as FieldElementImpl)).static = matches(((node.parent.parent as FieldDeclaration)).staticKeyword, sc.Keyword.STATIC);
|
| }
|
| PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(variable);
|
| getter.getter = true;
|
| @@ -1031,6 +1031,11 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| RecordingErrorListener _errorListener;
|
|
|
| /**
|
| + * The modification time of the source for which an element is being built.
|
| + */
|
| + int _modificationStamp = 0;
|
| +
|
| + /**
|
| * The line information associated with the source for which an element is being built, or
|
| * `null` if we are not building an element.
|
| */
|
| @@ -1073,16 +1078,19 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| * @return the HTML element that was built
|
| * @throws AnalysisException if the analysis could not be performed
|
| */
|
| - HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, _context.parseHtmlUnit(source));
|
| + HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, source.modificationStamp, _context.parseHtmlUnit(source));
|
|
|
| /**
|
| * Build the HTML element for the given source.
|
| *
|
| * @param source the source describing the compilation unit
|
| + * @param modificationStamp the modification time of the source for which an element is being
|
| + * built
|
| * @param unit the AST structure representing the HTML
|
| * @throws AnalysisException if the analysis could not be performed
|
| */
|
| - HtmlElementImpl buildHtmlElement2(Source source2, ht.HtmlUnit unit) {
|
| + HtmlElementImpl buildHtmlElement2(Source source2, int modificationStamp2, ht.HtmlUnit unit) {
|
| + this._modificationStamp = modificationStamp2;
|
| _lineInfo = _context.computeLineInfo(source2);
|
| HtmlElementImpl result = new HtmlElementImpl(_context, source2.shortName);
|
| result.source = source2;
|
| @@ -1162,7 +1170,7 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| unit.lineInfo = new LineInfo(lineStarts);
|
| try {
|
| LibraryResolver resolver = new LibraryResolver(_context);
|
| - LibraryElementImpl library = resolver.resolveEmbeddedLibrary(htmlSource, unit, true) as LibraryElementImpl;
|
| + LibraryElementImpl library = resolver.resolveEmbeddedLibrary(htmlSource, _modificationStamp, unit, true) as LibraryElementImpl;
|
| script.scriptLibrary = library;
|
| _resolvedLibraries.addAll(resolver.resolvedLibraries);
|
| _errorListener.addAll(resolver.errorListener);
|
| @@ -1174,14 +1182,15 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl(node);
|
| if (scriptSourcePath != null) {
|
| try {
|
| + scriptSourcePath = Uri.encodeFull(scriptSourcePath);
|
| parseUriWithException(scriptSourcePath);
|
| Source scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
|
| script.scriptSource = scriptSource;
|
| - if (!scriptSource.exists()) {
|
| - reportError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribute.offset + 1, scriptSourcePath.length, [scriptSourcePath]);
|
| + if (scriptSource == null || !scriptSource.exists()) {
|
| + reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribute, [scriptSourcePath]);
|
| }
|
| } on URISyntaxException catch (exception) {
|
| - reportError(HtmlWarningCode.INVALID_URI, scriptAttribute.offset + 1, scriptSourcePath.length, [scriptSourcePath]);
|
| + reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, [scriptSourcePath]);
|
| }
|
| }
|
| _scripts.add(script);
|
| @@ -1246,6 +1255,21 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
|
| void reportError(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
|
| _errorListener.onError(new AnalysisError.con2(_htmlElement.source, offset, length, errorCode, arguments));
|
| }
|
| +
|
| + /**
|
| + * Report an error with the given error code at the location of the value of the given attribute.
|
| + * Use the given arguments to compose the error message.
|
| + *
|
| + * @param errorCode the error code of the error to be reported
|
| + * @param offset the offset of the first character to be highlighted
|
| + * @param length the number of characters to be highlighted
|
| + * @param arguments the arguments used to compose the error message
|
| + */
|
| + void reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute, List<Object> arguments) {
|
| + int offset = attribute.value.offset + 1;
|
| + int length = attribute.value.length - 2;
|
| + reportError(errorCode, offset, length, arguments);
|
| + }
|
| }
|
| /**
|
| * Instances of the class `DeadCodeVerifier` traverse an AST structure looking for cases of
|
| @@ -1350,7 +1374,7 @@ class DeadCodeVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| Object visitTryStatement(TryStatement node) {
|
| safelyVisit(node.body);
|
| - safelyVisit(node.finallyClause);
|
| + safelyVisit(node.finallyBlock);
|
| NodeList<CatchClause> catchClauses = node.catchClauses;
|
| int numOfCatchClauses = catchClauses.length;
|
| List<Type2> visitedTypes = new List<Type2>();
|
| @@ -1602,7 +1626,7 @@ class ImportsVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| }
|
| putIntoLibraryMap(libraryElement, importDirective);
|
| - addAdditionalLibrariesForExports(_libraryMap, libraryElement, importDirective, new List<LibraryElement>());
|
| + addAdditionalLibrariesForExports(libraryElement, importDirective, new List<LibraryElement>());
|
| }
|
| }
|
| }
|
| @@ -1632,14 +1656,14 @@ class ImportsVerifier extends RecursiveASTVisitor<Object> {
|
| /**
|
| * Recursively add any exported library elements into the [libraryMap].
|
| */
|
| - void addAdditionalLibrariesForExports(Map<LibraryElement, List<ImportDirective>> map, LibraryElement library, ImportDirective importDirective, List<LibraryElement> exportPath) {
|
| + void addAdditionalLibrariesForExports(LibraryElement library, ImportDirective importDirective, List<LibraryElement> exportPath) {
|
| if (exportPath.contains(library)) {
|
| return;
|
| }
|
| + exportPath.add(library);
|
| for (LibraryElement exportedLibraryElt in library.exportedLibraries) {
|
| putIntoLibraryMap(exportedLibraryElt, importDirective);
|
| - exportPath.add(exportedLibraryElt);
|
| - addAdditionalLibrariesForExports(map, exportedLibraryElt, importDirective, exportPath);
|
| + addAdditionalLibrariesForExports(exportedLibraryElt, importDirective, exportPath);
|
| }
|
| }
|
|
|
| @@ -1762,7 +1786,7 @@ class PubVerifier extends RecursiveASTVisitor<Object> {
|
| if (JavaString.startsWithBefore(fullName, "/lib", fullNameIndex - 4)) {
|
| String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSPEC_YAML;
|
| Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePubspecPath);
|
| - if (pubspecSource.exists()) {
|
| + if (pubspecSource != null && pubspecSource.exists()) {
|
| _errorReporter.reportError2(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE, uriLiteral, []);
|
| }
|
| return true;
|
| @@ -1802,7 +1826,7 @@ class PubVerifier extends RecursiveASTVisitor<Object> {
|
| Source source = getSource(uriLiteral);
|
| String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML;
|
| Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePubspecPath);
|
| - if (!pubspecSource.exists()) {
|
| + if (pubspecSource == null || !pubspecSource.exists()) {
|
| return false;
|
| }
|
| String fullName = getSourceFullName(source);
|
| @@ -2499,6 +2523,16 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| bool _strictMode = false;
|
|
|
| /**
|
| + * The type representing the type 'dynamic'.
|
| + */
|
| + Type2 _dynamicType;
|
| +
|
| + /**
|
| + * The type representing the type 'type'.
|
| + */
|
| + Type2 _typeType;
|
| +
|
| + /**
|
| * The name of the method that can be implemented by a class to allow its instances to be invoked
|
| * as if they were a function.
|
| */
|
| @@ -2518,6 +2552,8 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| ElementResolver(ResolverVisitor resolver) {
|
| this._resolver = resolver;
|
| _strictMode = resolver.definingLibrary.context.analysisOptions.strictMode;
|
| + _dynamicType = resolver.typeProvider.dynamicType;
|
| + _typeType = resolver.typeProvider.typeType;
|
| }
|
| Object visitAssignmentExpression(AssignmentExpression node) {
|
| sc.Token operator = node.operator;
|
| @@ -2868,8 +2904,8 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| ErrorCode errorCode = checkForInvocationError(target, staticElement);
|
| if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
|
| _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
|
| - } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
|
| - _resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName, [methodName.name]);
|
| + } else if (identical(errorCode, CompileTimeErrorCode.UNDEFINED_FUNCTION)) {
|
| + _resolver.reportError(CompileTimeErrorCode.UNDEFINED_FUNCTION, methodName, [methodName.name]);
|
| } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
|
| String targetTypeName;
|
| if (target == null) {
|
| @@ -3007,6 +3043,11 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| if (node.staticElement != null || node.element != null) {
|
| return null;
|
| }
|
| + if (node.name == _dynamicType.name) {
|
| + recordResolution(node, _dynamicType.element);
|
| + node.staticType = _typeType;
|
| + return null;
|
| + }
|
| Element element = resolveSimpleIdentifier(node);
|
| if (isFactoryConstructorReturnType(node) && element != _resolver.enclosingClass) {
|
| _resolver.reportError(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node, []);
|
| @@ -3111,6 +3152,9 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| * @return the error code that should be reported
|
| */
|
| ErrorCode checkForInvocationError(Expression target, Element element) {
|
| + if (element is PrefixElement) {
|
| + element = null;
|
| + }
|
| if (element is PropertyAccessorElement) {
|
| FunctionType getterType = ((element as PropertyAccessorElement)).type;
|
| if (getterType != null) {
|
| @@ -3141,17 +3185,19 @@ class ElementResolver extends SimpleASTVisitor<Object> {
|
| } else {
|
| if (target == null) {
|
| ClassElement enclosingClass = _resolver.enclosingClass;
|
| - if (enclosingClass == null) {
|
| - return StaticTypeWarningCode.UNDEFINED_FUNCTION;
|
| - } else if (element == null) {
|
| - return StaticTypeWarningCode.UNDEFINED_METHOD;
|
| + if (element == null) {
|
| + if (enclosingClass == null) {
|
| + return CompileTimeErrorCode.UNDEFINED_FUNCTION;
|
| + } else {
|
| + return StaticTypeWarningCode.UNDEFINED_METHOD;
|
| + }
|
| } else {
|
| return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
|
| }
|
| } else {
|
| Type2 targetType = getStaticType(target);
|
| if (targetType == null) {
|
| - return StaticTypeWarningCode.UNDEFINED_FUNCTION;
|
| + return CompileTimeErrorCode.UNDEFINED_FUNCTION;
|
| } else if (!targetType.isDynamic) {
|
| return StaticTypeWarningCode.UNDEFINED_METHOD;
|
| }
|
| @@ -4448,14 +4494,11 @@ class InheritanceManager {
|
| _classLookup[superclassElt] = resultMap;
|
| return resultMap;
|
| }
|
| - recordMapWithClassMembers(resultMap, superclassElt);
|
| + recordMapWithClassMembers(resultMap, supertype);
|
| }
|
| List<InterfaceType> mixins = classElt.mixins;
|
| for (int i = mixins.length - 1; i >= 0; i--) {
|
| - ClassElement mixinElement = mixins[i].element;
|
| - if (mixinElement != null) {
|
| - recordMapWithClassMembers(resultMap, mixinElement);
|
| - }
|
| + recordMapWithClassMembers(resultMap, mixins[i]);
|
| }
|
| _classLookup[classElt] = resultMap;
|
| return resultMap;
|
| @@ -4530,16 +4573,26 @@ class InheritanceManager {
|
| ClassElement superclassElement = supertype != null ? supertype.element : null;
|
| List<InterfaceType> mixins = classElt.mixins;
|
| List<InterfaceType> interfaces = classElt.interfaces;
|
| - if ((superclassElement == null || supertype.isObject) && mixins.length == 0 && interfaces.length == 0) {
|
| - _interfaceLookup[classElt] = resultMap;
|
| - return resultMap;
|
| - }
|
| List<Map<String, ExecutableElement>> lookupMaps = new List<Map<String, ExecutableElement>>();
|
| if (superclassElement != null) {
|
| if (!visitedInterfaces.contains(superclassElement)) {
|
| try {
|
| javaSetAdd(visitedInterfaces, superclassElement);
|
| - lookupMaps.add(computeInterfaceLookupMap(superclassElement, visitedInterfaces));
|
| + Map<String, ExecutableElement> map = computeInterfaceLookupMap(superclassElement, visitedInterfaces);
|
| + map = new Map<String, ExecutableElement>.from(map);
|
| + List<MethodElement> methods = supertype.methods;
|
| + for (MethodElement method in methods) {
|
| + if (method.isAccessibleIn(_library) && !method.isStatic) {
|
| + map[method.name] = method;
|
| + }
|
| + }
|
| + List<PropertyAccessorElement> accessors = supertype.accessors;
|
| + for (PropertyAccessorElement accessor in accessors) {
|
| + if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
|
| + map[accessor.name] = accessor;
|
| + }
|
| + }
|
| + lookupMaps.add(map);
|
| } finally {
|
| visitedInterfaces.remove(superclassElement);
|
| }
|
| @@ -4554,12 +4607,8 @@ class InheritanceManager {
|
| }
|
| }
|
| for (InterfaceType mixinType in mixins) {
|
| - ClassElement mixinElement = mixinType.element;
|
| - if (mixinElement == null) {
|
| - continue;
|
| - }
|
| Map<String, ExecutableElement> mapWithMixinMembers = new Map<String, ExecutableElement>();
|
| - recordMapWithClassMembers(mapWithMixinMembers, mixinElement);
|
| + recordMapWithClassMembers(mapWithMixinMembers, mixinType);
|
| lookupMaps.add(mapWithMixinMembers);
|
| }
|
| for (InterfaceType interfaceType in interfaces) {
|
| @@ -4568,7 +4617,21 @@ class InheritanceManager {
|
| if (!visitedInterfaces.contains(interfaceElement)) {
|
| try {
|
| javaSetAdd(visitedInterfaces, interfaceElement);
|
| - lookupMaps.add(computeInterfaceLookupMap(interfaceElement, visitedInterfaces));
|
| + Map<String, ExecutableElement> map = computeInterfaceLookupMap(interfaceElement, visitedInterfaces);
|
| + map = new Map<String, ExecutableElement>.from(map);
|
| + List<MethodElement> methods = interfaceType.methods;
|
| + for (MethodElement method in methods) {
|
| + if (method.isAccessibleIn(_library) && !method.isStatic) {
|
| + map[method.name] = method;
|
| + }
|
| + }
|
| + List<PropertyAccessorElement> accessors = interfaceType.accessors;
|
| + for (PropertyAccessorElement accessor in accessors) {
|
| + if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
|
| + map[accessor.name] = accessor;
|
| + }
|
| + }
|
| + lookupMaps.add(map);
|
| } finally {
|
| visitedInterfaces.remove(interfaceElement);
|
| }
|
| @@ -4591,72 +4654,12 @@ class InheritanceManager {
|
| for (Map<String, ExecutableElement> lookupMap in lookupMaps) {
|
| for (MapEntry<String, ExecutableElement> entry in getMapEntrySet(lookupMap)) {
|
| String key = entry.getKey();
|
| - if (!unionMap.containsKey(key)) {
|
| - Set<ExecutableElement> set = new Set<ExecutableElement>();
|
| - javaSetAdd(set, entry.getValue());
|
| + Set<ExecutableElement> set = unionMap[key];
|
| + if (set == null) {
|
| + set = new Set<ExecutableElement>();
|
| unionMap[key] = set;
|
| - } else {
|
| - javaSetAdd(unionMap[key], entry.getValue());
|
| - }
|
| - }
|
| - }
|
| - if (superclassElement != null) {
|
| - List<MethodElement> methods = superclassElement.methods;
|
| - for (MethodElement method in methods) {
|
| - if (method.isAccessibleIn(_library) && !method.isStatic) {
|
| - String key = method.name;
|
| - if (!unionMap.containsKey(key)) {
|
| - Set<ExecutableElement> set = new Set<ExecutableElement>();
|
| - javaSetAdd(set, method);
|
| - unionMap[key] = set;
|
| - } else {
|
| - javaSetAdd(unionMap[key], method);
|
| - }
|
| - }
|
| - }
|
| - List<PropertyAccessorElement> accessors = superclassElement.accessors;
|
| - for (PropertyAccessorElement accessor in accessors) {
|
| - if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
|
| - String key = accessor.name;
|
| - if (!unionMap.containsKey(key)) {
|
| - Set<ExecutableElement> set = new Set<ExecutableElement>();
|
| - javaSetAdd(set, accessor);
|
| - unionMap[key] = set;
|
| - } else {
|
| - javaSetAdd(unionMap[key], accessor);
|
| - }
|
| - }
|
| - }
|
| - }
|
| - for (InterfaceType interfaceType in interfaces) {
|
| - ClassElement interfaceElement = interfaceType.element;
|
| - if (interfaceElement != null) {
|
| - List<MethodElement> methods = interfaceElement.methods;
|
| - for (MethodElement method in methods) {
|
| - if (method.isAccessibleIn(_library) && !method.isStatic) {
|
| - String key = method.name;
|
| - if (!unionMap.containsKey(key)) {
|
| - Set<ExecutableElement> set = new Set<ExecutableElement>();
|
| - javaSetAdd(set, method);
|
| - unionMap[key] = set;
|
| - } else {
|
| - javaSetAdd(unionMap[key], method);
|
| - }
|
| - }
|
| - }
|
| - List<PropertyAccessorElement> accessors = interfaceElement.accessors;
|
| - for (PropertyAccessorElement accessor in accessors) {
|
| - if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
|
| - String key = accessor.name;
|
| - if (!unionMap.containsKey(key)) {
|
| - Set<ExecutableElement> set = new Set<ExecutableElement>();
|
| - javaSetAdd(set, accessor);
|
| - unionMap[key] = set;
|
| - } else {
|
| - javaSetAdd(unionMap[key], accessor);
|
| - }
|
| - }
|
| }
|
| + javaSetAdd(set, entry.getValue());
|
| }
|
| }
|
| for (MapEntry<String, Set<ExecutableElement>> entry in getMapEntrySet(unionMap)) {
|
| @@ -4750,21 +4753,21 @@ class InheritanceManager {
|
| }
|
|
|
| /**
|
| - * Record the passed map with the set of all members (methods, getters and setters) in the class
|
| + * Record the passed map with the set of all members (methods, getters and setters) in the type
|
| * into the passed map.
|
| *
|
| * @param map some non-`null` map to put the methods and accessors from the passed
|
| * [ClassElement] into
|
| - * @param classElt the class element that will be recorded into the passed map
|
| + * @param type the type that will be recorded into the passed map
|
| */
|
| - void recordMapWithClassMembers(Map<String, ExecutableElement> map, ClassElement classElt) {
|
| - List<MethodElement> methods = classElt.methods;
|
| + void recordMapWithClassMembers(Map<String, ExecutableElement> map, InterfaceType type) {
|
| + List<MethodElement> methods = type.methods;
|
| for (MethodElement method in methods) {
|
| if (method.isAccessibleIn(_library) && !method.isStatic) {
|
| map[method.name] = method;
|
| }
|
| }
|
| - List<PropertyAccessorElement> accessors = classElt.accessors;
|
| + List<PropertyAccessorElement> accessors = type.accessors;
|
| for (PropertyAccessorElement accessor in accessors) {
|
| if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
|
| map[accessor.name] = accessor;
|
| @@ -4850,7 +4853,7 @@ class Library {
|
| * A table mapping the sources for the compilation units in this library to their corresponding
|
| * AST structures.
|
| */
|
| - Map<Source, CompilationUnit> _astMap = new Map<Source, CompilationUnit>();
|
| + Map<Source, ResolvableCompilationUnit> _astMap = new Map<Source, ResolvableCompilationUnit>();
|
|
|
| /**
|
| * The library scope used when resolving elements within this library's compilation units.
|
| @@ -4884,12 +4887,12 @@ class Library {
|
| * @throws AnalysisException if an AST structure could not be created for the compilation unit
|
| */
|
| CompilationUnit getAST(Source source) {
|
| - CompilationUnit unit = _astMap[source];
|
| - if (unit == null) {
|
| - unit = _analysisContext.computeResolvableCompilationUnit(source);
|
| - _astMap[source] = unit;
|
| + ResolvableCompilationUnit holder = _astMap[source];
|
| + if (holder == null) {
|
| + holder = _analysisContext.computeResolvableCompilationUnit(source);
|
| + _astMap[source] = holder;
|
| }
|
| - return unit;
|
| + return holder.compilationUnit;
|
| }
|
|
|
| /**
|
| @@ -5013,6 +5016,22 @@ class Library {
|
| Source get librarySource => _librarySource;
|
|
|
| /**
|
| + * Return the modification stamp associated with the given source.
|
| + *
|
| + * @param source the source representing the compilation unit whose AST is to be returned
|
| + * @return the AST structure associated with the given source
|
| + * @throws AnalysisException if an AST structure could not be created for the compilation unit
|
| + */
|
| + int getModificationStamp(Source source) {
|
| + ResolvableCompilationUnit holder = _astMap[source];
|
| + if (holder == null) {
|
| + holder = _analysisContext.computeResolvableCompilationUnit(source);
|
| + _astMap[source] = holder;
|
| + }
|
| + return holder.modificationStamp;
|
| + }
|
| +
|
| + /**
|
| * Return the result of resolving the URI of the given URI-based directive against the URI of the
|
| * library, or `null` if the URI is not valid. If the URI is not valid, report the error.
|
| *
|
| @@ -5030,7 +5049,7 @@ class Library {
|
| uriContent = Uri.encodeFull(uriContent);
|
| try {
|
| parseUriWithException(uriContent);
|
| - Source source = getSource2(uriContent);
|
| + Source source = _analysisContext.sourceFactory.resolveUri(_librarySource, uriContent);
|
| if (source == null || !source.exists()) {
|
| _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent]));
|
| }
|
| @@ -5050,10 +5069,12 @@ class Library {
|
| * Set the AST structure associated with the defining compilation unit for this library to the
|
| * given AST structure.
|
| *
|
| + * @param modificationStamp the modification time of the source from which the compilation unit
|
| + * was created
|
| * @param unit the AST structure associated with the defining compilation unit for this library
|
| */
|
| - void set definingCompilationUnit(CompilationUnit unit) {
|
| - _astMap[_librarySource] = unit;
|
| + void setDefiningCompilationUnit(int modificationStamp, CompilationUnit unit) {
|
| + _astMap[_librarySource] = new ResolvableCompilationUnit(modificationStamp, unit);
|
| }
|
|
|
| /**
|
| @@ -5095,20 +5116,6 @@ class Library {
|
| }
|
| }
|
| String toString() => _librarySource.shortName;
|
| -
|
| - /**
|
| - * Return the result of resolving the given URI against the URI of the library, or `null` if
|
| - * the URI is not valid.
|
| - *
|
| - * @param uri the URI to be resolved
|
| - * @return the result of resolving the given URI against the URI of the library
|
| - */
|
| - Source getSource2(String uri) {
|
| - if (uri == null) {
|
| - return null;
|
| - }
|
| - return _analysisContext.sourceFactory.resolveUri(_librarySource, uri);
|
| - }
|
| }
|
| /**
|
| * Instances of the class `LibraryElementBuilder` build an element model for a single library.
|
| @@ -5388,17 +5395,19 @@ class LibraryResolver {
|
| *
|
| * @param librarySource the source specifying the defining compilation unit of the library to be
|
| * resolved
|
| + * @param modificationStamp the time stamp of the source from which the compilation unit was
|
| + * created
|
| * @param unit the compilation unit representing the embedded library
|
| * @param fullAnalysis `true` if a full analysis should be performed
|
| * @return the element representing the resolved library
|
| * @throws AnalysisException if the library could not be resolved for some reason
|
| */
|
| - LibraryElement resolveEmbeddedLibrary(Source librarySource, CompilationUnit unit, bool fullAnalysis) {
|
| + LibraryElement resolveEmbeddedLibrary(Source librarySource, int modificationStamp, CompilationUnit unit, bool fullAnalysis) {
|
| InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.LibraryResolver.resolveEmbeddedLibrary");
|
| try {
|
| instrumentation.metric("fullAnalysis", fullAnalysis);
|
| instrumentation.data3("fullName", librarySource.fullName);
|
| - Library targetLibrary = createLibrary2(librarySource, unit);
|
| + Library targetLibrary = createLibrary2(librarySource, modificationStamp, unit);
|
| _coreLibrary = _libraryMap[_coreLibrarySource];
|
| if (_coreLibrary == null) {
|
| _coreLibrary = createLibrary(_coreLibrarySource);
|
| @@ -5820,12 +5829,15 @@ class LibraryResolver {
|
| * with the given source.
|
| *
|
| * @param librarySource the source of the library's defining compilation unit
|
| + * @param modificationStamp the modification time of the source from which the compilation unit
|
| + * was created
|
| + * @param unit the compilation unit that defines the library
|
| * @return the library object that was created
|
| * @throws AnalysisException if the library source is not valid
|
| */
|
| - Library createLibrary2(Source librarySource, CompilationUnit unit) {
|
| + Library createLibrary2(Source librarySource, int modificationStamp, CompilationUnit unit) {
|
| Library library = new Library(_analysisContext, _errorListener, librarySource);
|
| - library.definingCompilationUnit = unit;
|
| + library.setDefiningCompilationUnit(modificationStamp, unit);
|
| _libraryMap[librarySource] = library;
|
| return library;
|
| }
|
| @@ -5943,16 +5955,11 @@ class LibraryResolver {
|
| return null;
|
| }
|
| String uriContent = uriLiteral.stringValue.trim();
|
| - if (uriContent == null) {
|
| + if (uriContent == null || uriContent.isEmpty) {
|
| return null;
|
| }
|
| uriContent = Uri.encodeFull(uriContent);
|
| - try {
|
| - parseUriWithException(uriContent);
|
| - return _analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
|
| - } on URISyntaxException catch (exception) {
|
| - return null;
|
| - }
|
| + return _analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
|
| }
|
|
|
| /**
|
| @@ -6852,7 +6859,9 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
|
| Object visitBlock(Block node) {
|
| Scope outerScope = _nameScope;
|
| try {
|
| - _nameScope = new EnclosedScope(_nameScope);
|
| + EnclosedScope enclosedScope = new EnclosedScope(_nameScope);
|
| + hideNamesDefinedInBlock(enclosedScope, node);
|
| + _nameScope = enclosedScope;
|
| super.visitBlock(node);
|
| } finally {
|
| _nameScope = outerScope;
|
| @@ -7202,6 +7211,28 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
|
| }
|
| return outerScope;
|
| }
|
| +
|
| + /**
|
| + * Marks the local declarations of the given [Block] hidden in the enclosing scope.
|
| + * According to the scoping rules name is hidden if block defines it, but name is defined after
|
| + * its declaration statement.
|
| + */
|
| + void hideNamesDefinedInBlock(EnclosedScope scope, Block block) {
|
| + for (Statement statement in block.statements) {
|
| + if (statement is VariableDeclarationStatement) {
|
| + VariableDeclarationStatement vds = statement as VariableDeclarationStatement;
|
| + for (VariableDeclaration variableDeclaration in vds.variables.variables) {
|
| + Element element = variableDeclaration.element;
|
| + scope.hide(element);
|
| + }
|
| + }
|
| + if (statement is FunctionDeclarationStatement) {
|
| + FunctionDeclarationStatement fds = statement as FunctionDeclarationStatement;
|
| + Element element = fds.functionDeclaration.element;
|
| + scope.hide(element);
|
| + }
|
| + }
|
| + }
|
| }
|
| /**
|
| * Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
|
| @@ -8966,6 +8997,13 @@ class TypeOverrideManager_TypeOverrideScope {
|
| abstract class TypeProvider {
|
|
|
| /**
|
| + * Return the type representing the built-in type 'Null'.
|
| + *
|
| + * @return the type representing the built-in type 'null'
|
| + */
|
| + InterfaceType get nullType;
|
| +
|
| + /**
|
| * Return the type representing the built-in type 'bool'.
|
| *
|
| * @return the type representing the built-in type 'bool'
|
| @@ -9112,6 +9150,11 @@ class TypeProviderImpl implements TypeProvider {
|
| InterfaceType _mapType;
|
|
|
| /**
|
| + * The type representing the type 'Null'.
|
| + */
|
| + InterfaceType _nullType;
|
| +
|
| + /**
|
| * The type representing the built-in type 'num'.
|
| */
|
| InterfaceType _numType;
|
| @@ -9157,6 +9200,7 @@ class TypeProviderImpl implements TypeProvider {
|
| InterfaceType get intType => _intType;
|
| InterfaceType get listType => _listType;
|
| InterfaceType get mapType => _mapType;
|
| + InterfaceType get nullType => _nullType;
|
| InterfaceType get numType => _numType;
|
| InterfaceType get objectType => _objectType;
|
| InterfaceType get stackTraceType => _stackTraceType;
|
| @@ -9196,6 +9240,7 @@ class TypeProviderImpl implements TypeProvider {
|
| _intType = getType(namespace, "int");
|
| _listType = getType(namespace, "List");
|
| _mapType = getType(namespace, "Map");
|
| + _nullType = getType(namespace, "Null");
|
| _numType = getType(namespace, "num");
|
| _objectType = getType(namespace, "Object");
|
| _stackTraceType = getType(namespace, "StackTrace");
|
| @@ -10105,6 +10150,13 @@ class EnclosedScope extends Scope {
|
| Scope _enclosingScope;
|
|
|
| /**
|
| + * A set of names that will be defined in this scope, but right now are not defined. However
|
| + * according to the scoping rules these names are hidden, even if they were defined in an outer
|
| + * scope.
|
| + */
|
| + Set<String> _hiddenNames = new Set<String>();
|
| +
|
| + /**
|
| * Initialize a newly created scope enclosed within another scope.
|
| *
|
| * @param enclosingScope the scope in which this scope is lexically enclosed
|
| @@ -10116,6 +10168,21 @@ class EnclosedScope extends Scope {
|
| AnalysisErrorListener get errorListener => _enclosingScope.errorListener;
|
|
|
| /**
|
| + * Hides the name of the given element in this scope. If there is already an element with the
|
| + * given name defined in an outer scope, then it will become unavailable.
|
| + *
|
| + * @param element the element to be hidden in this scope
|
| + */
|
| + void hide(Element element) {
|
| + if (element != null) {
|
| + String name = element.name;
|
| + if (name != null && !name.isEmpty) {
|
| + javaSetAdd(_hiddenNames, name);
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| * Return the scope in which this scope is lexically enclosed.
|
| *
|
| * @return the scope in which this scope is lexically enclosed
|
| @@ -10126,6 +10193,9 @@ class EnclosedScope extends Scope {
|
| if (element != null) {
|
| return element;
|
| }
|
| + if (_hiddenNames.contains(name)) {
|
| + return null;
|
| + }
|
| return _enclosingScope.lookup3(identifier, name, referencingLibrary);
|
| }
|
| }
|
| @@ -10973,7 +11043,7 @@ class ConstantVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| Object visitListLiteral(ListLiteral node) {
|
| super.visitListLiteral(node);
|
| - if (node.modifier != null) {
|
| + if (node.constKeyword != null) {
|
| for (Expression element in node.elements) {
|
| validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT);
|
| }
|
| @@ -10982,7 +11052,7 @@ class ConstantVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| Object visitMapLiteral(MapLiteral node) {
|
| super.visitMapLiteral(node);
|
| - bool isConst = node.modifier != null;
|
| + bool isConst = node.constKeyword != null;
|
| bool reportEqualKeys = true;
|
| Set<Object> keys = new Set<Object>();
|
| List<Expression> invalidKeys = new List<Expression>();
|
| @@ -11300,6 +11370,12 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
|
|
| /**
|
| * This is set to `true` iff the visitor is currently visiting children nodes of an
|
| + * [Comment].
|
| + */
|
| + bool _isInComment = false;
|
| +
|
| + /**
|
| + * This is set to `true` iff the visitor is currently visiting children nodes of an
|
| * [InstanceCreationExpression].
|
| */
|
| bool _isInConstInstanceCreation = false;
|
| @@ -11335,6 +11411,12 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| bool _isInConstructorInitializer = false;
|
|
|
| /**
|
| + * This is set to `true` iff the visitor is currently visiting a
|
| + * [FunctionTypedFormalParameter].
|
| + */
|
| + bool _isInFunctionTypedFormalParameter = false;
|
| +
|
| + /**
|
| * This is set to `true` iff the visitor is currently visiting a static method. By "method"
|
| * here getter, setter and operator declarations are also implied since they are all represented
|
| * with a [MethodDeclaration] in the AST structure.
|
| @@ -11415,6 +11497,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| _isInStaticMethod = false;
|
| _dynamicType = typeProvider.dynamicType;
|
| _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [
|
| + typeProvider.nullType,
|
| typeProvider.numType,
|
| typeProvider.intType,
|
| typeProvider.doubleType,
|
| @@ -11511,6 +11594,14 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| return super.visitClassTypeAlias(node);
|
| }
|
| + Object visitComment(Comment node) {
|
| + _isInComment = true;
|
| + try {
|
| + return super.visitComment(node);
|
| + } finally {
|
| + _isInComment = false;
|
| + }
|
| + }
|
| Object visitConditionalExpression(ConditionalExpression node) {
|
| checkForNonBoolCondition(node.condition);
|
| return super.visitConditionalExpression(node);
|
| @@ -11521,13 +11612,15 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| _enclosingFunction = node.element;
|
| _isEnclosingConstructorConst = node.constKeyword != null;
|
| checkForConstConstructorWithNonFinalField(node);
|
| + checkForConstConstructorWithNonConstSuper(node);
|
| checkForConflictingConstructorNameAndMember(node);
|
| checkForAllFinalInitializedErrorCodes(node);
|
| checkForRedirectingConstructorErrorCodes(node);
|
| checkForMultipleSuperInitializers(node);
|
| checkForRecursiveConstructorRedirect(node);
|
| - checkForRecursiveFactoryRedirect(node);
|
| - checkForAllRedirectConstructorErrorCodes(node);
|
| + if (!checkForRecursiveFactoryRedirect(node)) {
|
| + checkForAllRedirectConstructorErrorCodes(node);
|
| + }
|
| checkForUndefinedConstructorInInitializerImplicit(node);
|
| checkForRedirectToNonConstConstructor(node);
|
| checkForReturnInGenerativeConstructor(node);
|
| @@ -11546,6 +11639,11 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| _isInConstructorInitializer = false;
|
| }
|
| }
|
| + Object visitDefaultFormalParameter(DefaultFormalParameter node) {
|
| + checkForInvalidAssignment2(node.identifier, node.defaultValue);
|
| + checkForDefaultValueInFunctionTypedParameter(node);
|
| + return super.visitDefaultFormalParameter(node);
|
| + }
|
| Object visitDoStatement(DoStatement node) {
|
| checkForNonBoolCondition(node.condition);
|
| return super.visitDoStatement(node);
|
| @@ -11629,6 +11727,15 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| checkForTypeAliasCannotReferenceItself_function(node);
|
| return super.visitFunctionTypeAlias(node);
|
| }
|
| + Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
|
| + bool old = _isInFunctionTypedFormalParameter;
|
| + _isInFunctionTypedFormalParameter = true;
|
| + try {
|
| + return super.visitFunctionTypedFormalParameter(node);
|
| + } finally {
|
| + _isInFunctionTypedFormalParameter = old;
|
| + }
|
| + }
|
| Object visitIfStatement(IfStatement node) {
|
| checkForNonBoolCondition(node.condition);
|
| return super.visitIfStatement(node);
|
| @@ -11665,7 +11772,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| }
|
| Object visitListLiteral(ListLiteral node) {
|
| - if (node.modifier != null) {
|
| + if (node.constKeyword != null) {
|
| TypeArgumentList typeArguments = node.typeArguments;
|
| if (typeArguments != null) {
|
| NodeList<TypeName> arguments = typeArguments.arguments;
|
| @@ -11683,7 +11790,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| NodeList<TypeName> arguments = typeArguments.arguments;
|
| if (arguments.length != 0) {
|
| checkForInvalidTypeArgumentForKey(arguments);
|
| - if (node.modifier != null) {
|
| + if (node.constKeyword != null) {
|
| checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
|
| }
|
| }
|
| @@ -11726,7 +11833,10 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| }
|
| Object visitMethodInvocation(MethodInvocation node) {
|
| - checkForStaticAccessToInstanceMember(node.target, node.methodName);
|
| + Expression target = node.realTarget;
|
| + SimpleIdentifier methodName = node.methodName;
|
| + checkForStaticAccessToInstanceMember(target, methodName);
|
| + checkForInstanceAccessToStaticMember(target, methodName);
|
| return super.visitMethodInvocation(node);
|
| }
|
| Object visitNativeClause(NativeClause node) {
|
| @@ -11747,6 +11857,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| Object visitPrefixedIdentifier(PrefixedIdentifier node) {
|
| if (node.parent is! Annotation) {
|
| checkForStaticAccessToInstanceMember(node.prefix, node.identifier);
|
| + checkForInstanceAccessToStaticMember(node.prefix, node.identifier);
|
| }
|
| return super.visitPrefixedIdentifier(node);
|
| }
|
| @@ -11759,7 +11870,9 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| Object visitPropertyAccess(PropertyAccess node) {
|
| Expression target = node.realTarget;
|
| - checkForStaticAccessToInstanceMember(target, node.propertyName);
|
| + SimpleIdentifier propertyName = node.propertyName;
|
| + checkForStaticAccessToInstanceMember(target, propertyName);
|
| + checkForInstanceAccessToStaticMember(target, propertyName);
|
| return super.visitPropertyAccess(node);
|
| }
|
| Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
|
| @@ -11941,7 +12054,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| /**
|
| * This checks the passed executable element against override-error codes.
|
| *
|
| - * @param executableElement the [ExecutableElement] to evaluate
|
| + * @param executableElement a non-null [ExecutableElement] to evaluate
|
| * @param parameters the parameters of the executable element
|
| * @param errorNameTarget the node to report problems on
|
| * @return `true` if and only if an error code is generated on the passed node
|
| @@ -11959,7 +12072,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| */
|
| bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, List<ParameterElement> parameters2, List<ASTNode> parameterLocations, SimpleIdentifier errorNameTarget) {
|
| String executableElementName = executableElement.name;
|
| - ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritance(_enclosingClass, executableElement.name);
|
| + ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritance(_enclosingClass, executableElementName);
|
| bool isGetter = false;
|
| bool isSetter = false;
|
| if (executableElement is PropertyAccessorElement) {
|
| @@ -12014,13 +12127,13 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| Map<String, Type2> overridingNamedPT = overridingFT.namedParameterTypes;
|
| Map<String, Type2> overriddenNamedPT = overriddenFT.namedParameterTypes;
|
| if (overridingNormalPT.length != overriddenNormalPT.length) {
|
| - _errorReporter.reportError2(CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
|
| + _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
|
| overriddenNormalPT.length,
|
| overriddenExecutable.enclosingElement.displayName]);
|
| return true;
|
| }
|
| if (overridingPositionalPT.length < overriddenPositionalPT.length) {
|
| - _errorReporter.reportError2(CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
|
| + _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
|
| overriddenPositionalPT.length,
|
| overriddenExecutable.enclosingElement.displayName]);
|
| return true;
|
| @@ -12030,7 +12143,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| while (overriddenParameterNameIterator.hasNext) {
|
| String overriddenParamName = overriddenParameterNameIterator.next();
|
| if (!overridingParameterNameSet.contains(overriddenParamName)) {
|
| - _errorReporter.reportError2(CompileTimeErrorCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
|
| + _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
|
| overriddenParamName,
|
| overriddenExecutable.enclosingElement.displayName]);
|
| return true;
|
| @@ -12108,7 +12221,11 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| for (ParameterElement parameterElt in overriddenPEs) {
|
| if (parameterElt.parameterKind.isOptional) {
|
| - overriddenParameterElts.add((parameterElt as ParameterElementImpl));
|
| + if (parameterElt is ParameterElementImpl) {
|
| + overriddenParameterElts.add((parameterElt as ParameterElementImpl));
|
| + } else if (parameterElt is ParameterMember) {
|
| + overriddenParameterElts.add((((parameterElt as ParameterMember)).baseElement as ParameterElementImpl));
|
| + }
|
| }
|
| }
|
| if (parameterElts.length > 0) {
|
| @@ -12892,7 +13009,51 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
|
|
| /**
|
| - * This verifies that the passed constructor declaration is 'const' then there are no non-final
|
| + * This verifies that if the passed constructor declaration is 'const' then there are no
|
| + * invocations of non-'const' super constructors.
|
| + *
|
| + * @param node the constructor declaration to evaluate
|
| + * @return `true` if and only if an error code is generated on the passed node
|
| + * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER
|
| + */
|
| + bool checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) {
|
| + if (!_isEnclosingConstructorConst) {
|
| + return false;
|
| + }
|
| + if (node.factoryKeyword != null) {
|
| + return false;
|
| + }
|
| + for (ConstructorInitializer initializer in node.initializers) {
|
| + if (initializer is SuperConstructorInvocation) {
|
| + SuperConstructorInvocation superInvocation = initializer as SuperConstructorInvocation;
|
| + ConstructorElement element = superInvocation.element;
|
| + if (element.isConst) {
|
| + return false;
|
| + }
|
| + _errorReporter.reportError2(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, superInvocation, []);
|
| + return true;
|
| + }
|
| + }
|
| + InterfaceType supertype = _enclosingClass.supertype;
|
| + if (supertype == null) {
|
| + return false;
|
| + }
|
| + if (supertype.isObject) {
|
| + return false;
|
| + }
|
| + ConstructorElement unnamedConstructor = supertype.element.unnamedConstructor;
|
| + if (unnamedConstructor == null) {
|
| + return false;
|
| + }
|
| + if (unnamedConstructor.isConst) {
|
| + return false;
|
| + }
|
| + _errorReporter.reportError2(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, node, []);
|
| + return true;
|
| + }
|
| +
|
| + /**
|
| + * This verifies that if the passed constructor declaration is 'const' then there are no non-final
|
| * instance variable.
|
| *
|
| * @param node the constructor declaration to evaluate
|
| @@ -13094,6 +13255,25 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
|
|
| /**
|
| + * This verifies that the given default formal parameter is not part of a function typed
|
| + * parameter.
|
| + *
|
| + * @param node the default formal parameter to evaluate
|
| + * @return `true` if and only if an error code is generated on the passed node
|
| + * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER
|
| + */
|
| + bool checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node) {
|
| + if (!_isInFunctionTypedFormalParameter) {
|
| + return false;
|
| + }
|
| + if (node.defaultValue == null) {
|
| + return false;
|
| + }
|
| + _errorReporter.reportError2(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node, []);
|
| + return true;
|
| + }
|
| +
|
| + /**
|
| * This verifies that the enclosing class does not have an instance member with the given name of
|
| * the static member.
|
| *
|
| @@ -13569,6 +13749,40 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
|
|
| /**
|
| + * This checks that if the given "target" is not a type reference then the "name" is reference to
|
| + * a instance member.
|
| + *
|
| + * @param target the target of the name access to evaluate
|
| + * @param name the accessed name to evaluate
|
| + * @return `true` if and only if an error code is generated on the passed node
|
| + * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER
|
| + */
|
| + bool checkForInstanceAccessToStaticMember(Expression target, SimpleIdentifier name2) {
|
| + if (target == null) {
|
| + return false;
|
| + }
|
| + if (_isInComment) {
|
| + return false;
|
| + }
|
| + Element element = name2.element;
|
| + if (element is! ExecutableElement) {
|
| + return false;
|
| + }
|
| + ExecutableElement executableElement = element as ExecutableElement;
|
| + if (executableElement.enclosingElement is! ClassElement) {
|
| + return false;
|
| + }
|
| + if (!executableElement.isStatic) {
|
| + return false;
|
| + }
|
| + if (isTypeReference(target)) {
|
| + return false;
|
| + }
|
| + _errorReporter.reportError2(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name2, [name2.name]);
|
| + return true;
|
| + }
|
| +
|
| + /**
|
| * This verifies that an 'int' can be assigned to the parameter corresponding to the given
|
| * expression. This is used for prefix and postfix expressions where the argument value is
|
| * implicit.
|
| @@ -13731,7 +13945,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
| Type2 listElementType = typeArguments[0].type;
|
| ErrorCode errorCode;
|
| - if (node.modifier != null) {
|
| + if (node.constKeyword != null) {
|
| errorCode = CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE;
|
| } else {
|
| errorCode = StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE;
|
| @@ -13767,7 +13981,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| Type2 valueType = typeArguments[1].type;
|
| ErrorCode keyErrorCode;
|
| ErrorCode valueErrorCode;
|
| - if (node.modifier != null) {
|
| + if (node.constKeyword != null) {
|
| keyErrorCode = CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE;
|
| valueErrorCode = CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE;
|
| } else {
|
| @@ -14156,7 +14370,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT
|
| */
|
| bool checkForNonConstMapAsExpressionStatement(MapLiteral node) {
|
| - if (node.modifier != null) {
|
| + if (node.constKeyword != null) {
|
| return false;
|
| }
|
| if (node.typeArguments != null) {
|
| @@ -14692,7 +14906,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| } else {
|
| errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
|
| }
|
| - _errorReporter.reportError2(errorCode, argTypeName, [argTypeName.name, boundType.displayName]);
|
| + _errorReporter.reportError2(errorCode, argTypeName, [argType.displayName, boundType.displayName]);
|
| foundError = true;
|
| }
|
| }
|
|
|