diff --git a/pkg/analyzer/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart index 8cb18dc4eb8..d483516c12c 100644 --- a/pkg/analyzer/example/resolver_driver.dart +++ b/pkg/analyzer/example/resolver_driver.dart @@ -26,8 +26,8 @@ main(List args) { DartSdk sdk = DirectoryBasedDartSdk.defaultSdk; AnalysisContext context = AnalysisEngine.instance.createAnalysisContext(); - context.sourceFactory = new SourceFactory.con2([new DartUriResolver(sdk), new FileUriResolver()]); - Source source = new FileBasedSource.con1(context.sourceFactory.contentCache, new JavaFile(args[1])); + context.sourceFactory = new SourceFactory([new DartUriResolver(sdk), new FileUriResolver()]); + Source source = new FileBasedSource.con1(new JavaFile(args[1])); // ChangeSet changeSet = new ChangeSet(); changeSet.added(source); diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart index 557295007d8..38942e3e836 100644 --- a/pkg/analyzer/lib/analyzer.dart +++ b/pkg/analyzer/lib/analyzer.dart @@ -25,7 +25,7 @@ export 'src/generated/utilities_dart.dart'; CompilationUnit parseDartFile(String path) { String contents = new File(path).readAsStringSync(); var errorCollector = new _ErrorCollector(); - var sourceFactory = new SourceFactory.con2([new FileUriResolver()]); + var sourceFactory = new SourceFactory([new FileUriResolver()]); var absolutePath = pathos.absolute(path); var source = sourceFactory.forUri(pathos.toUri(absolutePath).toString()); diff --git a/pkg/analyzer/lib/src/analyzer_impl.dart b/pkg/analyzer/lib/src/analyzer_impl.dart index 1c63f0358fd..a2b11514341 100644 --- a/pkg/analyzer/lib/src/analyzer_impl.dart +++ b/pkg/analyzer/lib/src/analyzer_impl.dart @@ -52,7 +52,7 @@ class AnalyzerImpl { } var sourceFile = new JavaFile(sourcePath); var uriKind = getUriKind(sourceFile); - var librarySource = new FileBasedSource.con2(contentCache, sourceFile, uriKind); + var librarySource = new FileBasedSource.con2(sourceFile, uriKind); // prepare context prepareAnalysisContext(sourceFile); // don't try to analyzer parts @@ -101,7 +101,7 @@ class AnalyzerImpl { resolvers.add(new PackageUriResolver([packageDirectory])); } } - sourceFactory = new SourceFactory.con1(contentCache, resolvers); + sourceFactory = new SourceFactory(resolvers); context = AnalysisEngine.instance.createAnalysisContext(); context.sourceFactory = sourceFactory; diff --git a/pkg/analyzer/lib/src/error.dart b/pkg/analyzer/lib/src/error.dart index 4c9b7af2045..483c433d509 100644 --- a/pkg/analyzer/lib/src/error.dart +++ b/pkg/analyzer/lib/src/error.dart @@ -44,17 +44,16 @@ class AnalyzerError implements Exception { String toString() { var builder = new StringBuffer(); - var receiver = new _ContentReceiver(); - error.source.getContents(receiver); - var beforeError = receiver.result.substring(0, error.offset); + var content = error.source.contents.data; + var beforeError = content.substring(0, error.offset); var lineNumber = "\n".allMatches(beforeError).length + 1; builder.writeln("Error on line $lineNumber of ${error.source.fullName}: " "${error.message}"); var errorLineIndex = beforeError.lastIndexOf("\n") + 1; - var errorEndOfLineIndex = receiver.result.indexOf("\n", error.offset); - if (errorEndOfLineIndex == -1) errorEndOfLineIndex = receiver.result.length; - var errorLine = receiver.result.substring( + var errorEndOfLineIndex = content.indexOf("\n", error.offset); + if (errorEndOfLineIndex == -1) errorEndOfLineIndex = content.length; + var errorLine = content.substring( errorLineIndex, errorEndOfLineIndex); var errorColumn = error.offset - errorLineIndex; var errorLength = error.length; diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart index 738761b7911..6b3240a9923 100644 --- a/pkg/analyzer/lib/src/generated/ast.dart +++ b/pkg/analyzer/lib/src/generated/ast.dart @@ -10093,6 +10093,11 @@ class SimpleStringLiteral extends StringLiteral { */ String _value; + /** + * The toolkit specific element associated with this literal, or `null`. + */ + Element _toolkitElement; + /** * Initialize a newly created simple string literal. * @@ -10109,6 +10114,13 @@ class SimpleStringLiteral extends StringLiteral { Token get endToken => literal; + /** + * Return the toolkit specific, non-Dart, element associated with this literal, or `null`. + * + * @return the element associated with this literal + */ + Element get toolkitElement => _toolkitElement; + /** * Return the value of the literal. * @@ -10156,6 +10168,15 @@ class SimpleStringLiteral extends StringLiteral { bool get isSynthetic => literal.isSynthetic; + /** + * Set the toolkit specific, non-Dart, element associated with this literal. + * + * @param element the toolkit specific element to be associated with this literal + */ + void set toolkitElement(Element element) { + _toolkitElement = element; + } + /** * Set the value of the literal to the given string. * @@ -12176,6 +12197,7 @@ class ConstantEvaluator extends GeneralizingASTVisitor { } else if (leftOperand is double && rightOperand is double) { return leftOperand ~/ rightOperand; } + } else { } break; } @@ -12258,6 +12280,7 @@ class ConstantEvaluator extends GeneralizingASTVisitor { } else if (operand is double) { return -operand; } + } else { } break; } diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart index 5b2378449db..752f0e482fb 100644 --- a/pkg/analyzer/lib/src/generated/constant.dart +++ b/pkg/analyzer/lib/src/generated/constant.dart @@ -517,11 +517,12 @@ class ConstantVisitor extends UnifyingASTVisitor { return leftResult.divide(_typeProvider, node, rightResult); } else if (operatorType == TokenType.TILDE_SLASH) { return leftResult.integerDivide(_typeProvider, node, rightResult); + } else { + // TODO(brianwilkerson) Figure out which error to report. + return error(node, null); } break; } - // TODO(brianwilkerson) Figure out which error to report. - return error(node, null); } EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => valid2(_typeProvider.boolType, BoolState.from(node.value)); @@ -724,11 +725,12 @@ class ConstantVisitor extends UnifyingASTVisitor { return operand.bitNot(_typeProvider, node); } else if (node.operator.type == TokenType.MINUS) { return operand.negated(_typeProvider, node); + } else { + // TODO(brianwilkerson) Figure out which error to report. + return error(node, null); } break; } - // TODO(brianwilkerson) Figure out which error to report. - return error(node, null); } EvaluationResultImpl visitPropertyAccess(PropertyAccess node) => getConstantValue(node, node.propertyName.staticElement); diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart index 597ceeb4003..1535596e6bd 100644 --- a/pkg/analyzer/lib/src/generated/element.dart +++ b/pkg/analyzer/lib/src/generated/element.dart @@ -15,7 +15,7 @@ import 'source.dart'; import 'scanner.dart' show Keyword; import 'ast.dart'; import 'sdk.dart' show DartSdk; -import 'html.dart' show XmlTagNode; +import 'html.dart' show XmlAttributeNode, XmlTagNode; import 'engine.dart' show AnalysisContext; import 'constant.dart' show EvaluationResultImpl; import 'utilities_dart.dart'; @@ -157,9 +157,11 @@ abstract class ClassElement implements Element { InterfaceType get supertype; /** - * Return an array containing all of the toolkit specific objects attached to this class. + * Return an array containing all of the toolkit specific objects associated with this class. The + * array will be empty if the class does not have any toolkit specific objects or if the + * compilation unit containing the class has not yet had toolkit references resolved. * - * @return the toolkit objects attached to this class + * @return the toolkit objects associated with this class */ List get toolkitObjects; @@ -211,6 +213,14 @@ abstract class ClassElement implements Element { */ bool get isAbstract; + /** + * Return `true` if this class [isProxy], or if it inherits the proxy annotation + * from a supertype. + * + * @return `true` if this class defines or inherits a proxy + */ + bool get isOrInheritsProxy; + /** * Return `true` if this element has an annotation of the form '@proxy'. * @@ -339,6 +349,15 @@ abstract class CompilationUnitElement implements Element, UriReferencedElement { */ List get accessors; + /** + * Return an array containing all of the Angular views defined in this compilation unit. The array + * will be empty if the element does not have any Angular views or if the compilation unit has not + * yet had toolkit references resolved. + * + * @return the Angular views defined in this compilation unit. + */ + List get angularViews; + /** * Return the library in which this compilation unit is defined. * @@ -413,7 +432,9 @@ abstract class ConstructorElement implements ClassMemberElement, ExecutableEleme ConstructorDeclaration get node; /** - * Return the constructor to which this constructor is redirecting. + * Return the constructor to which this constructor is redirecting, or `null` if this constructor + * does not redirect to another constructor or if the library containing this constructor has + * not yet been resolved. * * @return the constructor to which this constructor is redirecting */ @@ -556,7 +577,9 @@ abstract class Element { ElementLocation get location; /** - * Return an array containing all of the metadata associated with this element. + * Return an array containing all of the metadata associated with this element. The array will be + * empty if the element does not have any metadata or if the library containing this element has + * not yet been resolved. * * @return the metadata associated with this element */ @@ -626,6 +649,13 @@ abstract class Element { */ bool get isDeprecated; + /** + * Return `true` if this element has an annotation of the form '@override'. + * + * @return `true` if this element is overridden + */ + bool get isOverride; + /** * Return `true` if this element is private. Private elements are visible only within the * library in which they are declared. @@ -717,57 +747,61 @@ class ElementKind extends Enum { static final ElementKind ANGULAR_PROPERTY = new ElementKind('ANGULAR_PROPERTY', 4, "Angular property"); - static final ElementKind ANGULAR_SELECTOR = new ElementKind('ANGULAR_SELECTOR', 5, "Angular selector"); + static final ElementKind ANGULAR_SCOPE_PROPERTY = new ElementKind('ANGULAR_SCOPE_PROPERTY', 5, "Angular scope property"); - static final ElementKind CLASS = new ElementKind('CLASS', 6, "class"); + static final ElementKind ANGULAR_SELECTOR = new ElementKind('ANGULAR_SELECTOR', 6, "Angular selector"); - static final ElementKind COMPILATION_UNIT = new ElementKind('COMPILATION_UNIT', 7, "compilation unit"); + static final ElementKind ANGULAR_VIEW = new ElementKind('ANGULAR_VIEW', 7, "Angular view"); - static final ElementKind CONSTRUCTOR = new ElementKind('CONSTRUCTOR', 8, "constructor"); + static final ElementKind CLASS = new ElementKind('CLASS', 8, "class"); - static final ElementKind DYNAMIC = new ElementKind('DYNAMIC', 9, ""); + static final ElementKind COMPILATION_UNIT = new ElementKind('COMPILATION_UNIT', 9, "compilation unit"); - static final ElementKind EMBEDDED_HTML_SCRIPT = new ElementKind('EMBEDDED_HTML_SCRIPT', 10, "embedded html script"); + static final ElementKind CONSTRUCTOR = new ElementKind('CONSTRUCTOR', 10, "constructor"); - static final ElementKind ERROR = new ElementKind('ERROR', 11, ""); + static final ElementKind DYNAMIC = new ElementKind('DYNAMIC', 11, ""); - static final ElementKind EXPORT = new ElementKind('EXPORT', 12, "export directive"); + static final ElementKind EMBEDDED_HTML_SCRIPT = new ElementKind('EMBEDDED_HTML_SCRIPT', 12, "embedded html script"); - static final ElementKind EXTERNAL_HTML_SCRIPT = new ElementKind('EXTERNAL_HTML_SCRIPT', 13, "external html script"); + static final ElementKind ERROR = new ElementKind('ERROR', 13, ""); - static final ElementKind FIELD = new ElementKind('FIELD', 14, "field"); + static final ElementKind EXPORT = new ElementKind('EXPORT', 14, "export directive"); - static final ElementKind FUNCTION = new ElementKind('FUNCTION', 15, "function"); + static final ElementKind EXTERNAL_HTML_SCRIPT = new ElementKind('EXTERNAL_HTML_SCRIPT', 15, "external html script"); - static final ElementKind GETTER = new ElementKind('GETTER', 16, "getter"); + static final ElementKind FIELD = new ElementKind('FIELD', 16, "field"); - static final ElementKind HTML = new ElementKind('HTML', 17, "html"); + static final ElementKind FUNCTION = new ElementKind('FUNCTION', 17, "function"); - static final ElementKind IMPORT = new ElementKind('IMPORT', 18, "import directive"); + static final ElementKind GETTER = new ElementKind('GETTER', 18, "getter"); - static final ElementKind LABEL = new ElementKind('LABEL', 19, "label"); + static final ElementKind HTML = new ElementKind('HTML', 19, "html"); - static final ElementKind LIBRARY = new ElementKind('LIBRARY', 20, "library"); + static final ElementKind IMPORT = new ElementKind('IMPORT', 20, "import directive"); - static final ElementKind LOCAL_VARIABLE = new ElementKind('LOCAL_VARIABLE', 21, "local variable"); + static final ElementKind LABEL = new ElementKind('LABEL', 21, "label"); - static final ElementKind METHOD = new ElementKind('METHOD', 22, "method"); + static final ElementKind LIBRARY = new ElementKind('LIBRARY', 22, "library"); - static final ElementKind NAME = new ElementKind('NAME', 23, ""); + static final ElementKind LOCAL_VARIABLE = new ElementKind('LOCAL_VARIABLE', 23, "local variable"); - static final ElementKind PARAMETER = new ElementKind('PARAMETER', 24, "parameter"); + static final ElementKind METHOD = new ElementKind('METHOD', 24, "method"); - static final ElementKind PREFIX = new ElementKind('PREFIX', 25, "import prefix"); + static final ElementKind NAME = new ElementKind('NAME', 25, ""); - static final ElementKind SETTER = new ElementKind('SETTER', 26, "setter"); + static final ElementKind PARAMETER = new ElementKind('PARAMETER', 26, "parameter"); - static final ElementKind TOP_LEVEL_VARIABLE = new ElementKind('TOP_LEVEL_VARIABLE', 27, "top level variable"); + static final ElementKind PREFIX = new ElementKind('PREFIX', 27, "import prefix"); - static final ElementKind FUNCTION_TYPE_ALIAS = new ElementKind('FUNCTION_TYPE_ALIAS', 28, "function type alias"); + static final ElementKind SETTER = new ElementKind('SETTER', 28, "setter"); - static final ElementKind TYPE_PARAMETER = new ElementKind('TYPE_PARAMETER', 29, "type parameter"); + static final ElementKind TOP_LEVEL_VARIABLE = new ElementKind('TOP_LEVEL_VARIABLE', 29, "top level variable"); - static final ElementKind UNIVERSE = new ElementKind('UNIVERSE', 30, ""); + static final ElementKind FUNCTION_TYPE_ALIAS = new ElementKind('FUNCTION_TYPE_ALIAS', 30, "function type alias"); + + static final ElementKind TYPE_PARAMETER = new ElementKind('TYPE_PARAMETER', 31, "type parameter"); + + static final ElementKind UNIVERSE = new ElementKind('UNIVERSE', 32, ""); static final List values = [ ANGULAR_FILTER, @@ -775,7 +809,9 @@ class ElementKind extends Enum { ANGULAR_CONTROLLER, ANGULAR_DIRECTIVE, ANGULAR_PROPERTY, + ANGULAR_SCOPE_PROPERTY, ANGULAR_SELECTOR, + ANGULAR_VIEW, CLASS, COMPILATION_UNIT, CONSTRUCTOR, @@ -862,8 +898,12 @@ abstract class ElementVisitor { R visitAngularPropertyElement(AngularPropertyElement element); + R visitAngularScopePropertyElement(AngularScopePropertyElement element); + R visitAngularSelectorElement(AngularSelectorElement element); + R visitAngularViewElement(AngularViewElement element); + R visitClassElement(ClassElement element); R visitCompilationUnitElement(CompilationUnitElement element); @@ -1348,7 +1388,8 @@ abstract class LibraryElement implements Element { bool hasExtUri(); /** - * Return `true` if this library is created for Angular analysis. + * Return `true` if this library is created for Angular analysis. If this library has not + * yet had toolkit references resolved, then `false` will be returned. * * @return `true` if this library is created for Angular analysis */ @@ -1479,6 +1520,23 @@ abstract class MultiplyDefinedElement implements Element { Type2 get type; } +/** + * The interface [MultiplyInheritedExecutableElement] defines all of the behavior of an + * [ExecutableElement], with the additional information of an array of + * [ExecutableElement]s from which this element was composed. + * + * @coverage dart.engine.element + */ +abstract class MultiplyInheritedExecutableElement implements ExecutableElement { + /** + * Return an array containing all of the executable elements defined within this executable + * element. + * + * @return the elements defined within this executable element + */ + List get inheritedElements; +} + /** * The interface `NamespaceCombinator` defines the behavior common to objects that control how * namespaces are combined. @@ -1827,12 +1885,18 @@ abstract class VariableElement implements Element { * * @coverage dart.engine.element */ -abstract class AngularComponentElement implements AngularHasSelectorElement { +abstract class AngularComponentElement implements AngularHasSelectorElement, AngularHasTemplateElement { /** * Return an array containing all of the properties declared by this component. */ List get properties; + /** + * Return an array containing all of the scope properties set in the implementation of this + * component. + */ + List get scopeProperties; + /** * Returns the CSS file URI. */ @@ -1844,23 +1908,6 @@ abstract class AngularComponentElement implements AngularHasSelectorElement { * @return the offset of the style URI */ int get styleUriOffset; - - /** - * Returns the HTML template [Source], `null` if not resolved. - */ - Source get templateSource; - - /** - * Returns the HTML template URI. - */ - String get templateUri; - - /** - * Return the offset of the [getTemplateUri] in the [getSource]. - * - * @return the offset of the template URI - */ - int get templateUriOffset; } /** @@ -1901,6 +1948,13 @@ abstract class AngularElement implements ToolkitObjectElement { * An empty array of angular elements. */ static final List EMPTY_ARRAY = new List(0); + + /** + * Returns the [AngularApplication] this element is used in. + * + * @return the [AngularApplication] this element is used in + */ + AngularApplication get application; } /** @@ -1912,6 +1966,18 @@ abstract class AngularElement implements ToolkitObjectElement { abstract class AngularFilterElement implements AngularElement { } +/** + * [AngularSelectorElement] based on presence of attribute. + */ +abstract class AngularHasAttributeSelectorElement implements AngularSelectorElement { +} + +/** + * [AngularSelectorElement] based on presence of a class. + */ +abstract class AngularHasClassSelectorElement implements AngularSelectorElement { +} + /** * The interface `AngularElement` defines the behavior of objects representing information * about an Angular element which is applied conditionally using some [AngularSelectorElement]. @@ -1927,6 +1993,31 @@ abstract class AngularHasSelectorElement implements AngularElement { AngularSelectorElement get selector; } +/** + * The interface `AngularHasTemplateElement` defines common behavior for + * [AngularElement] that have template URI / [Source]. + * + * @coverage dart.engine.element + */ +abstract class AngularHasTemplateElement implements AngularElement { + /** + * Returns the HTML template [Source], `null` if not resolved. + */ + Source get templateSource; + + /** + * Returns the HTML template URI. + */ + String get templateUri; + + /** + * Return the offset of the [getTemplateUri] in the [getSource]. + * + * @return the offset of the template URI + */ + int get templateUriOffset; +} + /** * The interface `AngularPropertyElement` defines a single property in * [AngularComponentElement]. @@ -1947,7 +2038,8 @@ abstract class AngularPropertyElement implements AngularElement { FieldElement get field; /** - * Return the offset of the field name of this property in the property map. + * Return the offset of the field name of this property in the property map, or `-1` if + * property was created using annotation on [FieldElement]. * * @return the offset of the field name of this property */ @@ -2021,6 +2113,26 @@ class AngularPropertyKind_TWO_WAY extends AngularPropertyKind { bool callsGetter() => true; } +/** + * The interface `AngularScopeVariableElement` defines the Angular Scope + * property. They are created for every scope['property'] = value; code snippet. + * + * @coverage dart.engine.element + */ +abstract class AngularScopePropertyElement implements AngularElement { + /** + * An empty array of scope property elements. + */ + static final List EMPTY_ARRAY = []; + + /** + * Returns the type of this property, not `null`, maybe dynamic. + * + * @return the type of this property. + */ + Type2 get type; +} + /** * [AngularSelectorElement] is used to decide when Angular object should be applied. * @@ -2037,6 +2149,25 @@ abstract class AngularSelectorElement implements AngularElement { bool apply(XmlTagNode node); } +/** + * [AngularSelectorElement] based on tag name. + */ +abstract class AngularTagSelectorElement implements AngularSelectorElement { +} + +/** + * The interface `AngularViewElement` defines the Angular view defined using invocation like + * view('views/create.html'). + * + * @coverage dart.engine.element + */ +abstract class AngularViewElement implements AngularHasTemplateElement { + /** + * An empty array of view elements. + */ + static final List EMPTY_ARRAY = new List(0); +} + /** * Instances of the class `GeneralizingElementVisitor` implement an element visitor that will * recursively visit all of the elements in an element model (like instances of the class @@ -2109,8 +2240,12 @@ class GeneralizingElementVisitor implements ElementVisitor { R visitAngularPropertyElement(AngularPropertyElement element) => visitAngularElement(element); + R visitAngularScopePropertyElement(AngularScopePropertyElement element) => visitAngularElement(element); + R visitAngularSelectorElement(AngularSelectorElement element) => visitAngularElement(element); + R visitAngularViewElement(AngularViewElement element) => visitAngularElement(element); + R visitClassElement(ClassElement element) => visitElement(element); R visitCompilationUnitElement(CompilationUnitElement element) => visitElement(element); @@ -2220,11 +2355,21 @@ class RecursiveElementVisitor implements ElementVisitor { return null; } + R visitAngularScopePropertyElement(AngularScopePropertyElement element) { + element.visitChildren(this); + return null; + } + R visitAngularSelectorElement(AngularSelectorElement element) { element.visitChildren(this); return null; } + R visitAngularViewElement(AngularViewElement element) { + element.visitChildren(this); + return null; + } + R visitClassElement(ClassElement element) { element.visitChildren(this); return null; @@ -2355,8 +2500,12 @@ class SimpleElementVisitor implements ElementVisitor { R visitAngularPropertyElement(AngularPropertyElement element) => null; + R visitAngularScopePropertyElement(AngularScopePropertyElement element) => null; + R visitAngularSelectorElement(AngularSelectorElement element) => null; + R visitAngularViewElement(AngularViewElement element) => null; + R visitClassElement(ClassElement element) => null; R visitCompilationUnitElement(CompilationUnitElement element) => null; @@ -2489,7 +2638,7 @@ class ClassElementImpl extends ElementImpl implements ClassElement { List _typeParameters = TypeParameterElementImpl.EMPTY_ARRAY; /** - * An empty array of type elements. + * An empty array of class elements. */ static List EMPTY_ARRAY = new List(0); @@ -2654,6 +2803,8 @@ class ClassElementImpl extends ElementImpl implements ClassElement { bool get isAbstract => hasModifier(Modifier.ABSTRACT); + bool get isOrInheritsProxy => isOrInheritsProxy2(this, new Set()); + bool get isProxy { for (ElementAnnotation annotation in metadata) { if (annotation.isProxy) { @@ -2914,6 +3065,31 @@ class ClassElementImpl extends ElementImpl implements ClassElement { } } } + + bool isOrInheritsProxy2(ClassElement classElt, Set visitedClassElts) { + if (visitedClassElts.contains(classElt)) { + return false; + } + visitedClassElts.add(classElt); + if (classElt.isProxy) { + return true; + } else if (classElt.supertype != null && isOrInheritsProxy2(classElt.supertype.element, visitedClassElts)) { + return true; + } + List supertypes = classElt.interfaces; + for (int i = 0; i < supertypes.length; i++) { + if (isOrInheritsProxy2(supertypes[i].element, visitedClassElts)) { + return true; + } + } + supertypes = classElt.mixins; + for (int i = 0; i < supertypes.length; i++) { + if (isOrInheritsProxy2(supertypes[i].element, visitedClassElts)) { + return true; + } + } + return false; + } } /** @@ -2970,6 +3146,11 @@ class CompilationUnitElementImpl extends ElementImpl implements CompilationUnitE */ String uri; + /** + * An array containing all of the Angular views contained in this compilation unit. + */ + List _angularViews = AngularViewElement.EMPTY_ARRAY; + /** * Initialize a newly created compilation unit element to have the given name. * @@ -2983,6 +3164,8 @@ class CompilationUnitElementImpl extends ElementImpl implements CompilationUnitE List get accessors => _accessors; + List get angularViews => _angularViews; + ElementImpl getChild(String identifier) { // // The casts in this method are safe because the set methods would have thrown a CCE if any of @@ -3054,6 +3237,18 @@ class CompilationUnitElementImpl extends ElementImpl implements CompilationUnitE this._accessors = accessors; } + /** + * Set the Angular views defined in this compilation unit. + * + * @param angularViews the Angular views defined in this compilation unit + */ + void set angularViews(List angularViews) { + for (AngularViewElement view in angularViews) { + (view as AngularViewElementImpl).enclosingElement = this; + } + this._angularViews = angularViews; + } + /** * Set the top-level functions contained in this compilation unit to the given functions. * @@ -3109,6 +3304,7 @@ class CompilationUnitElementImpl extends ElementImpl implements CompilationUnitE safelyVisitChildren(_typeAliases, visitor); safelyVisitChildren(_types, visitor); safelyVisitChildren(_variables, visitor); + safelyVisitChildren(_angularViews, visitor); } void appendTo(JavaStringBuilder builder) { @@ -3241,7 +3437,16 @@ class ConstructorElementImpl extends ExecutableElementImpl implements Constructo * * @param name the name of this element */ - ConstructorElementImpl(Identifier name) : super.con1(name); + ConstructorElementImpl.con1(Identifier name) : super.con1(name); + + /** + * Initialize a newly created constructor element to have the given name. + * + * @param name the name of this element + * @param nameOffset the offset of the name of this element in the file that contains the + * declaration of this element + */ + ConstructorElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset); accept(ElementVisitor visitor) => visitor.visitConstructorElement(this); @@ -3621,6 +3826,15 @@ abstract class ElementImpl implements Element { return false; } + bool get isOverride { + for (ElementAnnotation annotation in metadata) { + if (annotation.isOverride) { + return true; + } + } + return false; + } + bool get isPrivate { String name = displayName; if (name == null) { @@ -4862,13 +5076,14 @@ class LibraryElementImpl extends ElementImpl implements LibraryElement { static bool isUpToDate(LibraryElement library, int timeStamp, Set visitedLibraries) { if (!visitedLibraries.contains(library)) { visitedLibraries.add(library); + AnalysisContext context = library.context; // Check the defining compilation unit. - if (timeStamp < library.definingCompilationUnit.source.modificationStamp) { + if (timeStamp < context.getModificationStamp(library.definingCompilationUnit.source)) { return false; } // Check the parted compilation units. for (CompilationUnitElement element in library.parts) { - if (timeStamp < element.source.modificationStamp) { + if (timeStamp < context.getModificationStamp(element.source)) { return false; } } @@ -5584,6 +5799,8 @@ class MultiplyDefinedElementImpl implements MultiplyDefinedElement { bool get isDeprecated => false; + bool get isOverride => false; + bool get isPrivate { String name = displayName; if (name == null) { @@ -5614,6 +5831,54 @@ class MultiplyDefinedElementImpl implements MultiplyDefinedElement { } } +/** + * The interface [MultiplyInheritedMethodElementImpl] defines all of the behavior of an + * [MethodElementImpl], with the additional information of an array of + * [ExecutableElement]s from which this element was composed. + * + * @coverage dart.engine.element + */ +class MultiplyInheritedMethodElementImpl extends MethodElementImpl implements MultiplyInheritedExecutableElement { + /** + * An array the array of executable elements that were used to compose this element. + */ + List _elements = MethodElementImpl.EMPTY_ARRAY; + + MultiplyInheritedMethodElementImpl(Identifier name) : super.con1(name) { + synthetic = true; + } + + List get inheritedElements => _elements; + + void set inheritedElements(List elements) { + this._elements = elements; + } +} + +/** + * The interface [MultiplyInheritedPropertyAccessorElementImpl] defines all of the behavior of + * an [PropertyAccessorElementImpl], with the additional information of an array of + * [ExecutableElement]s from which this element was composed. + * + * @coverage dart.engine.element + */ +class MultiplyInheritedPropertyAccessorElementImpl extends PropertyAccessorElementImpl implements MultiplyInheritedExecutableElement { + /** + * An array the array of executable elements that were used to compose this element. + */ + List _elements = PropertyAccessorElementImpl.EMPTY_ARRAY; + + MultiplyInheritedPropertyAccessorElementImpl(Identifier name) : super.con1(name) { + synthetic = true; + } + + List get inheritedElements => _elements; + + void set inheritedElements(List elements) { + this._elements = elements; + } +} + /** * Instances of the class `ParameterElementImpl` implement a `ParameterElement`. * @@ -5777,6 +6042,7 @@ class ParameterElementImpl extends VariableElementImpl implements ParameterEleme } else if (parameterKind == ParameterKind.POSITIONAL) { left = "["; right = "]"; + } else if (parameterKind == ParameterKind.REQUIRED) { } break; } @@ -6189,8 +6455,8 @@ abstract class VariableElementImpl extends ElementImpl implements VariableElemen /** * Return the result of evaluating this variable's initializer as a compile-time constant - * expression, or `null` if this variable is not a 'const' variable or does not have an - * initializer. + * expression, or `null` if this variable is not a 'const' variable, if it does not have an + * initializer, or if the compilation unit containing the variable has not been resolved. * * @return the result of evaluating this variable's initializer */ @@ -6205,8 +6471,9 @@ abstract class VariableElementImpl extends ElementImpl implements VariableElemen bool get isFinal => hasModifier(Modifier.FINAL); /** - * Return `true` if this variable is potentially mutated somewhere in closure. This - * information is only available for local variables (including parameters). + * Return `true` if this variable is potentially mutated somewhere in a closure. This + * information is only available for local variables (including parameters) and only after the + * compilation unit containing the variable has been resolved. * * @return `true` if this variable is potentially mutated somewhere in closure */ @@ -6214,7 +6481,8 @@ abstract class VariableElementImpl extends ElementImpl implements VariableElemen /** * Return `true` if this variable is potentially mutated somewhere in its scope. This - * information is only available for local variables (including parameters). + * information is only available for local variables (including parameters) and only after the + * compilation unit containing the variable has been resolved. * * @return `true` if this variable is potentially mutated somewhere in its scope */ @@ -6272,6 +6540,28 @@ abstract class VariableElementImpl extends ElementImpl implements VariableElemen } } +/** + * Information about Angular application. + */ +class AngularApplication { + final Source entryPoint; + + Set _librarySources; + + final List elements; + + final List elementSources; + + AngularApplication(this.entryPoint, Set librarySources, this.elements, this.elementSources) { + this._librarySources = librarySources; + } + + /** + * Checks if this application depends on the library with the given [Source]. + */ + bool dependsOn(Source librarySource) => _librarySources.contains(librarySource); +} + /** * Implementation of `AngularComponentElement`. * @@ -6288,6 +6578,11 @@ class AngularComponentElementImpl extends AngularHasSelectorElementImpl implemen */ List _properties = AngularPropertyElement.EMPTY_ARRAY; + /** + * The array containing all of the scope properties set by this component. + */ + List _scopeProperties = AngularScopePropertyElement.EMPTY_ARRAY; + /** * The the CSS file URI. */ @@ -6330,6 +6625,8 @@ class AngularComponentElementImpl extends AngularHasSelectorElementImpl implemen List get properties => _properties; + List get scopeProperties => _scopeProperties; + /** * Set an array containing all of the properties declared by this component. * @@ -6342,8 +6639,21 @@ class AngularComponentElementImpl extends AngularHasSelectorElementImpl implemen this._properties = properties; } + /** + * Set an array containing all of the scope properties declared by this component. + * + * @param properties the properties to set + */ + void set scopeProperties(List properties) { + for (AngularScopePropertyElement property in properties) { + encloseElement(property as AngularScopePropertyElementImpl); + } + this._scopeProperties = properties; + } + void visitChildren(ElementVisitor visitor) { safelyVisitChildren(_properties, visitor); + safelyVisitChildren(_scopeProperties, visitor); super.visitChildren(visitor); } @@ -6434,6 +6744,11 @@ class AngularDirectiveElementImpl extends AngularHasSelectorElementImpl implemen * @coverage dart.engine.element */ abstract class AngularElementImpl extends ToolkitObjectElementImpl implements AngularElement { + /** + * The [AngularApplication] this element is used in. + */ + AngularApplication _application; + /** * Initialize a newly created Angular element to have the given name. * @@ -6442,6 +6757,15 @@ abstract class AngularElementImpl extends ToolkitObjectElementImpl implements An * declaration of this element */ AngularElementImpl(String name, int nameOffset) : super(name, nameOffset); + + AngularApplication get application => _application; + + /** + * Set the [AngularApplication] this element is used in. + */ + void set application(AngularApplication application) { + this._application = application; + } } /** @@ -6464,6 +6788,34 @@ class AngularFilterElementImpl extends AngularElementImpl implements AngularFilt ElementKind get kind => ElementKind.ANGULAR_FILTER; } +/** + * Implementation of [AngularSelectorElement] based on presence of a class. + */ +class AngularHasClassSelectorElementImpl extends AngularSelectorElementImpl implements AngularHasClassSelectorElement { + AngularHasClassSelectorElementImpl(String name, int offset) : super(name, offset); + + bool apply(XmlTagNode node) { + XmlAttributeNode attribute = node.getAttribute("class"); + if (attribute != null) { + String text = attribute.text; + if (text != null) { + String name = this.name; + for (String className in StringUtils.split(text)) { + if (className == name) { + return true; + } + } + } + } + return false; + } + + void appendTo(JavaStringBuilder builder) { + builder.append("."); + builder.append(name); + } +} + /** * Implementation of `AngularSelectorElement`. * @@ -6534,6 +6886,31 @@ class AngularPropertyElementImpl extends AngularElementImpl implements AngularPr ElementKind get kind => ElementKind.ANGULAR_PROPERTY; } +/** + * Implementation of `AngularScopePropertyElement`. + * + * @coverage dart.engine.element + */ +class AngularScopePropertyElementImpl extends AngularElementImpl implements AngularScopePropertyElement { + /** + * The type of the property + */ + final Type2 type; + + /** + * Initialize a newly created Angular scope property to have the given name. + * + * @param name the name of this element + * @param nameOffset the offset of the name of this element in the file that contains the + * declaration of this element + */ + AngularScopePropertyElementImpl(String name, int nameOffset, this.type) : super(name, nameOffset); + + accept(ElementVisitor visitor) => visitor.visitAngularScopePropertyElement(this); + + ElementKind get kind => ElementKind.ANGULAR_SCOPE_PROPERTY; +} + /** * Implementation of `AngularFilterElement`. * @@ -6554,10 +6931,57 @@ abstract class AngularSelectorElementImpl extends AngularElementImpl implements ElementKind get kind => ElementKind.ANGULAR_SELECTOR; } +/** + * Implementation of [AngularSelectorElement] based on tag name. + */ +class AngularTagSelectorElementImpl extends AngularSelectorElementImpl implements AngularTagSelectorElement { + AngularTagSelectorElementImpl(String name, int offset) : super(name, offset); + + bool apply(XmlTagNode node) { + String tagName = name; + return node.tag == tagName; + } + + AngularApplication get application => (enclosingElement as AngularElementImpl).application; +} + +/** + * Implementation of `AngularViewElement`. + * + * @coverage dart.engine.element + */ +class AngularViewElementImpl extends AngularElementImpl implements AngularViewElement { + /** + * The HTML template URI. + */ + final String templateUri; + + /** + * The offset of the [templateUri] in the [getSource]. + */ + final int templateUriOffset; + + /** + * The HTML template source. + */ + Source templateSource; + + /** + * Initialize a newly created Angular view. + */ + AngularViewElementImpl(this.templateUri, this.templateUriOffset) : super(null, -1); + + accept(ElementVisitor visitor) => visitor.visitAngularViewElement(this); + + ElementKind get kind => ElementKind.ANGULAR_VIEW; + + String get identifier => "AngularView@${templateUriOffset}"; +} + /** * Implementation of [AngularSelectorElement] based on presence of attribute. */ -class HasAttributeSelectorElementImpl extends AngularSelectorElementImpl { +class HasAttributeSelectorElementImpl extends AngularSelectorElementImpl implements AngularHasAttributeSelectorElement { HasAttributeSelectorElementImpl(String attributeName, int offset) : super(attributeName, offset); bool apply(XmlTagNode node) { @@ -6565,11 +6989,15 @@ class HasAttributeSelectorElementImpl extends AngularSelectorElementImpl { return node.getAttribute(attributeName) != null; } - String get displayName => "[${super.displayName}]"; + void appendTo(JavaStringBuilder builder) { + builder.append("["); + builder.append(name); + builder.append("]"); + } } /** - * Combination of [IsTagSelectorElementImpl] and [HasAttributeSelectorElementImpl]. + * Combination of [AngularTagSelectorElementImpl] and [HasAttributeSelectorElementImpl]. */ class IsTagHasAttributeSelectorElementImpl extends AngularSelectorElementImpl { final String tagName; @@ -6581,18 +7009,6 @@ class IsTagHasAttributeSelectorElementImpl extends AngularSelectorElementImpl { bool apply(XmlTagNode node) => node.tag == tagName && node.getAttribute(attributeName) != null; } -/** - * Implementation of [AngularSelectorElement] based on tag name. - */ -class IsTagSelectorElementImpl extends AngularSelectorElementImpl { - IsTagSelectorElementImpl(String name, int offset) : super(name, offset); - - bool apply(XmlTagNode node) { - String tagName = name; - return node.tag == tagName; - } -} - /** * Instances of the class `ConstructorMember` represent a constructor element defined in a * parameterized type where the values of the type parameters are known. @@ -6887,6 +7303,8 @@ abstract class Member implements Element { bool get isDeprecated => _baseElement.isDeprecated; + bool get isOverride => _baseElement.isOverride; + bool get isPrivate => _baseElement.isPrivate; bool get isPublic => _baseElement.isPublic; @@ -7136,6 +7554,7 @@ class ParameterMember extends VariableMember implements ParameterElement { } else if (baseElement.parameterKind == ParameterKind.POSITIONAL) { left = "["; right = "]"; + } else if (baseElement.parameterKind == ParameterKind.REQUIRED) { } break; } diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart index 99970733b87..b64bdc1a1f4 100644 --- a/pkg/analyzer/lib/src/generated/engine.dart +++ b/pkg/analyzer/lib/src/generated/engine.dart @@ -126,6 +126,13 @@ class AnalysisEngine { * Container with statistics about the [AnalysisContext]. */ abstract class AnalysisContentStatistics { + /** + * Return the statistics for each kind of cached data. + * + * @return the statistics for each kind of cached data + */ + List get cacheRows; + /** * Return the exceptions that caused some entries to have a state of [CacheState#ERROR]. * @@ -134,11 +141,11 @@ abstract class AnalysisContentStatistics { List get exceptions; /** - * Return the statistics for each kind of cached data. + * Return an array containing all of the sources in the cache. * - * @return the statistics for each kind of cached data + * @return an array containing all of the sources in the cache */ - List get cacheRows; + List get sources; } /** @@ -280,6 +287,18 @@ abstract class AnalysisContext { */ LineInfo computeLineInfo(Source source); + /** + * Return `true` if the given source exists. + * + * This method should be used rather than the method [Source#exists] because contexts can + * have local overrides of the content of a source that the source is not aware of and a source + * with local content is considered to exist even if there is no file on disk. + * + * @param source the source whose modification stamp is to be returned + * @return `true` if the source exists + */ + bool exists(Source source); + /** * Create a new context in which analysis can be performed. Any sources in the specified container * will be removed from this context and added to the newly created context. @@ -299,6 +318,43 @@ abstract class AnalysisContext { */ AnalysisOptions get analysisOptions; + /** + * Return the element model corresponding to the compilation unit defined by the given source in + * the library defined by the given source, or `null` if the element model does not + * currently exist or if the library cannot be analyzed for some reason. + * + * @param unitSource the source of the compilation unit + * @param librarySource the source of the defining compilation unit of the library containing the + * compilation unit + * @return the element model corresponding to the compilation unit defined by the given source + */ + CompilationUnitElement getCompilationUnitElement(Source unitSource, Source librarySource); + + /** + * Get the contents and timestamp of the given source. + * + * This method should be used rather than the method [Source#getContents] because contexts + * can have local overrides of the content of a source that the source is not aware of. + * + * @param source the source whose content is to be returned + * @return the contents and timestamp of the source + * @throws Exception if the contents of the source could not be accessed + */ + TimestampedData getContents(Source source); + + /** + * Get the contents of the given source and pass it to the given content receiver. + * + * This method should be used rather than the method [Source#getContentsToReceiver] + * because contexts can have local overrides of the content of a source that the source is not + * aware of. + * + * @param source the source whose content is to be returned + * @param receiver the content receiver to which the content of the source will be passed + * @throws Exception if the contents of the source could not be accessed + */ + void getContentsToReceiver(Source source, Source_ContentReceiver receiver); + /** * Return the element referenced by the given location, or `null` if the element is not * immediately available or if there is no element with the given location. The latter condition @@ -437,6 +493,21 @@ abstract class AnalysisContext { */ LineInfo getLineInfo(Source source); + /** + * Return the modification stamp for the given source. A modification stamp is a non-negative + * integer with the property that if the contents of the source have not been modified since the + * last time the modification stamp was accessed then the same value will be returned, but if the + * contents of the source have been modified one or more times (even if the net change is zero) + * the stamps will be different. + * + * This method should be used rather than the method [Source#getModificationStamp] because + * contexts can have local overrides of the content of a source that the source is not aware of. + * + * @param source the source whose modification stamp is to be returned + * @return the modification stamp for the source + */ + int getModificationStamp(Source source); + /** * Return an array containing all of the sources known to this context and their resolution state * is not valid or flush. So, these sources are not safe to update during refactoring, because we @@ -642,15 +713,6 @@ abstract class AnalysisContext { * context */ void set sourceFactory(SourceFactory factory); - - /** - * Given a collection of sources with content that has changed, return an [Iterable] - * identifying the sources that need to be resolved. - * - * @param changedSources an array of sources (not `null`, contains no `null`s) - * @return An iterable returning the sources to be resolved - */ - Iterable sourcesToResolve(List changedSources); } /** @@ -714,6 +776,13 @@ class AnalysisException extends JavaException { * set of analysis options used to control the behavior of an analysis context. */ abstract class AnalysisOptions { + /** + * Return `true` if analysis is to analyze Angular. + * + * @return `true` if analysis is to analyze Angular + */ + bool get analyzeAngular; + /** * Return `true` if analysis is to parse and analyze function bodies. * @@ -735,6 +804,14 @@ abstract class AnalysisOptions { */ bool get dart2jsHint; + /** + * Return `true` if errors, warnings and hints should be generated for sources in the SDK. + * The default value is `false`. + * + * @return `true` if errors, warnings and hints should be generated for the SDK + */ + bool get generateSdkErrors; + /** * Return `true` if analysis is to generate hint results (e.g. type inference based * information and pub best practices). @@ -756,13 +833,6 @@ abstract class AnalysisOptions { * @return `true` if analysis is to parse comments */ bool get preserveComments; - - /** - * Return `true` if analysis is to analyze Angular. - * - * @return `true` if analysis is to analyze Angular - */ - bool get analyzeAngular; } /** @@ -969,6 +1039,34 @@ class ChangeSet { } } +/** + * Instances of the class `ObsoleteSourceAnalysisException` represent an analysis attempt that + * failed because a source was deleted between the time the analysis started and the time the + * results of the analysis were ready to be recorded. + */ +class ObsoleteSourceAnalysisException extends AnalysisException { + /** + * The source that was removed while it was being analyzed. + */ + Source _source; + + /** + * Initialize a newly created exception to represent the removal of the given source. + * + * @param source the source that was removed while it was being analyzed + */ + ObsoleteSourceAnalysisException(Source source) : super.con1("The source '${source.fullName}' was removed while it was being analyzed") { + this._source = source; + } + + /** + * Return the source that was removed while it was being analyzed. + * + * @return the source that was removed + */ + Source get source => _source; +} + /** * Instances of the class `AnalysisCache` implement an LRU cache of information related to * analysis. @@ -1162,17 +1260,6 @@ class AnalysisCache { } } -/** - * Information about Angular application. - */ -class AngularApplicationInfo { - final Source entryPoint; - - final List elements; - - AngularApplicationInfo(this.entryPoint, this.elements); -} - /** * Instances of the class `CacheRetentionPolicy` define the behavior of objects that determine * how important it is for data to be retained in the analysis cache. @@ -1336,11 +1423,26 @@ abstract class DartEntry implements SourceEntry { */ static final DataDescriptor SOURCE_KIND = new DataDescriptor("DartEntry.SOURCE_KIND"); + /** + * The data descriptor representing the token stream. + */ + static final DataDescriptor> SCAN_ERRORS = new DataDescriptor>("DartEntry.SCAN_ERRORS"); + + /** + * The data descriptor representing the token stream. + */ + static final DataDescriptor TOKEN_STREAM = new DataDescriptor("DartEntry.TOKEN_STREAM"); + /** * The data descriptor representing the errors resulting from verifying the source. */ static final DataDescriptor> VERIFICATION_ERRORS = new DataDescriptor>("DartEntry.VERIFICATION_ERRORS"); + /** + * The data descriptor representing the errors reported during Angular resolution. + */ + static final DataDescriptor> ANGULAR_ERRORS = new DataDescriptor>("DartEntry.ANGULAR_ERRORS"); + /** * Return all of the errors associated with the compilation unit that are currently cached. * @@ -1411,6 +1513,27 @@ abstract class DartEntry implements SourceEntry { * @coverage dart.engine */ class DartEntryImpl extends SourceEntryImpl implements DartEntry { + /** + * The state of the cached token stream. + */ + CacheState _tokenStreamState = CacheState.INVALID; + + /** + * The head of the token stream, or `null` if the token stream is not currently cached. + */ + Token _tokenStream; + + /** + * The state of the cached scan errors. + */ + CacheState _scanErrorsState = CacheState.INVALID; + + /** + * The errors produced while scanning the compilation unit, or `null` if the errors are not + * currently cached. + */ + List _scanErrors = AnalysisError.NO_ERRORS; + /** * The state of the cached source kind. */ @@ -1444,8 +1567,8 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { CacheState _parseErrorsState = CacheState.INVALID; /** - * The errors produced while scanning and parsing the compilation unit, or `null` if the - * errors are not currently cached. + * The errors produced while parsing the compilation unit, or `null` if the errors are not + * currently cached. */ List _parseErrors = AnalysisError.NO_ERRORS; @@ -1529,6 +1652,12 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { */ int _bitmask = 0; + /** + * The error produced while performing Angular resolution, or an empty array if there are no + * errors if the error are not currently cached. + */ + List _angularErrors = AnalysisError.NO_ERRORS; + /** * The index of the bit in the [bitmask] indicating that this library is launchable: that * the file has a main method. @@ -1556,6 +1685,10 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { * Flush any AST structures being maintained by this entry. */ void flushAstStructures() { + if (identical(_tokenStreamState, CacheState.VALID)) { + _tokenStreamState = CacheState.FLUSHED; + _tokenStream = null; + } if (identical(_parsedUnitState, CacheState.VALID)) { _parsedUnitState = CacheState.FLUSHED; _parsedUnitAccessed = false; @@ -1566,23 +1699,16 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { List get allErrors { List errors = new List(); - for (AnalysisError error in _parseErrors) { - errors.add(error); - } + ListUtilities.addAll(errors, _scanErrors); + ListUtilities.addAll(errors, _parseErrors); DartEntryImpl_ResolutionState state = _resolutionState; while (state != null) { - for (AnalysisError error in state._resolutionErrors) { - errors.add(error); - } - for (AnalysisError error in state._verificationErrors) { - errors.add(error); - } - for (AnalysisError error in state._hints) { - errors.add(error); - } + ListUtilities.addAll(errors, state._resolutionErrors); + ListUtilities.addAll(errors, state._verificationErrors); + ListUtilities.addAll(errors, state._hints); state = state._nextState; } - ; + ListUtilities.addAll(errors, _angularErrors); if (errors.length == 0) { return AnalysisError.NO_ERRORS; } @@ -1673,8 +1799,12 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { return _parsedUnitState; } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) { return _publicNamespaceState; + } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) { + return _scanErrorsState; } else if (identical(descriptor, DartEntry.SOURCE_KIND)) { return _sourceKindState; + } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) { + return _tokenStreamState; } else { return super.getState(descriptor); } @@ -1707,7 +1837,9 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { } Object getValue(DataDescriptor descriptor) { - if (identical(descriptor, DartEntry.CONTAINING_LIBRARIES)) { + if (identical(descriptor, DartEntry.ANGULAR_ERRORS)) { + return _angularErrors; + } else if (identical(descriptor, DartEntry.CONTAINING_LIBRARIES)) { return new List.from(_containingLibraries); } else if (identical(descriptor, DartEntry.ELEMENT)) { return _element; @@ -1728,8 +1860,12 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { return _parsedUnit; } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) { return _publicNamespace; + } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) { + return _scanErrors; } else if (identical(descriptor, DartEntry.SOURCE_KIND)) { return _sourceKind; + } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) { + return _tokenStream; } return super.getValue(descriptor); } @@ -1787,8 +1923,12 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { return identical(_parsedUnitState, CacheState.INVALID); } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) { return identical(_publicNamespaceState, CacheState.INVALID); + } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) { + return identical(_scanErrorsState, CacheState.INVALID); } else if (identical(descriptor, DartEntry.SOURCE_KIND)) { return identical(_sourceKindState, CacheState.INVALID); + } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) { + return identical(_tokenStreamState, CacheState.INVALID); } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) { DartEntryImpl_ResolutionState state = _resolutionState; while (state != null) { @@ -1810,6 +1950,10 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { void invalidateAllInformation() { super.invalidateAllInformation(); + _scanErrors = AnalysisError.NO_ERRORS; + _scanErrorsState = CacheState.INVALID; + _tokenStream = null; + _tokenStreamState = CacheState.INVALID; _sourceKind = SourceKind.UNKNOWN; _sourceKindState = CacheState.INVALID; _parseErrors = AnalysisError.NO_ERRORS; @@ -1902,7 +2046,6 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { * as being in error. */ void recordParseError() { - setState(SourceEntry.LINE_INFO, CacheState.ERROR); _sourceKind = SourceKind.UNKNOWN; _sourceKindState = CacheState.ERROR; _parseErrors = AnalysisError.NO_ERRORS; @@ -1919,9 +2062,6 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { * the current thread. */ void recordParseInProcess() { - if (getState(SourceEntry.LINE_INFO) != CacheState.VALID) { - setState(SourceEntry.LINE_INFO, CacheState.IN_PROCESS); - } if (_sourceKindState != CacheState.VALID) { _sourceKindState = CacheState.IN_PROCESS; } @@ -1988,6 +2128,52 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { _resolutionState.recordResolutionNotInProcess(); } + /** + * Record that an error occurred while attempting to scan or parse the entry represented by this + * entry. This will set the state of all information, including any resolution-based information, + * as being in error. + */ + void recordScanError() { + setState(SourceEntry.LINE_INFO, CacheState.ERROR); + _scanErrors = AnalysisError.NO_ERRORS; + _scanErrorsState = CacheState.ERROR; + _tokenStream = null; + _tokenStreamState = CacheState.ERROR; + recordParseError(); + } + + /** + * Record that the scan-related information for the associated source is about to be computed by + * the current thread. + */ + void recordScanInProcess() { + if (getState(SourceEntry.LINE_INFO) != CacheState.VALID) { + setState(SourceEntry.LINE_INFO, CacheState.IN_PROCESS); + } + if (_scanErrorsState != CacheState.VALID) { + _scanErrorsState = CacheState.IN_PROCESS; + } + if (_tokenStreamState != CacheState.VALID) { + _tokenStreamState = CacheState.IN_PROCESS; + } + } + + /** + * Record that an in-process scan has stopped without recording results because the results were + * invalidated before they could be recorded. + */ + void recordScanNotInProcess() { + if (identical(getState(SourceEntry.LINE_INFO), CacheState.IN_PROCESS)) { + setState(SourceEntry.LINE_INFO, CacheState.INVALID); + } + if (identical(_scanErrorsState, CacheState.IN_PROCESS)) { + _scanErrorsState = CacheState.INVALID; + } + if (identical(_tokenStreamState, CacheState.IN_PROCESS)) { + _tokenStreamState = CacheState.INVALID; + } + } + /** * Remove the given library from the list of libraries that contain this part. This method should * only be invoked on entries that represent a part. @@ -2039,30 +2225,6 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { _containingLibraries.add(librarySource); } - /** - * Set the results of parsing the compilation unit at the given time to the given values. - * - * @param modificationStamp the earliest time at which the source was last modified before the - * parsing was started - * @param lineInfo the line information resulting from parsing the compilation unit - * @param unit the AST structure resulting from parsing the compilation unit - * @param errors the parse errors resulting from parsing the compilation unit - */ - void setParseResults(int modificationStamp, LineInfo lineInfo, CompilationUnit unit, List errors) { - if (getState(SourceEntry.LINE_INFO) != CacheState.VALID) { - setValue(SourceEntry.LINE_INFO, lineInfo); - } - if (_parsedUnitState != CacheState.VALID) { - _parsedUnit = unit; - _parsedUnitAccessed = false; - _parsedUnitState = CacheState.VALID; - } - if (_parseErrorsState != CacheState.VALID) { - _parseErrors = errors == null ? AnalysisError.NO_ERRORS : errors; - _parseErrorsState = CacheState.VALID; - } - } - void setState(DataDescriptor descriptor, CacheState state) { if (identical(descriptor, DartEntry.ELEMENT)) { _element = updatedValue(state, _element, null); @@ -2095,9 +2257,15 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) { _publicNamespace = updatedValue(state, _publicNamespace, null); _publicNamespaceState = state; + } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) { + _scanErrors = updatedValue(state, _scanErrors, AnalysisError.NO_ERRORS); + _scanErrorsState = state; } else if (identical(descriptor, DartEntry.SOURCE_KIND)) { _sourceKind = updatedValue(state, _sourceKind, SourceKind.UNKNOWN); _sourceKindState = state; + } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) { + _tokenStream = updatedValue(state, _tokenStream, null); + _tokenStreamState = state; } else { super.setState(descriptor, state); } @@ -2132,7 +2300,9 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { } void setValue(DataDescriptor descriptor, Object value) { - if (identical(descriptor, DartEntry.ELEMENT)) { + if (identical(descriptor, DartEntry.ANGULAR_ERRORS)) { + _angularErrors = value == null ? AnalysisError.NO_ERRORS : (value as List); + } else if (identical(descriptor, DartEntry.ELEMENT)) { _element = value as LibraryElement; _elementState = CacheState.VALID; } else if (identical(descriptor, DartEntry.EXPORTED_LIBRARIES)) { @@ -2160,9 +2330,15 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) { _publicNamespace = value as Namespace; _publicNamespaceState = CacheState.VALID; + } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) { + _scanErrors = value == null ? AnalysisError.NO_ERRORS : (value as List); + _scanErrorsState = CacheState.VALID; } else if (identical(descriptor, DartEntry.SOURCE_KIND)) { _sourceKind = value as SourceKind; _sourceKindState = CacheState.VALID; + } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) { + _tokenStream = value as Token; + _tokenStreamState = CacheState.VALID; } else { super.setValue(descriptor, value); } @@ -2197,6 +2373,10 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { void copyFrom(SourceEntryImpl entry) { super.copyFrom(entry); DartEntryImpl other = entry as DartEntryImpl; + _scanErrorsState = other._scanErrorsState; + _scanErrors = other._scanErrors; + _tokenStreamState = other._tokenStreamState; + _tokenStream = other._tokenStream; _sourceKindState = other._sourceKindState; _sourceKind = other._sourceKind; _parsedUnitState = other._parsedUnitState; @@ -2219,13 +2399,18 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry { _clientServerState = other._clientServerState; _launchableState = other._launchableState; _bitmask = other._bitmask; + _angularErrors = other._angularErrors; } - bool hasErrorState() => super.hasErrorState() || identical(_sourceKindState, CacheState.ERROR) || identical(_parsedUnitState, CacheState.ERROR) || identical(_parseErrorsState, CacheState.ERROR) || identical(_importedLibrariesState, CacheState.ERROR) || identical(_exportedLibrariesState, CacheState.ERROR) || identical(_includedPartsState, CacheState.ERROR) || identical(_elementState, CacheState.ERROR) || identical(_publicNamespaceState, CacheState.ERROR) || identical(_clientServerState, CacheState.ERROR) || identical(_launchableState, CacheState.ERROR) || _resolutionState.hasErrorState(); + bool hasErrorState() => super.hasErrorState() || identical(_scanErrorsState, CacheState.ERROR) || identical(_tokenStreamState, CacheState.ERROR) || identical(_sourceKindState, CacheState.ERROR) || identical(_parsedUnitState, CacheState.ERROR) || identical(_parseErrorsState, CacheState.ERROR) || identical(_importedLibrariesState, CacheState.ERROR) || identical(_exportedLibrariesState, CacheState.ERROR) || identical(_includedPartsState, CacheState.ERROR) || identical(_elementState, CacheState.ERROR) || identical(_publicNamespaceState, CacheState.ERROR) || identical(_clientServerState, CacheState.ERROR) || identical(_launchableState, CacheState.ERROR) || _resolutionState.hasErrorState(); void writeOn(JavaStringBuilder builder) { builder.append("Dart: "); super.writeOn(builder); + builder.append("; tokenStream = "); + builder.append(_tokenStreamState); + builder.append("; scanErrors = "); + builder.append(_scanErrorsState); builder.append("; sourceKind = "); builder.append(_sourceKindState); builder.append("; parsedUnit = "); @@ -2529,7 +2714,7 @@ abstract class HtmlEntry implements SourceEntry { * The data descriptor representing the information about an Angular application this source is * used in. */ - static final DataDescriptor ANGULAR_APPLICATION = new DataDescriptor("HtmlEntry.ANGULAR_APPLICATION"); + static final DataDescriptor ANGULAR_APPLICATION = new DataDescriptor("HtmlEntry.ANGULAR_APPLICATION"); /** * The data descriptor representing the information about an Angular component this source is used @@ -2541,7 +2726,7 @@ abstract class HtmlEntry implements SourceEntry { * The data descriptor representing the information about an Angular application this source is * entry point for. */ - static final DataDescriptor ANGULAR_ENTRY = new DataDescriptor("HtmlEntry.ANGULAR_ENTRY"); + static final DataDescriptor ANGULAR_ENTRY = new DataDescriptor("HtmlEntry.ANGULAR_ENTRY"); /** * The data descriptor representing the errors reported during Angular resolution. @@ -2678,17 +2863,17 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry { /** * Information about the Angular Application this unit is used in. */ - AngularApplicationInfo _angularApplication; + AngularApplication _angularApplication; /** * The state of the [angularEntry]. */ - CacheState _angularEntryState = CacheState.VALID; + CacheState _angularEntryState = CacheState.INVALID; /** * Information about the Angular Application this unit is entry point for. */ - AngularApplicationInfo _angularEntry = null; + AngularApplication _angularEntry = null; /** * The state of the [angularComponent]. @@ -2855,6 +3040,8 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry { * Invalidate all of the resolution information associated with the HTML file. */ void invalidateAllResolutionInformation() { + _angularEntry = null; + _angularEntryState = CacheState.INVALID; _angularErrors = AnalysisError.NO_ERRORS; _angularErrorsState = CacheState.INVALID; _element = null; @@ -2930,13 +3117,13 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry { void setValue(DataDescriptor descriptor, Object value) { if (identical(descriptor, HtmlEntry.ANGULAR_APPLICATION)) { - _angularApplication = value as AngularApplicationInfo; + _angularApplication = value as AngularApplication; _angularApplicationState = CacheState.VALID; } else if (identical(descriptor, HtmlEntry.ANGULAR_COMPONENT)) { _angularComponent = value as AngularComponentElement; _angularComponentState = CacheState.VALID; } else if (identical(descriptor, HtmlEntry.ANGULAR_ENTRY)) { - _angularEntry = value as AngularApplicationInfo; + _angularEntry = value as AngularApplication; _angularEntryState = CacheState.VALID; } else if (identical(descriptor, HtmlEntry.ANGULAR_ERRORS)) { _angularErrors = value as List; @@ -3293,8 +3480,14 @@ abstract class SourceEntryImpl implements SourceEntry { class AnalysisContentStatisticsImpl implements AnalysisContentStatistics { Map _dataMap = new Map(); + List _sources = new List(); + Set _exceptions = new Set(); + void addSource(Source source) { + _sources.add(source); + } + List get cacheRows { Iterable items = _dataMap.values; return new List.from(items); @@ -3302,12 +3495,14 @@ class AnalysisContentStatisticsImpl implements AnalysisContentStatistics { List get exceptions => new List.from(_exceptions); - void putCacheItem(DartEntry dartEntry, DataDescriptor descriptor) { - putCacheItem3(dartEntry, descriptor, dartEntry.getState(descriptor)); + List get sources => new List.from(_sources); + + void putCacheItem(DartEntry dartEntry, Source librarySource, DataDescriptor descriptor) { + putCacheItem3(dartEntry, descriptor, dartEntry.getState2(descriptor, librarySource)); } - void putCacheItem2(DartEntry dartEntry, Source librarySource, DataDescriptor descriptor) { - putCacheItem3(dartEntry, descriptor, dartEntry.getState2(descriptor, librarySource)); + void putCacheItem2(SourceEntry dartEntry, DataDescriptor descriptor) { + putCacheItem3(dartEntry, descriptor, dartEntry.getState(descriptor)); } void putCacheItem3(SourceEntry dartEntry, DataDescriptor rowDesc, CacheState state) { @@ -3394,6 +3589,11 @@ class AnalysisContextImpl implements InternalAnalysisContext { */ AnalysisOptionsImpl _options = new AnalysisOptionsImpl(); + /** + * A cache of content used to override the default content of a source. + */ + ContentCache _contentCache = new ContentCache(); + /** * The source factory used to create the sources that can be analyzed in this context. */ @@ -3449,6 +3649,11 @@ class AnalysisContextImpl implements InternalAnalysisContext { */ WorkManager _workManager = new WorkManager(); + /** + * The set of [AngularApplication] in this context. + */ + Set _angularApplications = new Set(); + /** * Initialize a newly created analysis context. */ @@ -3560,24 +3765,34 @@ class AnalysisContextImpl implements InternalAnalysisContext { SourceEntry sourceEntry = getReadableSourceEntry(source); if (sourceEntry is DartEntry) { List errors = new List(); - DartEntry dartEntry = sourceEntry; - ListUtilities.addAll(errors, getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS)); - dartEntry = getReadableDartEntry(source); - if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) { - ListUtilities.addAll(errors, getDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS)); - ListUtilities.addAll(errors, getDartVerificationData(source, source, dartEntry, DartEntry.VERIFICATION_ERRORS)); - if (enableHints) { - ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry, DartEntry.HINTS)); - } - } else { - List libraries = getLibrariesContaining(source); - for (Source librarySource in libraries) { - ListUtilities.addAll(errors, getDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS)); - ListUtilities.addAll(errors, getDartVerificationData(source, librarySource, dartEntry, DartEntry.VERIFICATION_ERRORS)); + try { + DartEntry dartEntry = sourceEntry; + ListUtilities.addAll(errors, getDartScanData(source, dartEntry, DartEntry.SCAN_ERRORS)); + dartEntry = getReadableDartEntry(source); + ListUtilities.addAll(errors, getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS)); + dartEntry = getReadableDartEntry(source); + if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) { + ListUtilities.addAll(errors, getDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS)); + dartEntry = getReadableDartEntry(source); + ListUtilities.addAll(errors, getDartVerificationData(source, source, dartEntry, DartEntry.VERIFICATION_ERRORS)); if (enableHints) { - ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS)); + dartEntry = getReadableDartEntry(source); + ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry, DartEntry.HINTS)); + } + } else { + List libraries = getLibrariesContaining(source); + for (Source librarySource in libraries) { + ListUtilities.addAll(errors, getDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS)); + dartEntry = getReadableDartEntry(source); + ListUtilities.addAll(errors, getDartVerificationData(source, librarySource, dartEntry, DartEntry.VERIFICATION_ERRORS)); + if (enableHints) { + dartEntry = getReadableDartEntry(source); + ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS)); + } } } + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not compute errors", exception); } if (errors.isEmpty) { return AnalysisError.NO_ERRORS; @@ -3585,7 +3800,11 @@ class AnalysisContextImpl implements InternalAnalysisContext { return new List.from(errors); } else if (sourceEntry is HtmlEntry) { HtmlEntry htmlEntry = sourceEntry; - return getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS); + try { + return getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS); + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not compute errors", exception); + } } return AnalysisError.NO_ERRORS; } @@ -3614,10 +3833,14 @@ class AnalysisContextImpl implements InternalAnalysisContext { LineInfo computeLineInfo(Source source) { SourceEntry sourceEntry = getReadableSourceEntry(source); - if (sourceEntry is HtmlEntry) { - return getHtmlParseData(source, SourceEntry.LINE_INFO, null); - } else if (sourceEntry is DartEntry) { - return getDartParseData2(source, SourceEntry.LINE_INFO, null); + try { + if (sourceEntry is HtmlEntry) { + return getHtmlParseData(source, SourceEntry.LINE_INFO, null); + } else if (sourceEntry is DartEntry) { + return getDartScanData2(source, SourceEntry.LINE_INFO, null); + } + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not compute ${SourceEntry.LINE_INFO.toString()}", exception); } return null; } @@ -3668,6 +3891,16 @@ class AnalysisContextImpl implements InternalAnalysisContext { return new ResolvableHtmlUnit(htmlEntry.modificationTime, unit); } + bool exists(Source source) { + if (source == null) { + return false; + } + if (_contentCache.getContents(source) != null) { + return true; + } + return source.exists(); + } + AnalysisContext extractContext(SourceContainer container) => extractContextInto(container, AnalysisEngine.instance.createAnalysisContext() as InternalAnalysisContext); InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) { @@ -3687,6 +3920,41 @@ class AnalysisContextImpl implements InternalAnalysisContext { AnalysisOptions get analysisOptions => _options; + CompilationUnitElement getCompilationUnitElement(Source unitSource, Source librarySource) { + LibraryElement libraryElement = getLibraryElement(librarySource); + if (libraryElement != null) { + // try defining unit + CompilationUnitElement definingUnit = libraryElement.definingCompilationUnit; + if (definingUnit.source == unitSource) { + return definingUnit; + } + // try parts + for (CompilationUnitElement partUnit in libraryElement.parts) { + if (partUnit.source == unitSource) { + return partUnit; + } + } + } + return null; + } + + TimestampedData getContents(Source source) { + String contents = _contentCache.getContents(source); + if (contents != null) { + return new TimestampedData(_contentCache.getModificationStamp(source), contents); + } + return source.contents; + } + + void getContentsToReceiver(Source source, Source_ContentReceiver receiver) { + String contents = _contentCache.getContents(source); + if (contents != null) { + receiver.accept(contents, _contentCache.getModificationStamp(source)); + return; + } + source.getContentsToReceiver(receiver); + } + Element getElement(ElementLocation location) { // TODO(brianwilkerson) This should not be a "get" method. try { @@ -3848,6 +4116,14 @@ class AnalysisContextImpl implements InternalAnalysisContext { return null; } + int getModificationStamp(Source source) { + int stamp = _contentCache.getModificationStamp(source); + if (stamp != null) { + return stamp; + } + return source.modificationStamp; + } + Namespace getPublicNamespace(LibraryElement library) { // TODO(brianwilkerson) Rename this to not start with 'get'. Note that this is not part of the // API of the interface. @@ -3981,32 +4257,41 @@ class AnalysisContextImpl implements InternalAnalysisContext { AnalysisContentStatisticsImpl statistics = new AnalysisContentStatisticsImpl(); { for (MapEntry mapEntry in _cache.entrySet()) { + statistics.addSource(mapEntry.getKey()); SourceEntry entry = mapEntry.getValue(); if (entry is DartEntry) { Source source = mapEntry.getKey(); DartEntry dartEntry = entry; SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND); // get library independent values - statistics.putCacheItem(dartEntry, DartEntry.PARSE_ERRORS); - statistics.putCacheItem(dartEntry, DartEntry.PARSED_UNIT); - statistics.putCacheItem(dartEntry, DartEntry.SOURCE_KIND); - statistics.putCacheItem(dartEntry, SourceEntry.LINE_INFO); + statistics.putCacheItem2(dartEntry, SourceEntry.LINE_INFO); + statistics.putCacheItem2(dartEntry, DartEntry.PARSE_ERRORS); + statistics.putCacheItem2(dartEntry, DartEntry.PARSED_UNIT); + statistics.putCacheItem2(dartEntry, DartEntry.SOURCE_KIND); if (identical(kind, SourceKind.LIBRARY)) { - statistics.putCacheItem(dartEntry, DartEntry.ELEMENT); - statistics.putCacheItem(dartEntry, DartEntry.EXPORTED_LIBRARIES); - statistics.putCacheItem(dartEntry, DartEntry.IMPORTED_LIBRARIES); - statistics.putCacheItem(dartEntry, DartEntry.INCLUDED_PARTS); - statistics.putCacheItem(dartEntry, DartEntry.IS_CLIENT); - statistics.putCacheItem(dartEntry, DartEntry.IS_LAUNCHABLE); + statistics.putCacheItem2(dartEntry, DartEntry.ELEMENT); + statistics.putCacheItem2(dartEntry, DartEntry.EXPORTED_LIBRARIES); + statistics.putCacheItem2(dartEntry, DartEntry.IMPORTED_LIBRARIES); + statistics.putCacheItem2(dartEntry, DartEntry.INCLUDED_PARTS); + statistics.putCacheItem2(dartEntry, DartEntry.IS_CLIENT); + statistics.putCacheItem2(dartEntry, DartEntry.IS_LAUNCHABLE); } // get library-specific values List librarySources = getLibrariesContaining(source); for (Source librarySource in librarySources) { - statistics.putCacheItem2(dartEntry, librarySource, DartEntry.HINTS); - statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS); - statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLVED_UNIT); - statistics.putCacheItem2(dartEntry, librarySource, DartEntry.VERIFICATION_ERRORS); + statistics.putCacheItem(dartEntry, librarySource, DartEntry.HINTS); + statistics.putCacheItem(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS); + statistics.putCacheItem(dartEntry, librarySource, DartEntry.RESOLVED_UNIT); + statistics.putCacheItem(dartEntry, librarySource, DartEntry.VERIFICATION_ERRORS); } + } else if (entry is HtmlEntry) { + HtmlEntry htmlEntry = entry; + statistics.putCacheItem2(htmlEntry, SourceEntry.LINE_INFO); + statistics.putCacheItem2(htmlEntry, HtmlEntry.PARSE_ERRORS); + statistics.putCacheItem2(htmlEntry, HtmlEntry.PARSED_UNIT); + statistics.putCacheItem2(htmlEntry, HtmlEntry.RESOLUTION_ERRORS); + statistics.putCacheItem2(htmlEntry, HtmlEntry.RESOLVED_UNIT); + statistics.putCacheItem2(htmlEntry, HtmlEntry.HINTS); } } } @@ -4018,6 +4303,19 @@ class AnalysisContextImpl implements InternalAnalysisContext { return new TypeProviderImpl(computeLibraryElement(coreSource)); } + TimestampedData internalParseCompilationUnit(Source source) { + DartEntry dartEntry = getReadableDartEntry(source); + if (dartEntry == null) { + throw new AnalysisException.con1("internalParseCompilationUnit invoked for non-Dart file: ${source.fullName}"); + } + dartEntry = cacheDartParseData(source, dartEntry, DartEntry.PARSED_UNIT); + CompilationUnit unit = dartEntry.anyParsedCompilationUnit; + if (unit == null) { + throw new AnalysisException.con2("internalParseCompilationUnit could not cache a parsed unit: ${source.fullName}", dartEntry.exception); + } + return new TimestampedData(dartEntry.modificationTime, unit); + } + TimestampedData internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement) { DartEntry dartEntry = getReadableDartEntry(unitSource); if (dartEntry == null) { @@ -4028,6 +4326,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { return new TimestampedData(dartEntry.modificationTime, dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource)); } + TimestampedData internalScanTokenStream(Source source) { + DartEntry dartEntry = getReadableDartEntry(source); + if (dartEntry == null) { + throw new AnalysisException.con1("internalScanTokenStream invoked for non-Dart file: ${source.fullName}"); + } + dartEntry = cacheDartScanData(source, dartEntry, DartEntry.TOKEN_STREAM); + return new TimestampedData(dartEntry.modificationTime, dartEntry.getValue(DartEntry.TOKEN_STREAM)); + } + bool isClientLibrary(Source librarySource) { SourceEntry sourceEntry = getReadableSourceEntry(librarySource); if (sourceEntry is DartEntry) { @@ -4090,6 +4397,8 @@ class AnalysisContextImpl implements InternalAnalysisContext { int performStart = JavaSystem.currentTimeMillis(); try { task.perform(_resultRecorder); + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not perform analysis task: ${taskDescriptor}", exception); } on AnalysisException catch (exception) { if (exception.cause is! JavaIOException) { AnalysisEngine.instance.logger.logError2("Internal error while performing the task: ${task}", exception); @@ -4189,7 +4498,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { void setChangedContents(Source source, String contents, int offset, int oldLength, int newLength) { { _recentTasks.clear(); - String originalContents = _sourceFactory.setContents(source, contents); + String originalContents = _contentCache.setContents(source, contents); if (contents != null) { if (contents != originalContents) { if (_options.incremental) { @@ -4207,7 +4516,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { void setContents(Source source, String contents) { { _recentTasks.clear(); - String originalContents = _sourceFactory.setContents(source, contents); + String originalContents = _contentCache.setContents(source, contents); if (contents != null) { if (contents != originalContents) { _incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source); @@ -4236,16 +4545,6 @@ class AnalysisContextImpl implements InternalAnalysisContext { } } - Iterable sourcesToResolve(List changedSources) { - List librarySources = new List(); - for (Source source in changedSources) { - if (identical(computeKindOf(source), SourceKind.LIBRARY)) { - librarySources.add(source); - } - } - return librarySources; - } - /** * Record the results produced by performing a [ResolveDartLibraryTask]. If the results were * computed from data that is now out-of-date, then the results will not be recorded. @@ -4294,7 +4593,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { List errors = errorListener.getErrors2(source); LineInfo lineInfo = getLineInfo(source); DartEntry dartEntry = _cache.get(source) as DartEntry; - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); if (dartEntry.modificationTime != sourceTime) { // The source has changed without the context being notified. Simulate notification. sourceChanged(source); @@ -4338,7 +4637,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { DartEntry dartEntry = getReadableDartEntry(source); if (dartEntry != null) { int resultTime = library.getModificationTime(source); - writer.println(" ${debuggingString(source)}; sourceTime = ${source.modificationStamp}, resultTime = ${resultTime}, cacheTime = ${dartEntry.modificationTime}"); + writer.println(" ${debuggingString(source)}; sourceTime = ${getModificationStamp(source)}, resultTime = ${resultTime}, cacheTime = ${dartEntry.modificationTime}"); DartEntryImpl dartCopy = dartEntry.writableCopy; if (thrownException == null || resultTime >= 0) { // @@ -4361,7 +4660,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { unitEntry = dartCopy; } } else { - writer.println(" ${debuggingString(source)}; sourceTime = ${source.modificationStamp}, no entry"); + writer.println(" ${debuggingString(source)}; sourceTime = ${getModificationStamp(source)}, no entry"); } } } @@ -4429,7 +4728,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { // source didn't represent a Dart file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to resolve non-Dart file as a Dart file: ${source.fullName}"); } - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); int resultTime = library.getModificationTime(source); if (sourceTime != resultTime) { // The source has changed without the context being notified. Simulate notification. @@ -4508,8 +4807,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { * @param dartEntry the cache entry associated with the Dart file * @param descriptor the descriptor representing the data to be returned * @return a cache entry containing the required data - * @throws AnalysisException if data could not be returned because the source could not be - * resolved + * @throws AnalysisException if data could not be returned because the source could not be parsed */ DartEntry cacheDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) { if (identical(descriptor, DartEntry.PARSED_UNIT)) { @@ -4564,6 +4862,42 @@ class AnalysisContextImpl implements InternalAnalysisContext { return dartEntry; } + /** + * Given a source for a Dart file, return a cache entry in which the state of the data represented + * by the given descriptor is either [CacheState#VALID] or [CacheState#ERROR]. This + * method assumes that the data can be produced by scanning the source if it is not already + * cached. + * + * @param source the source representing the Dart file + * @param dartEntry the cache entry associated with the Dart file + * @param descriptor the descriptor representing the data to be returned + * @return a cache entry containing the required data + * @throws AnalysisException if data could not be returned because the source could not be scanned + */ + DartEntry cacheDartScanData(Source source, DartEntry dartEntry, DataDescriptor descriptor) { + // + // Check to see whether we already have the information being requested. + // + CacheState state = dartEntry.getState(descriptor); + while (state != CacheState.ERROR && state != CacheState.VALID) { + // + // If not, compute the information. Unless the modification date of the source continues to + // change, this loop will eventually terminate. + // + // TODO(brianwilkerson) Convert this to get the contents from the cache. (I'm not sure how + // that would work in an asynchronous environment.) + try { + dartEntry = new ScanDartTask(this, source, getContents(source)).perform(_resultRecorder) as DartEntry; + } on AnalysisException catch (exception) { + throw exception; + } on JavaException catch (exception) { + throw new AnalysisException.con3(exception); + } + state = dartEntry.getState(descriptor); + } + return dartEntry; + } + /** * Given a source for a Dart file and the library that contains it, return a cache entry in which * the state of the data represented by the given descriptor is either [CacheState#VALID] or @@ -4712,12 +5046,12 @@ class AnalysisContextImpl implements InternalAnalysisContext { String name = source.shortName; if (AnalysisEngine.isHtmlFileName(name)) { HtmlEntryImpl htmlEntry = new HtmlEntryImpl(); - htmlEntry.modificationTime = source.modificationStamp; + htmlEntry.modificationTime = getModificationStamp(source); _cache.put(source, htmlEntry); return htmlEntry; } else { DartEntryImpl dartEntry = new DartEntryImpl(); - dartEntry.modificationTime = source.modificationStamp; + dartEntry.modificationTime = getModificationStamp(source); _cache.put(source, dartEntry); return dartEntry; } @@ -4730,7 +5064,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { * @param source the source for which a debugging string is to be produced * @return debugging information about the given source */ - String debuggingString(Source source) => "'${source.fullName}' [${source.modificationStamp}]"; + String debuggingString(Source source) => "'${source.fullName}' [${getModificationStamp(source)}]"; /** * Return an array containing all of the change notices that are waiting to be returned. If there @@ -4787,7 +5121,12 @@ class AnalysisContextImpl implements InternalAnalysisContext { if (dartEntry == null) { return defaultValue; } - return getDartDependencyData(source, dartEntry, descriptor); + try { + return getDartDependencyData(source, dartEntry, descriptor); + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception); + return defaultValue; + } } /** @@ -4847,7 +5186,12 @@ class AnalysisContextImpl implements InternalAnalysisContext { if (dartEntry == null) { return defaultValue; } - return getDartParseData(source, dartEntry, descriptor); + try { + return getDartParseData(source, dartEntry, descriptor); + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception); + return defaultValue; + } } /** @@ -4892,7 +5236,53 @@ class AnalysisContextImpl implements InternalAnalysisContext { if (dartEntry == null) { return defaultValue; } - return getDartResolutionData(unitSource, librarySource, dartEntry, descriptor); + try { + return getDartResolutionData(unitSource, librarySource, dartEntry, descriptor); + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception); + return defaultValue; + } + } + + /** + * Given a source for a Dart file, return the data represented by the given descriptor that is + * associated with that source. This method assumes that the data can be produced by scanning the + * source if it is not already cached. + * + * @param source the source representing the Dart file + * @param dartEntry the cache entry associated with the Dart file + * @param descriptor the descriptor representing the data to be returned + * @return the requested data about the given source + * @throws AnalysisException if data could not be returned because the source could not be scanned + */ + Object getDartScanData(Source source, DartEntry dartEntry, DataDescriptor descriptor) { + dartEntry = cacheDartScanData(source, dartEntry, descriptor); + return dartEntry.getValue(descriptor); + } + + /** + * Given a source for a Dart file, return the data represented by the given descriptor that is + * associated with that source, or the given default value if the source is not a Dart file. This + * method assumes that the data can be produced by scanning the source if it is not already + * cached. + * + * @param source the source representing the Dart file + * @param descriptor the descriptor representing the data to be returned + * @param defaultValue the value to be returned if the source is not a Dart file + * @return the requested data about the given source + * @throws AnalysisException if data could not be returned because the source could not be scanned + */ + Object getDartScanData2(Source source, DataDescriptor descriptor, Object defaultValue) { + DartEntry dartEntry = getReadableDartEntry(source); + if (dartEntry == null) { + return defaultValue; + } + try { + return getDartScanData(source, dartEntry, descriptor); + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception); + return defaultValue; + } } /** @@ -4955,7 +5345,12 @@ class AnalysisContextImpl implements InternalAnalysisContext { if (htmlEntry == null) { return defaultValue; } - return getHtmlResolutionData2(source, htmlEntry, descriptor); + try { + return getHtmlResolutionData2(source, htmlEntry, descriptor); + } on ObsoleteSourceAnalysisException catch (exception) { + AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception); + return defaultValue; + } } /** @@ -4987,6 +5382,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { AnalysisTask get nextAnalysisTask { { bool hintsEnabled = _options.hint; + bool sdkErrorsEnabled = _options.generateSdkErrors; // // Look for incremental analysis // @@ -4999,7 +5395,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { // Look for a priority source that needs to be analyzed. // for (Source source in _priorityOrder) { - AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), true, hintsEnabled); + AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), true, hintsEnabled, sdkErrorsEnabled); if (task != null) { return task; } @@ -5009,7 +5405,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { // Source source = _workManager.nextSource; while (source != null) { - AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), false, hintsEnabled); + AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), false, hintsEnabled, sdkErrorsEnabled); if (task != null) { return task; } @@ -5042,11 +5438,29 @@ class AnalysisContextImpl implements InternalAnalysisContext { * @param sourceEntry the cache entry associated with the source * @param isPriority `true` if the source is a priority source * @param hintsEnabled `true` if hints are currently enabled + * @param sdkErrorsEnabled `true` if errors, warnings and hints should be generated for + * sources in the SDK * @return the next task that needs to be performed for the given source */ - AnalysisTask getNextAnalysisTask2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled) { + AnalysisTask getNextAnalysisTask2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, bool sdkErrorsEnabled) { if (sourceEntry is DartEntry) { DartEntry dartEntry = sourceEntry; + CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS); + if (identical(scanErrorsState, CacheState.INVALID) || (isPriority && identical(scanErrorsState, CacheState.FLUSHED))) { + // TODO(brianwilkerson) Convert this to get the contents from the cache or to asynchronously + // request the contents if they are not in the cache. + try { + DartEntryImpl dartCopy = dartEntry.writableCopy; + dartCopy.setState(DartEntry.SCAN_ERRORS, CacheState.IN_PROCESS); + _cache.put(source, dartCopy); + return new ScanDartTask(this, source, getContents(source)); + } on JavaException catch (exception) { + DartEntryImpl dartCopy = dartEntry.writableCopy; + dartCopy.recordScanError(); + dartCopy.exception = new AnalysisException.con3(exception); + _cache.put(source, dartCopy); + } + } CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS); if (identical(parseErrorsState, CacheState.INVALID) || (isPriority && identical(parseErrorsState, CacheState.FLUSHED))) { DartEntryImpl dartCopy = dartEntry.writableCopy; @@ -5096,25 +5510,27 @@ class AnalysisContextImpl implements InternalAnalysisContext { //return new ResolveDartUnitTask(this, source, libraryElement); return new ResolveDartLibraryTask(this, source, librarySource); } - CacheState verificationErrorsState = dartEntry.getState2(DartEntry.VERIFICATION_ERRORS, librarySource); - if (identical(verificationErrorsState, CacheState.INVALID) || (isPriority && identical(verificationErrorsState, CacheState.FLUSHED))) { - LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT); - if (libraryElement != null) { - DartEntryImpl dartCopy = dartEntry.writableCopy; - dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, CacheState.IN_PROCESS); - _cache.put(source, dartCopy); - return new GenerateDartErrorsTask(this, source, libraryElement); - } - } - if (hintsEnabled) { - CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, librarySource); - if (identical(hintsState, CacheState.INVALID) || (isPriority && identical(hintsState, CacheState.FLUSHED))) { + if (sdkErrorsEnabled || !source.isInSystemLibrary) { + CacheState verificationErrorsState = dartEntry.getState2(DartEntry.VERIFICATION_ERRORS, librarySource); + if (identical(verificationErrorsState, CacheState.INVALID) || (isPriority && identical(verificationErrorsState, CacheState.FLUSHED))) { LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT); if (libraryElement != null) { DartEntryImpl dartCopy = dartEntry.writableCopy; - dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.IN_PROCESS); + dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, CacheState.IN_PROCESS); _cache.put(source, dartCopy); - return new GenerateDartHintsTask(this, libraryElement); + return new GenerateDartErrorsTask(this, source, libraryElement); + } + } + if (hintsEnabled) { + CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, librarySource); + if (identical(hintsState, CacheState.INVALID) || (isPriority && identical(hintsState, CacheState.FLUSHED))) { + LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT); + if (libraryElement != null) { + DartEntryImpl dartCopy = dartEntry.writableCopy; + dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.IN_PROCESS); + _cache.put(source, dartCopy); + return new GenerateDartHintsTask(this, libraryElement); + } } } } @@ -5145,29 +5561,26 @@ class AnalysisContextImpl implements InternalAnalysisContext { _cache.put(source, htmlCopy); return new ResolveHtmlTask(this, source); } + // Angular support if (_options.analyzeAngular) { + // try to resolve as an Angular entry point + CacheState angularEntryState = htmlEntry.getState(HtmlEntry.ANGULAR_ENTRY); + if (identical(angularEntryState, CacheState.INVALID)) { + HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; + htmlCopy.setState(HtmlEntry.ANGULAR_ENTRY, CacheState.IN_PROCESS); + _cache.put(source, htmlCopy); + return new ResolveAngularEntryHtmlTask(this, source); + } + // try to resolve as an Angular application part CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS); if (identical(angularErrorsState, CacheState.INVALID)) { - AngularApplicationInfo entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY); - if (entryInfo != null) { - HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; - htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS); - _cache.put(source, htmlCopy); - return new ResolveAngularEntryHtmlTask(this, source, entryInfo); - } - AngularApplicationInfo applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION); - if (applicationInfo != null) { - AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT); - if (component != null) { - HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; - htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS); - _cache.put(source, htmlCopy); - return new ResolveAngularComponentTemplateTask(this, source, component, applicationInfo); - } - } + AngularApplication application = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION); + // try to resolve as an Angular template + AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT); HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; - htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS); + htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS); _cache.put(source, htmlCopy); + return new ResolveAngularComponentTemplateTask(this, source, component, application); } } } @@ -5282,6 +5695,11 @@ class AnalysisContextImpl implements InternalAnalysisContext { void getSourcesNeedingProcessing2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, Set sources) { if (sourceEntry is DartEntry) { DartEntry dartEntry = sourceEntry; + CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS); + if (identical(scanErrorsState, CacheState.INVALID) || (isPriority && identical(scanErrorsState, CacheState.FLUSHED))) { + sources.add(source); + return; + } CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS); if (identical(parseErrorsState, CacheState.INVALID) || (isPriority && identical(parseErrorsState, CacheState.FLUSHED))) { sources.add(source); @@ -5342,15 +5760,16 @@ class AnalysisContextImpl implements InternalAnalysisContext { sources.add(source); return; } + // Angular if (_options.analyzeAngular) { CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS); if (identical(angularErrorsState, CacheState.INVALID)) { - AngularApplicationInfo entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY); + AngularApplication entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY); if (entryInfo != null) { sources.add(source); return; } - AngularApplicationInfo applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION); + AngularApplication applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION); if (applicationInfo != null) { AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT); if (component != null) { @@ -5387,6 +5806,55 @@ class AnalysisContextImpl implements InternalAnalysisContext { } } + /** + * In response to a change to Angular entry point [HtmlElement], invalidate any results that + * depend on it. + * + * Note: This method must only be invoked while we are synchronized on [cacheLock]. + * + * Note: Any cache entries that were accessed before this method was invoked must be + * re-accessed after this method returns. + * + * @param entryCopy the [HtmlEntryImpl] of the (maybe) Angular entry point being invalidated + */ + void invalidateAngularResolution(HtmlEntryImpl entryCopy) { + AngularApplication application = entryCopy.getValue(HtmlEntry.ANGULAR_ENTRY); + if (application == null) { + return; + } + _angularApplications.remove(application); + // invalidate Entry + entryCopy.setState(HtmlEntry.ANGULAR_ENTRY, CacheState.INVALID); + // reset HTML sources + List oldAngularElements = application.elements; + for (AngularElement angularElement in oldAngularElements) { + if (angularElement is AngularHasTemplateElement) { + AngularHasTemplateElement hasTemplate = angularElement; + Source templateSource = hasTemplate.templateSource; + if (templateSource != null) { + HtmlEntry htmlEntry = getReadableHtmlEntry(templateSource); + HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; + htmlCopy.setValue(HtmlEntry.ANGULAR_APPLICATION, null); + htmlCopy.setValue(HtmlEntry.ANGULAR_COMPONENT, null); + htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.INVALID); + _cache.put(templateSource, htmlCopy); + _workManager.add(templateSource, SourcePriority.HTML); + } + } + } + // reset Dart sources + List oldElementSources = application.elementSources; + for (Source elementSource in oldElementSources) { + DartEntry dartEntry = getReadableDartEntry(elementSource); + DartEntryImpl dartCopy = dartEntry.writableCopy; + dartCopy.setValue(DartEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS); + _cache.put(elementSource, dartCopy); + // notify about (disappeared) Angular errors + ChangeNoticeImpl notice = getNotice(elementSource); + notice.setErrors(dartCopy.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO)); + } + } + /** * In response to a change to at least one of the compilation units in the given library, * invalidate any results that are dependent on the result of resolving that library. @@ -5431,6 +5899,18 @@ class AnalysisContextImpl implements InternalAnalysisContext { } } } + // invalidate Angular applications + List angularApplicationsCopy = []; + for (AngularApplication application in angularApplicationsCopy) { + if (application.dependsOn(librarySource)) { + Source entryPointSource = application.entryPoint; + HtmlEntry entry = getReadableHtmlEntry(entryPointSource); + HtmlEntryImpl entryCopy = entry.writableCopy; + invalidateAngularResolution(entryCopy); + _cache.put(entryPointSource, entryCopy); + _workManager.add(entryPointSource, SourcePriority.HTML); + } + } } /** @@ -5486,59 +5966,49 @@ class AnalysisContextImpl implements InternalAnalysisContext { } /** - * Updates [HtmlEntry]s that correspond to the previously known and new Angular components. - * - * @param library the [Library] that was resolved - * @param dartCopy the [DartEntryImpl] to record new Angular components + * Updates [HtmlEntry]s that correspond to the previously known and new Angular application + * information. */ - void recordAngularComponents(HtmlEntryImpl entry, AngularApplicationInfo app) { - if (!_options.analyzeAngular) { - return; - } - // reset old Angular errors - AngularApplicationInfo oldApp = entry.getValue(HtmlEntry.ANGULAR_ENTRY); - if (oldApp != null) { - List oldAngularElements = oldApp.elements; - for (AngularElement angularElement in oldAngularElements) { - if (angularElement is AngularComponentElement) { - AngularComponentElement component = angularElement; - Source templateSource = component.templateSource; - if (templateSource != null) { - HtmlEntry htmlEntry = getReadableHtmlEntry(templateSource); - HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; - htmlCopy.setValue(HtmlEntry.ANGULAR_APPLICATION, null); - htmlCopy.setValue(HtmlEntry.ANGULAR_COMPONENT, null); - htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS); - _cache.put(templateSource, htmlCopy); - // notify about (disappeared) HTML errors - ChangeNoticeImpl notice = getNotice(templateSource); - notice.setErrors(htmlCopy.allErrors, computeLineInfo(templateSource)); - } - } - } - } - // prepare for new Angular analysis - if (app != null) { - List newAngularElements = app.elements; + void recordAngularEntryPoint(HtmlEntryImpl entry, ResolveAngularEntryHtmlTask task) { + AngularApplication application = task.application; + if (application != null) { + _angularApplications.add(application); + // if this is an entry point, then we already resolved it + entry.setValue(HtmlEntry.ANGULAR_ERRORS, task.entryErrors); + // schedule HTML templates analysis + List newAngularElements = application.elements; for (AngularElement angularElement in newAngularElements) { - if (angularElement is AngularComponentElement) { - AngularComponentElement component = angularElement; - Source templateSource = component.templateSource; + if (angularElement is AngularHasTemplateElement) { + AngularHasTemplateElement hasTemplate = angularElement; + Source templateSource = hasTemplate.templateSource; if (templateSource != null) { HtmlEntry htmlEntry = getReadableHtmlEntry(templateSource); HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; - htmlCopy.setValue(HtmlEntry.ANGULAR_APPLICATION, app); - htmlCopy.setValue(HtmlEntry.ANGULAR_COMPONENT, component); + htmlCopy.setValue(HtmlEntry.ANGULAR_APPLICATION, application); + if (hasTemplate is AngularComponentElement) { + AngularComponentElement component = hasTemplate; + htmlCopy.setValue(HtmlEntry.ANGULAR_COMPONENT, component); + } htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.INVALID); _cache.put(templateSource, htmlCopy); _workManager.add(templateSource, SourcePriority.HTML); } } } + // update Dart sources errors + List newElementSources = application.elementSources; + for (Source elementSource in newElementSources) { + DartEntry dartEntry = getReadableDartEntry(elementSource); + DartEntryImpl dartCopy = dartEntry.writableCopy; + dartCopy.setValue(DartEntry.ANGULAR_ERRORS, task.getErrors(elementSource)); + _cache.put(elementSource, dartCopy); + // notify about Dart errors + ChangeNoticeImpl notice = getNotice(elementSource); + notice.setErrors(dartCopy.allErrors, computeLineInfo(elementSource)); + } } - // remember Angular application - entry.setValue(HtmlEntry.ANGULAR_ENTRY, app); - entry.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.INVALID); + // remember Angular entry point + entry.setValue(HtmlEntry.ANGULAR_ENTRY, application); } /** @@ -5591,13 +6061,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { DartEntry dartEntry = null; { SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry is! DartEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(source); + } else if (sourceEntry is! DartEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent a Dart file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to verify non-Dart file as a Dart file: ${source.fullName}"); } dartEntry = sourceEntry as DartEntry; - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); int resultTime = task.modificationTime; if (sourceTime == resultTime) { if (dartEntry.modificationTime != sourceTime) { @@ -5670,7 +6142,9 @@ class AnalysisContextImpl implements InternalAnalysisContext { // We don't have any information about which sources to mark as invalid other than the library // source. SourceEntry sourceEntry = _cache.get(librarySource); - if (sourceEntry is! DartEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(librarySource); + } else if (sourceEntry is! DartEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent a Dart file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to generate hints for non-Dart file as a Dart file: ${librarySource.fullName}"); @@ -5699,7 +6173,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { if (unitSource == librarySource) { libraryEntry = dartEntry; } - int sourceTime = unitSource.modificationStamp; + int sourceTime = getModificationStamp(unitSource); int resultTime = results.modificationTime; if (sourceTime == resultTime) { if (dartEntry.modificationTime != sourceTime) { @@ -5790,13 +6264,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { DartEntry dartEntry = null; { SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry is! DartEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(source); + } else if (sourceEntry is! DartEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent a Dart file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${source.fullName}"); } dartEntry = sourceEntry as DartEntry; - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); int resultTime = task.modificationTime; if (sourceTime == resultTime) { if (dartEntry.modificationTime != sourceTime) { @@ -5809,10 +6285,9 @@ class AnalysisContextImpl implements InternalAnalysisContext { } DartEntryImpl dartCopy = dartEntry.writableCopy; if (thrownException == null) { - LineInfo lineInfo = task.lineInfo; - dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo); if (task.hasPartOfDirective() && !task.hasLibraryDirective()) { dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.PART); + dartCopy.removeContainingLibrary(source); _workManager.add(source, SourcePriority.NORMAL_PART); } else { dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY); @@ -5823,7 +6298,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { dartCopy.setValue(DartEntry.PARSE_ERRORS, task.errors); _cache.storedAst(source); ChangeNoticeImpl notice = getNotice(source); - notice.setErrors(dartEntry.allErrors, lineInfo); + notice.setErrors(dartCopy.allErrors, dartCopy.getValue(SourceEntry.LINE_INFO)); // Verify that the incrementally parsed and resolved unit in the incremental cache // is structurally equivalent to the fully parsed unit _incrementalAnalysisCache = IncrementalAnalysisCache.verifyStructure(_incrementalAnalysisCache, source, task.compilationUnit); @@ -5882,13 +6357,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { HtmlEntry htmlEntry = null; { SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry is! HtmlEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(source); + } else if (sourceEntry is! HtmlEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent an HTML file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to parse non-HTML file as a HTML file: ${source.fullName}"); } htmlEntry = sourceEntry as HtmlEntry; - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); int resultTime = task.modificationTime; if (sourceTime == resultTime) { if (htmlEntry.modificationTime != sourceTime) { @@ -5909,7 +6386,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { htmlCopy.setValue(HtmlEntry.REFERENCED_LIBRARIES, task.referencedLibraries); _cache.storedAst(source); ChangeNoticeImpl notice = getNotice(source); - notice.setErrors(htmlEntry.allErrors, lineInfo); + notice.setErrors(htmlCopy.allErrors, lineInfo); } else { htmlCopy.recordParseError(); _cache.removedAst(source); @@ -5972,13 +6449,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { HtmlEntry htmlEntry = null; { SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry is! HtmlEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(source); + } else if (sourceEntry is! HtmlEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent an HTML file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as an HTML file: ${source.fullName}"); } htmlEntry = sourceEntry as HtmlEntry; - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); int resultTime = task.modificationTime; if (sourceTime == resultTime) { if (htmlEntry.modificationTime != sourceTime) { @@ -5992,6 +6471,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; if (thrownException == null) { htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, task.resolutionErrors); + // notify about errors ChangeNoticeImpl notice = getNotice(source); notice.htmlUnit = task.resolvedUnit; notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO)); @@ -6052,13 +6532,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { HtmlEntry htmlEntry = null; { SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry is! HtmlEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(source); + } else if (sourceEntry is! HtmlEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent an HTML file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as an HTML file: ${source.fullName}"); } htmlEntry = sourceEntry as HtmlEntry; - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); int resultTime = task.modificationTime; if (sourceTime == resultTime) { if (htmlEntry.modificationTime != sourceTime) { @@ -6071,7 +6553,9 @@ class AnalysisContextImpl implements InternalAnalysisContext { } HtmlEntryImpl htmlCopy = htmlEntry.writableCopy; if (thrownException == null) { - htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, task.resolutionErrors); + htmlCopy.setValue(HtmlEntry.RESOLVED_UNIT, task.resolvedUnit); + recordAngularEntryPoint(htmlCopy, task); + _cache.storedAst(source); ChangeNoticeImpl notice = getNotice(source); notice.htmlUnit = task.resolvedUnit; notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO)); @@ -6133,13 +6617,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { DartEntry dartEntry = null; { SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry is! DartEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(source); + } else if (sourceEntry is! DartEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent a Dart file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to resolve Dart dependencies in a non-Dart file: ${source.fullName}"); } dartEntry = sourceEntry as DartEntry; - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); int resultTime = task.modificationTime; if (sourceTime == resultTime) { if (dartEntry.modificationTime != sourceTime) { @@ -6222,13 +6708,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { DartEntry dartEntry = null; { SourceEntry sourceEntry = _cache.get(unitSource); - if (sourceEntry is! DartEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(unitSource); + } else if (sourceEntry is! DartEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent a Dart file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to resolve non-Dart file as a Dart file: ${unitSource.fullName}"); } dartEntry = sourceEntry as DartEntry; - int sourceTime = unitSource.modificationStamp; + int sourceTime = getModificationStamp(unitSource); int resultTime = task.modificationTime; if (sourceTime == resultTime) { if (dartEntry.modificationTime != sourceTime) { @@ -6299,13 +6787,15 @@ class AnalysisContextImpl implements InternalAnalysisContext { HtmlEntry htmlEntry = null; { SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry is! HtmlEntry) { + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(source); + } else if (sourceEntry is! HtmlEntry) { // This shouldn't be possible because we should never have performed the task if the source // didn't represent an HTML file, but check to be safe. throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as an HTML file: ${source.fullName}"); } htmlEntry = sourceEntry as HtmlEntry; - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); int resultTime = task.modificationTime; if (sourceTime == resultTime) { if (htmlEntry.modificationTime != sourceTime) { @@ -6331,7 +6821,6 @@ class AnalysisContextImpl implements InternalAnalysisContext { _cache.removedAst(source); } htmlCopy.exception = thrownException; - recordAngularComponents(htmlCopy, task.angularApplication); _cache.put(source, htmlCopy); htmlEntry = htmlCopy; } else { @@ -6370,6 +6859,90 @@ class AnalysisContextImpl implements InternalAnalysisContext { return htmlEntry; } + /** + * Record the results produced by performing a [ScanDartTask]. If the results were computed + * from data that is now out-of-date, then the results will not be recorded. + * + * @param task the task that was performed + * @return an entry containing the computed results + * @throws AnalysisException if the results could not be recorded + */ + DartEntry recordScanDartTaskResults(ScanDartTask task) { + Source source = task.source; + AnalysisException thrownException = task.exception; + DartEntry dartEntry = null; + { + SourceEntry sourceEntry = _cache.get(source); + if (sourceEntry == null) { + throw new ObsoleteSourceAnalysisException(source); + } else if (sourceEntry is! DartEntry) { + // This shouldn't be possible because we should never have performed the task if the source + // didn't represent a Dart file, but check to be safe. + throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${source.fullName}"); + } + dartEntry = sourceEntry as DartEntry; + int sourceTime = getModificationStamp(source); + int resultTime = task.modificationTime; + if (sourceTime == resultTime) { + if (dartEntry.modificationTime != sourceTime) { + // The source has changed without the context being notified. Simulate notification. + sourceChanged(source); + dartEntry = getReadableDartEntry(source); + if (dartEntry == null) { + throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}"); + } + } + DartEntryImpl dartCopy = dartEntry.writableCopy; + if (thrownException == null) { + LineInfo lineInfo = task.lineInfo; + dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo); + dartCopy.setValue(DartEntry.TOKEN_STREAM, task.tokenStream); + dartCopy.setValue(DartEntry.SCAN_ERRORS, task.errors); + _cache.storedAst(source); + _workManager.add(source, SourcePriority.NORMAL_PART); + ChangeNoticeImpl notice = getNotice(source); + notice.setErrors(dartEntry.allErrors, lineInfo); + } else { + removeFromParts(source, dartEntry); + dartCopy.recordScanError(); + _cache.removedAst(source); + } + dartCopy.exception = thrownException; + _cache.put(source, dartCopy); + dartEntry = dartCopy; + } else { + logInformation2("Scan results discarded for ${debuggingString(source)}; sourceTime = ${sourceTime}, resultTime = ${resultTime}, cacheTime = ${dartEntry.modificationTime}", thrownException); + DartEntryImpl dartCopy = dartEntry.writableCopy; + if (thrownException == null || resultTime >= 0) { + // + // The analysis was performed on out-of-date sources. Mark the cache so that the sources + // will be re-analyzed using the up-to-date sources. + // + // dartCopy.recordScanNotInProcess(); + removeFromParts(source, dartEntry); + dartCopy.invalidateAllInformation(); + dartCopy.modificationTime = sourceTime; + _cache.removedAst(source); + _workManager.add(source, SourcePriority.UNKNOWN); + } else { + // + // We could not determine whether the sources were up-to-date or out-of-date. Mark the + // cache so that we won't attempt to re-analyze the sources until there's a good chance + // that we'll be able to do so without error. + // + dartCopy.recordScanError(); + } + dartCopy.exception = thrownException; + _cache.put(source, dartCopy); + dartEntry = dartCopy; + } + } + if (thrownException != null) { + throw thrownException; + } + return dartEntry; + } + /** * Remove the given library from the list of containing libraries for all of the parts referenced * by the given entry. @@ -6427,7 +7000,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { } else { SourceEntryImpl sourceCopy = sourceEntry.writableCopy; int oldTime = sourceCopy.modificationTime; - sourceCopy.modificationTime = source.modificationStamp; + sourceCopy.modificationTime = getModificationStamp(source); // TODO(brianwilkerson) Understand why we're not invalidating the cache. _cache.put(source, sourceCopy); logInformation("Added new source: ${debuggingString(source)} (previously modified at ${oldTime})"); @@ -6447,7 +7020,7 @@ class AnalysisContextImpl implements InternalAnalysisContext { */ void sourceChanged(Source source) { SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry == null || sourceEntry.modificationTime == source.modificationStamp) { + if (sourceEntry == null || sourceEntry.modificationTime == getModificationStamp(source)) { // Either we have removed this source, in which case we don't care that it is changed, or we // have already invalidated the cache and don't need to invalidate it again. if (sourceEntry == null) { @@ -6460,7 +7033,8 @@ class AnalysisContextImpl implements InternalAnalysisContext { if (sourceEntry is HtmlEntry) { HtmlEntryImpl htmlCopy = sourceEntry.writableCopy; int oldTime = htmlCopy.modificationTime; - htmlCopy.modificationTime = source.modificationStamp; + htmlCopy.modificationTime = getModificationStamp(source); + invalidateAngularResolution(htmlCopy); htmlCopy.invalidateAllInformation(); _cache.put(source, htmlCopy); _cache.removedAst(source); @@ -6482,9 +7056,9 @@ class AnalysisContextImpl implements InternalAnalysisContext { // for (Source library : containingLibraries) { invalidateLibraryResolution(library, writer); } - removeFromParts(source, sourceEntry); - DartEntryImpl dartCopy = sourceEntry.writableCopy; - dartCopy.modificationTime = source.modificationStamp; + removeFromParts(source, _cache.get(source) as DartEntry); + DartEntryImpl dartCopy = (_cache.get(source) as DartEntry).writableCopy; + dartCopy.modificationTime = getModificationStamp(source); dartCopy.invalidateAllInformation(); _cache.put(source, dartCopy); _cache.removedAst(source); @@ -6502,7 +7076,10 @@ class AnalysisContextImpl implements InternalAnalysisContext { PrintStringWriter writer = new PrintStringWriter(); writer.println("Removed source: ${debuggingString(source)}"); SourceEntry sourceEntry = _cache.get(source); - if (sourceEntry is DartEntry) { + if (sourceEntry is HtmlEntry) { + HtmlEntryImpl htmlCopy = sourceEntry.writableCopy; + invalidateAngularResolution(htmlCopy); + } else if (sourceEntry is DartEntry) { Set libraries = new Set(); for (Source librarySource in getLibrariesContaining(source)) { libraries.add(librarySource); @@ -6537,13 +7114,13 @@ class AnalysisContextImpl implements InternalAnalysisContext { for (MapEntry entry in _cache.entrySet()) { Source source = entry.getKey(); SourceEntry sourceEntry = entry.getValue(); - int sourceTime = source.modificationStamp; + int sourceTime = getModificationStamp(source); if (sourceTime != sourceEntry.modificationTime) { sourceChanged(source); inconsistentCount++; } if (sourceEntry.exception != null) { - if (!source.exists()) { + if (!exists(source)) { missingSources.add(source); } } @@ -6599,6 +7176,8 @@ class AnalysisContextImpl_AnalysisTaskResultRecorder implements AnalysisTaskVisi SourceEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisContextImpl_this.recordResolveDartUnitTaskResults(task); SourceEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl_this.recordResolveHtmlTaskResults(task); + + SourceEntry visitScanDartTask(ScanDartTask task) => AnalysisContextImpl_this.recordScanDartTaskResults(task); } class AnalysisContextImpl_ContextRetentionPolicy implements CacheRetentionPolicy { @@ -6673,6 +7252,12 @@ class AnalysisOptionsImpl implements AnalysisOptions { */ bool dart2jsHint = true; + /** + * A flag indicating whether errors, warnings and hints should be generated for sources in the + * SDK. + */ + bool _generateSdkErrors = false; + /** * A flag indicating whether analysis is to generate hint results (e.g. type inference based * information and pub best practices). @@ -6690,7 +7275,7 @@ class AnalysisOptionsImpl implements AnalysisOptions { bool preserveComments = true; /** - * A flag indicating whether analysis is to parse comments. + * A flag indicating whether analysis is to analyze Angular. */ bool analyzeAngular = true; @@ -6710,7 +7295,19 @@ class AnalysisOptionsImpl implements AnalysisOptions { dart2jsHint = options.dart2jsHint; hint = options.hint; incremental = options.incremental; - analyzeAngular = options.analyzeAngular; + } + + bool get generateSdkErrors => _generateSdkErrors; + + /** + * Set whether errors, warnings and hints should be generated for sources in the SDK to match the + * given value. + * + * @param generate `true` if errors, warnings and hints should be generated for sources in + * the SDK + */ + void set generateSdkErrors(bool generate) { + _generateSdkErrors = generate; } } @@ -6776,7 +7373,7 @@ class ChangeNoticeImpl implements ChangeNotice { this._errors = errors; this._lineInfo = lineInfo; if (lineInfo == null) { - AnalysisEngine.instance.logger.logError2("No line info: ${source}", new JavaException()); + AnalysisEngine.instance.logger.logInformation3("No line info: ${source}", new JavaException()); } } @@ -7326,15 +7923,7 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext { } } - List computeExportedLibraries(Source source) { - InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeExportedLibraries"); - try { - instrumentation.metric3("contextId", _contextId); - return _basis.computeExportedLibraries(source); - } finally { - instrumentation.log(); - } - } + List computeExportedLibraries(Source source) => _basis.computeExportedLibraries(source); HtmlElement computeHtmlElement(Source source) { InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeHtmlElement"); @@ -7349,15 +7938,7 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext { } } - List computeImportedLibraries(Source source) { - InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeImportedLibraries"); - try { - instrumentation.metric3("contextId", _contextId); - return _basis.computeImportedLibraries(source); - } finally { - instrumentation.log(); - } - } + List computeImportedLibraries(Source source) => _basis.computeImportedLibraries(source); SourceKind computeKindOf(Source source) { InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeKindOf"); @@ -7401,6 +7982,16 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext { ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) => _basis.computeResolvableHtmlUnit(source); + bool exists(Source source) { + InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-exists"); + try { + instrumentation.metric3("contextId", _contextId); + return _basis.exists(source); + } finally { + instrumentation.log(); + } + } + AnalysisContext extractContext(SourceContainer container) { InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-extractContext"); try { @@ -7430,6 +8021,22 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext { */ AnalysisContext get basis => _basis; + CompilationUnitElement getCompilationUnitElement(Source unitSource, Source librarySource) { + InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getCompilationUnitElement"); + try { + instrumentation.metric3("contextId", _contextId); + return _basis.getCompilationUnitElement(unitSource, librarySource); + } finally { + instrumentation.log(); + } + } + + TimestampedData getContents(Source source) => _basis.getContents(source); + + void getContentsToReceiver(Source source, Source_ContentReceiver receiver) { + _basis.getContentsToReceiver(source, receiver); + } + Element getElement(ElementLocation location) { InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getElement"); try { @@ -7592,11 +8199,29 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext { } } + int getModificationStamp(Source source) { + InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getModificationStamp"); + try { + instrumentation.metric3("contextId", _contextId); + return _basis.getModificationStamp(source); + } finally { + instrumentation.log(); + } + } + Namespace getPublicNamespace(LibraryElement library) => _basis.getPublicNamespace(library); Namespace getPublicNamespace2(Source source) => _basis.getPublicNamespace2(source); - List get refactoringUnsafeSources => _basis.refactoringUnsafeSources; + List get refactoringUnsafeSources { + InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getRefactoringUnsafeSources"); + try { + instrumentation.metric3("contextId", _contextId); + return _basis.refactoringUnsafeSources; + } finally { + instrumentation.log(); + } + } CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) { InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getResolvedCompilationUnit"); @@ -7642,8 +8267,12 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext { TypeProvider get typeProvider => _basis.typeProvider; + TimestampedData internalParseCompilationUnit(Source source) => _basis.internalParseCompilationUnit(source); + TimestampedData internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement) => _basis.internalResolveCompilationUnit(unitSource, libraryElement); + TimestampedData internalScanTokenStream(Source source) => _basis.internalScanTokenStream(source); + bool isClientLibrary(Source librarySource) { InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-isClientLibrary"); try { @@ -7809,16 +8438,6 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext { instrumentation.log(); } } - - Iterable sourcesToResolve(List changedSources) { - InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-sourcesToResolve"); - try { - instrumentation.metric3("contextId", _contextId); - return _basis.sourcesToResolve(changedSources); - } finally { - instrumentation.log(); - } - } } /** @@ -7931,6 +8550,15 @@ abstract class InternalAnalysisContext implements AnalysisContext { */ TypeProvider get typeProvider; + /** + * Return a time-stamped parsed AST for the given source. + * + * @param source the source of the compilation unit for which an AST is to be returned + * @return a time-stamped AST for the source + * @throws AnalysisException if the source could not be parsed + */ + TimestampedData internalParseCompilationUnit(Source source); + /** * Return a time-stamped fully-resolved compilation unit for the given source in the given * library. @@ -7944,6 +8572,15 @@ abstract class InternalAnalysisContext implements AnalysisContext { */ TimestampedData internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement); + /** + * Return a time-stamped token stream for the given source. + * + * @param source the source of the compilation unit for which a token stream is to be returned + * @return a time-stamped token stream for the source + * @throws AnalysisException if the token stream could not be computed + */ + TimestampedData internalScanTokenStream(Source source); + /** * Given a table mapping the source for the libraries represented by the corresponding elements to * the elements representing the libraries, record those mappings. @@ -8466,21 +9103,6 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { return null; } - /** - * Returns the array of all top-level Angular elements that could be used in the application with - * this entry point. Maybe `null` of not an Angular entry point. - */ - static List getAngularElements(AnalysisContext context, ht.HtmlUnit unit) { - if (hasAngularAnnotation(unit)) { - CompilationUnit dartUnit = getDartUnit(context, unit); - if (dartUnit != null) { - LibraryElement libraryElement = dartUnit.element.library; - return getAngularElements2(libraryElement); - } - } - return null; - } - /** * @return `true` if the given [HtmlUnit] has ng-app annotation. */ @@ -8519,11 +9141,15 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { * @return the array of all top-level Angular elements that could be used in this library */ static void addAngularElements2(Set angularElements, LibraryElement library, Set visited) { + if (library == null) { + return; + } if (!visited.add(library)) { return; } // add Angular elements from current library for (CompilationUnitElement unit in library.units) { + angularElements.addAll(unit.angularViews); for (ClassElement type in unit.types) { addAngularElements(angularElements, type); } @@ -8543,9 +9169,9 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { * @param libraryElement the [LibraryElement] to analyze * @return the array of all top-level Angular elements that could be used in this library */ - static List getAngularElements2(LibraryElement libraryElement) { + static List getAngularElements(Set libraries, LibraryElement libraryElement) { Set angularElements = new Set(); - addAngularElements2(angularElements, libraryElement, new Set()); + addAngularElements2(angularElements, libraryElement, libraries); return new List.from(angularElements); } @@ -8564,11 +9190,19 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { return null; } + static Set getLibrarySources(Set libraries) { + Set sources = new Set(); + for (LibraryElement library in libraries) { + sources.add(library.source); + } + return sources; + } + InternalAnalysisContext _context; TypeProvider _typeProvider; - AnalysisErrorListener _errorListener; + AngularHtmlUnitResolver_FilteringAnalysisErrorListener _errorListener; Source _source; @@ -8601,17 +9235,17 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { AngularHtmlUnitResolver(InternalAnalysisContext context, AnalysisErrorListener errorListener, Source source, LineInfo lineInfo, ht.HtmlUnit unit) { this._context = context; this._typeProvider = context.typeProvider; - this._errorListener = errorListener; + this._errorListener = new AngularHtmlUnitResolver_FilteringAnalysisErrorListener(errorListener); this._source = source; this._lineInfo = lineInfo; this._unit = unit; } /** - * The [AngularApplicationInfo] for the Web application with this entry point, may be + * The [AngularApplication] for the Web application with this entry point, may be * `null` if not an entry point. */ - AngularApplicationInfo calculateAngularApplication() { + AngularApplication calculateAngularApplication() { // check if Angular at all if (!hasAngularAnnotation(_unit)) { return null; @@ -8623,36 +9257,50 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { } // prepare accessible Angular elements LibraryElement libraryElement = dartUnit.element.library; - List angularElements = getAngularElements2(libraryElement); - // resolve template URIs + Set libraries = new Set(); + List angularElements = getAngularElements(libraries, libraryElement); + // resolve AngularComponentElement template URIs // TODO(scheglov) resolve to HtmlElement to allow F3 ? + Set angularElementsSources = new Set(); for (AngularElement angularElement in angularElements) { - if (angularElement is AngularComponentElement) { - AngularComponentElement component = angularElement; - String templateUri = component.templateUri; + if (angularElement is AngularHasTemplateElement) { + AngularHasTemplateElement hasTemplate = angularElement; + angularElementsSources.add(angularElement.source); + String templateUri = hasTemplate.templateUri; if (templateUri == null) { continue; } try { Source templateSource = _source.resolveRelative(parseUriWithException(templateUri)); - if (templateSource == null || !templateSource.exists()) { + if (!_context.exists(templateSource)) { templateSource = _context.sourceFactory.resolveUri(_source, "package:${templateUri}"); - if (templateSource == null || !templateSource.exists()) { - reportError7(component.templateUriOffset, templateUri.length, AngularCode.URI_DOES_NOT_EXIST, [templateUri]); + if (!_context.exists(templateSource)) { + _errorListener.onError(new AnalysisError.con2(angularElement.source, hasTemplate.templateUriOffset, templateUri.length, AngularCode.URI_DOES_NOT_EXIST, [templateUri])); continue; } } if (!AnalysisEngine.isHtmlFileName(templateUri)) { continue; } - (component as AngularComponentElementImpl).templateSource = templateSource; + if (hasTemplate is AngularComponentElementImpl) { + hasTemplate.templateSource = templateSource; + } + if (hasTemplate is AngularViewElementImpl) { + hasTemplate.templateSource = templateSource; + } } on URISyntaxException catch (exception) { - reportError7(component.templateUriOffset, templateUri.length, AngularCode.INVALID_URI, [templateUri]); + _errorListener.onError(new AnalysisError.con2(angularElement.source, hasTemplate.templateUriOffset, templateUri.length, AngularCode.INVALID_URI, [templateUri])); } } } + // create AngularApplication + AngularApplication application = new AngularApplication(_source, getLibrarySources(libraries), angularElements, new List.from(angularElementsSources)); + // set AngularApplication for each AngularElement + for (AngularElement angularElement in angularElements) { + (angularElement as AngularElementImpl).application = application; + } // done - return new AngularApplicationInfo(_source, angularElements); + return application; } /** @@ -8661,7 +9309,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { * @param application the Angular application we are resolving for * @param component the [AngularComponentElement] to resolve template for, not `null` */ - void resolveComponentTemplate(AngularApplicationInfo application, AngularComponentElement component) { + void resolveComponentTemplate(AngularApplication application, AngularComponentElement component) { _isAngular = true; resolveInternal(application.elements, component); } @@ -8669,7 +9317,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { /** * Resolves [source] as an Angular application entry point. */ - void resolveEntryPoint(AngularApplicationInfo application) { + void resolveEntryPoint(AngularApplication application) { resolveInternal(application.elements, null); } @@ -8935,9 +9583,10 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { } /** - * Defines variable for the given [AngularElement]. + * Defines variable for the given [AngularElement] with type of the enclosing + * [ClassElement]. */ - void defineTopElementVariable(AngularElement element) { + void defineTopVariable_forClassElement(AngularElement element) { ClassElement classElement = element.enclosingElement as ClassElement; InterfaceType type = classElement.type; LocalVariableElementImpl variable = createLocalVariable2(type, element.name); @@ -8945,6 +9594,16 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { variable.toolkitObjects = [element]; } + /** + * Defines variable for the given [AngularScopePropertyElement]. + */ + void defineTopVariable_forScopeProperty(AngularScopePropertyElement element) { + Type2 type = element.type; + LocalVariableElementImpl variable = createLocalVariable2(type, element.name); + defineTopVariable(variable); + variable.toolkitObjects = [element]; + } + /** * Parse the value of the given token for embedded expressions, and add any embedded expressions * that are found to the given list of expressions. @@ -9048,13 +9707,6 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { for (AngularElement angularElement in angularElements) { _injectedLibraries.add(angularElement.library); } - // add accessible processors - for (AngularElement angularElement in angularElements) { - NgProcessor processor = createProcessor(angularElement); - if (processor != null) { - _processors.add(processor); - } - } // prepare Dart library createLibraryElement(); (_unit.element as HtmlElementImpl).angularCompilationUnit = _unitElement; @@ -9062,12 +9714,22 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { createResolver(); // maybe resolving component template if (component != null) { - defineTopElementVariable(component); + defineTopVariable_forClassElement(component); + for (AngularScopePropertyElement scopeProperty in component.scopeProperties) { + defineTopVariable_forScopeProperty(scopeProperty); + } + } + // add processors + for (AngularElement angularElement in angularElements) { + NgProcessor processor = createProcessor(angularElement); + if (processor != null) { + _processors.add(processor); + } } // define filters for (AngularElement angularElement in angularElements) { if (angularElement is AngularFilterElement) { - defineTopElementVariable(angularElement); + defineTopVariable_forClassElement(angularElement); } } // run this HTML visitor @@ -9112,6 +9774,22 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor { } } +class AngularHtmlUnitResolver_FilteringAnalysisErrorListener implements AnalysisErrorListener { + AnalysisErrorListener _listener; + + AngularHtmlUnitResolver_FilteringAnalysisErrorListener(AnalysisErrorListener listener) { + this._listener = listener; + } + + void onError(AnalysisError error) { + ErrorCode errorCode = error.errorCode; + if (identical(errorCode, StaticWarningCode.UNDEFINED_GETTER) || identical(errorCode, StaticWarningCode.UNDEFINED_IDENTIFIER) || identical(errorCode, StaticTypeWarningCode.UNDEFINED_GETTER)) { + return; + } + _listener.onError(error); + } +} + class AngularHtmlUnitResolver_FoundAppError extends Error { } @@ -9345,19 +10023,32 @@ class NgDirectiveElementProcessor extends NgDirectiveProcessor { } void apply(AngularHtmlUnitResolver resolver, ht.XmlTagNode node) { + String selectorAttributeName = null; + { + AngularSelectorElement selector = _element.selector; + if (selector is HasAttributeSelectorElementImpl) { + selectorAttributeName = selector.name; + // resolve attribute expression + ht.XmlAttributeNode attribute = node.getAttribute(selectorAttributeName); + if (attribute != null) { + attribute.element = selector; + } + } + } + // for (AngularPropertyElement property in _element.properties) { // prepare attribute name String name = property.name; if (name == ".") { - AngularSelectorElement selector = _element.selector; - if (selector is HasAttributeSelectorElementImpl) { - name = selector.name; - } + name = selectorAttributeName; } // resolve attribute expression ht.XmlAttributeNode attribute = node.getAttribute(name); if (attribute != null) { - attribute.element = property; + // if not resolved as the selector, resolve as a property + if (name != selectorAttributeName) { + attribute.element = property; + } // resolve if binding if (property.propertyKind != AngularPropertyKind.ATTR) { resolver.pushNameScope(); @@ -9695,6 +10386,15 @@ abstract class AnalysisTaskVisitor { * @throws AnalysisException if the visitor throws an exception for some reason */ E visitResolveHtmlTask(ResolveHtmlTask task); + + /** + * Visit a [ScanDartTask]. + * + * @param task the task to be visited + * @return the result of visiting the task + * @throws AnalysisException if the visitor throws an exception for some reason + */ + E visitScanDartTask(ScanDartTask task); } /** @@ -9978,11 +10678,6 @@ class ParseDartTask extends AnalysisTask { */ int _modificationTime = -1; - /** - * The line information that was produced. - */ - LineInfo _lineInfo; - /** * The compilation unit that was produced by parsing the source. */ @@ -10029,14 +10724,6 @@ class ParseDartTask extends AnalysisTask { */ List get errors => _errors; - /** - * Return the line information that was produced, or `null` if the task has not yet been - * performed or if an exception occurred. - * - * @return the line information that was produced - */ - LineInfo get lineInfo => _lineInfo; - /** * Return the time at which the contents of the source that was parsed were last modified, or a * negative value if the task has not yet been performed or if an exception occurred. @@ -10070,19 +10757,12 @@ class ParseDartTask extends AnalysisTask { void internalPerform() { RecordingErrorListener errorListener = new RecordingErrorListener(); - List token = [null]; - // - // Scan the contents of the file. - // - Source_ContentReceiver receiver = new Source_ContentReceiver_ParseDartTask_internalPerform(this, errorListener, token); - try { - source.getContents(receiver); - } on JavaException catch (exception) { - _modificationTime = source.modificationStamp; - throw new AnalysisException.con3(exception); - } - if (token[0] == null) { - throw new AnalysisException.con1("Could not get contents for '${source.fullName}'"); + InternalAnalysisContext context = this.context; + TimestampedData data = context.internalScanTokenStream(source); + _modificationTime = data.modificationTime; + Token token = data.data; + if (token == null) { + throw new AnalysisException.con1("Could not get token stream for ${source.fullName}"); } // // Then parse the token stream. @@ -10091,7 +10771,7 @@ class ParseDartTask extends AnalysisTask { try { Parser parser = new Parser(source, errorListener); parser.parseFunctionBodies = context.analysisOptions.analyzeFunctionBodies; - _unit = parser.parseCompilationUnit(token[0]); + _unit = parser.parseCompilationUnit(token); _errors = errorListener.getErrors2(source); for (Directive directive in _unit.directives) { if (directive is LibraryDirective) { @@ -10100,36 +10780,13 @@ class ParseDartTask extends AnalysisTask { _hasPartOfDirective2 = true; } } - _unit.lineInfo = _lineInfo; + _unit.lineInfo = context.getLineInfo(source); } finally { timeCounterParse.stop(); } } } -class Source_ContentReceiver_ParseDartTask_internalPerform implements Source_ContentReceiver { - final ParseDartTask ParseDartTask_this; - - RecordingErrorListener errorListener; - - List token; - - Source_ContentReceiver_ParseDartTask_internalPerform(this.ParseDartTask_this, this.errorListener, this.token); - - void accept(String contents, int modificationTime) { - ParseDartTask_this._modificationTime = modificationTime; - TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start(); - try { - Scanner scanner = new Scanner(ParseDartTask_this.source, new CharSequenceReader(contents), errorListener); - scanner.preserveComments = ParseDartTask_this.context.analysisOptions.preserveComments; - token[0] = scanner.tokenize(); - ParseDartTask_this._lineInfo = new LineInfo(scanner.lineStarts); - } finally { - timeCounterScan.stop(); - } - } -} - /** * Instances of the class `ParseHtmlTask` parse a specific source as an HTML file. */ @@ -10169,22 +10826,11 @@ class ParseHtmlTask extends AnalysisTask { */ static String _ATTRIBUTE_SRC = "src"; - /** - * The name of the 'type' attribute in a HTML tag. - */ - static String _ATTRIBUTE_TYPE = "type"; - /** * The name of the 'script' tag in an HTML file. */ static String _TAG_SCRIPT = "script"; - /** - * The value of the 'type' attribute of a 'script' tag that indicates that the script is written - * in Dart. - */ - static String _TYPE_DART = "application/dart"; - /** * Initialize a newly created task to perform analysis within the given context. * @@ -10241,20 +10887,20 @@ class ParseHtmlTask extends AnalysisTask { } void internalPerform() { - ht.HtmlScanner scanner = new ht.HtmlScanner(source); try { - source.getContents(scanner); + TimestampedData contents = context.getContents(source); + _modificationTime = contents.modificationTime; + ht.AbstractScanner scanner = new ht.StringScanner(source, contents.data); + scanner.passThroughElements = [_TAG_SCRIPT]; + ht.Token token = scanner.tokenize(); + _lineInfo = new LineInfo(scanner.lineStarts); + RecordingErrorListener errorListener = new RecordingErrorListener(); + _unit = new ht.HtmlParser(source, errorListener).parse(token, _lineInfo); + _errors = errorListener.getErrors2(source); + _referencedLibraries = librarySources; } on JavaException catch (exception) { throw new AnalysisException.con3(exception); } - ht.HtmlScanResult scannerResult = scanner.result; - _modificationTime = scannerResult.modificationTime; - _lineInfo = new LineInfo(scannerResult.lineStarts); - RecordingErrorListener errorListener = new RecordingErrorListener(); - ht.HtmlParseResult result = new ht.HtmlParser(source, errorListener).parse(scannerResult); - _unit = result.htmlUnit; - _errors = errorListener.getErrors2(source); - _referencedLibraries = librarySources; } /** @@ -10291,7 +10937,7 @@ class RecursiveXmlVisitor_ParseHtmlTask_getLibrarySources extends ht.RecursiveXm Uri uri = new Uri(path: scriptAttribute.text); String fileName = uri.path; Source librarySource = ParseHtmlTask_this.context.sourceFactory.resolveUri(ParseHtmlTask_this.source, fileName); - if (librarySource != null && librarySource.exists()) { + if (ParseHtmlTask_this.context.exists(librarySource)) { libraries.add(librarySource); } } on URISyntaxException catch (e) { @@ -10314,7 +10960,7 @@ class ResolveAngularComponentTemplateTask extends AnalysisTask { /** * The Angular application to resolve in context of. */ - AngularApplicationInfo _application; + AngularApplication _application; /** * The source to be resolved. @@ -10344,7 +10990,7 @@ class ResolveAngularComponentTemplateTask extends AnalysisTask { * @param component the component that uses this HTML template, not `null` * @param application the Angular application to resolve in context of */ - ResolveAngularComponentTemplateTask(InternalAnalysisContext context, this.source, AngularComponentElement component, AngularApplicationInfo application) : super(context) { + ResolveAngularComponentTemplateTask(InternalAnalysisContext context, this.source, AngularComponentElement component, AngularApplication application) : super(context) { this._component = component; this._application = application; } @@ -10381,12 +11027,13 @@ class ResolveAngularComponentTemplateTask extends AnalysisTask { RecordingErrorListener errorListener = new RecordingErrorListener(); LineInfo lineInfo = context.getLineInfo(source); // do resolve - AngularHtmlUnitResolver resolver = new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit); - resolver.resolveComponentTemplate(_application, _component); + if (_application != null) { + AngularHtmlUnitResolver resolver = new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit); + resolver.resolveComponentTemplate(_application, _component); + _resolvedUnit = unit; + } // remember errors _resolutionErrors = errorListener.getErrors2(source); - // remember resolved unit - _resolvedUnit = unit; } } @@ -10401,9 +11048,9 @@ class ResolveAngularEntryHtmlTask extends AnalysisTask { final Source source; /** - * The Angular application to resolve in context of. + * The listener to record errors. */ - AngularApplicationInfo _application; + RecordingErrorListener _errorListener = new RecordingErrorListener(); /** * The time at which the contents of the source were last modified. @@ -10421,25 +11068,38 @@ class ResolveAngularEntryHtmlTask extends AnalysisTask { HtmlElement _element = null; /** - * The resolution errors that were discovered while resolving the source. + * The Angular application to resolve in context of. */ - List _resolutionErrors = AnalysisError.NO_ERRORS; + AngularApplication _application; /** * Initialize a newly created task to perform analysis within the given context. * * @param context the context in which the task is to be performed * @param source the source to be resolved - * @param application the Angular application to resolve in context of */ - ResolveAngularEntryHtmlTask(InternalAnalysisContext context, this.source, AngularApplicationInfo application) : super(context) { - this._application = application; - } + ResolveAngularEntryHtmlTask(InternalAnalysisContext context, this.source) : super(context); accept(AnalysisTaskVisitor visitor) => visitor.visitResolveAngularEntryHtmlTask(this); + /** + * Returns the [AngularApplication] for the Web application with this Angular entry point, + * maybe `null` if not an Angular entry point. + */ + AngularApplication get application => _application; + HtmlElement get element => _element; + /** + * The resolution errors that were discovered while resolving the source. + */ + List get entryErrors => _errorListener.getErrors2(source); + + /** + * Returns [AnalysisError]s recorded for the given [Source]. + */ + List getErrors(Source source) => _errorListener.getErrors2(source); + /** * Return the time at which the contents of the source that was parsed were last modified, or a * negative value if the task has not yet been performed or if an exception occurred. @@ -10448,8 +11108,6 @@ class ResolveAngularEntryHtmlTask extends AnalysisTask { */ int get modificationTime => _modificationTime; - List get resolutionErrors => _resolutionErrors; - /** * Return the [HtmlUnit] that was resolved by this task. * @@ -10472,12 +11130,13 @@ class ResolveAngularEntryHtmlTask extends AnalysisTask { } _modificationTime = resolvableHtmlUnit.modificationTime; // prepare for resolution - RecordingErrorListener errorListener = new RecordingErrorListener(); LineInfo lineInfo = context.getLineInfo(source); + // try to resolve as an Angular entry point + _application = new AngularHtmlUnitResolver(context, _errorListener, source, lineInfo, unit).calculateAngularApplication(); // do resolve - new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit).resolveEntryPoint(_application); - // remember errors - _resolutionErrors = errorListener.getErrors2(source); + if (_application != null) { + new AngularHtmlUnitResolver(context, _errorListener, source, lineInfo, unit).resolveEntryPoint(_application); + } // remember resolved unit _resolvedUnit = unit; } @@ -10563,14 +11222,11 @@ class ResolveDartDependenciesTask extends AnalysisTask { } void internalPerform() { - ResolvableCompilationUnit unit = context.computeResolvableCompilationUnit(source); + TimestampedData unit = context.internalParseCompilationUnit(source); _modificationTime = unit.modificationTime; - // - // Then parse the token stream. - // TimeCounter_TimeCounterHandle timeCounterParse = PerformanceStatistics.parse.start(); try { - for (Directive directive in unit.compilationUnit.directives) { + for (Directive directive in unit.data.directives) { if (directive is ExportDirective) { Source exportSource = resolveSource(source, directive); if (exportSource != null) { @@ -10853,16 +11509,6 @@ class ResolveHtmlTask extends AnalysisTask { */ List _resolutionErrors = AnalysisError.NO_ERRORS; - /** - * The flag that says is this unit is an Angular application. - */ - bool _isAngularApplication2 = false; - - /** - * The Angular application information, maybe `null` - */ - AngularApplicationInfo _angularApplication; - /** * Initialize a newly created task to perform analysis within the given context. * @@ -10873,12 +11519,6 @@ class ResolveHtmlTask extends AnalysisTask { accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this); - /** - * Returns the [AngularApplicationInfo] for the Web application with this Angular entry - * point, maybe `null` if not an Angular entry point. - */ - AngularApplicationInfo get angularApplication => _angularApplication; - HtmlElement get element => _element; /** @@ -10898,11 +11538,6 @@ class ResolveHtmlTask extends AnalysisTask { */ ht.HtmlUnit get resolvedUnit => _resolvedUnit; - /** - * Returns `true` if analyzed unit is an Angular application. - */ - bool get isAngularApplication => _isAngularApplication2; - String get taskDescription { if (source == null) { return "resolve as html null source"; @@ -10921,12 +11556,6 @@ class ResolveHtmlTask extends AnalysisTask { HtmlUnitBuilder builder = new HtmlUnitBuilder(context); _element = builder.buildHtmlElement2(source, _modificationTime, unit); RecordingErrorListener errorListener = builder.errorListener; - LineInfo lineInfo = context.getLineInfo(source); - // try to resolve as an Angular entry point - if (context.analysisOptions.analyzeAngular) { - _isAngularApplication2 = AngularHtmlUnitResolver.hasAngularAnnotation(unit); - _angularApplication = new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit).calculateAngularApplication(); - } // record all resolution errors _resolutionErrors = errorListener.getErrors2(source); // remember resolved unit @@ -10934,6 +11563,110 @@ class ResolveHtmlTask extends AnalysisTask { } } +/** + * Instances of the class `ScanDartTask` scan a specific source as a Dart file. + */ +class ScanDartTask extends AnalysisTask { + /** + * The source to be scanned. + */ + final Source source; + + /** + * The contents of the source. + */ + String _content; + + /** + * The time at which the contents of the source were last modified. + */ + int _modificationTime = 0; + + /** + * The token stream that was produced by scanning the source. + */ + Token _tokenStream; + + /** + * The line information that was produced. + */ + LineInfo _lineInfo; + + /** + * The errors that were produced by scanning the source. + */ + List _errors = AnalysisError.NO_ERRORS; + + /** + * Initialize a newly created task to perform analysis within the given context. + * + * @param context the context in which the task is to be performed + * @param source the source to be parsed + * @param contentData the time-stamped contents of the source + */ + ScanDartTask(InternalAnalysisContext context, this.source, TimestampedData contentData) : super(context) { + this._content = contentData.data; + this._modificationTime = contentData.modificationTime; + } + + accept(AnalysisTaskVisitor visitor) => visitor.visitScanDartTask(this); + + /** + * Return the errors that were produced by scanning the source, or `null` if the task has + * not yet been performed or if an exception occurred. + * + * @return the errors that were produced by scanning the source + */ + List get errors => _errors; + + /** + * Return the line information that was produced, or `null` if the task has not yet been + * performed or if an exception occurred. + * + * @return the line information that was produced + */ + LineInfo get lineInfo => _lineInfo; + + /** + * Return the time at which the contents of the source that was parsed were last modified, or a + * negative value if the task has not yet been performed or if an exception occurred. + * + * @return the time at which the contents of the source that was parsed were last modified + */ + int get modificationTime => _modificationTime; + + /** + * Return the token stream that was produced by scanning the source, or `null` if the task + * has not yet been performed or if an exception occurred. + * + * @return the token stream that was produced by scanning the source + */ + Token get tokenStream => _tokenStream; + + String get taskDescription { + if (source == null) { + return "scan as dart null source"; + } + return "scan as dart ${source.fullName}"; + } + + void internalPerform() { + RecordingErrorListener errorListener = new RecordingErrorListener(); + TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start(); + try { + Scanner scanner = new Scanner(source, new CharSequenceReader(_content), errorListener); + scanner.preserveComments = context.analysisOptions.preserveComments; + _tokenStream = scanner.tokenize(); + _lineInfo = new LineInfo(scanner.lineStarts); + _errors = errorListener.getErrors2(source); + } on JavaException catch (exception) { + throw new AnalysisException.con3(exception); + } finally { + timeCounterScan.stop(); + } + } +} + /** * The interface `Logger` defines the behavior of objects that can be used to receive * information about errors within the analysis engine. Implementations usually write this diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart index 70408c6c74b..0358ac75189 100644 --- a/pkg/analyzer/lib/src/generated/error.dart +++ b/pkg/analyzer/lib/src/generated/error.dart @@ -210,12 +210,12 @@ class AngularCode extends Enum implements ErrorCode { */ AngularCode.con2(String name, int ordinal, String message, ErrorSeverity severity) : super(name, ordinal) { this._message = message; - this._severity = severity; + this._severity = ErrorSeverity.INFO; } String get correction => null; - ErrorSeverity get errorSeverity => ErrorSeverity.INFO; + ErrorSeverity get errorSeverity => _severity; String get message => _message; @@ -656,7 +656,22 @@ class HintCode extends Enum implements ErrorCode { * * @param returnType the name of the declared return type */ - static final HintCode MISSING_RETURN = new HintCode.con2('MISSING_RETURN', 10, "This function declares a return type of '%s', but does not end with a return statement.", "Either add a return statement or change the return type to 'void'."); + static final HintCode MISSING_RETURN = new HintCode.con2('MISSING_RETURN', 10, "This function declares a return type of '%s', but does not end with a return statement", "Either add a return statement or change the return type to 'void'"); + + /** + * A getter with the override annotation does not override an existing getter. + */ + static final HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = new HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_GETTER', 11, "Getter does not override an inherited getter"); + + /** + * A method with the override annotation does not override an existing method. + */ + static final HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = new HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_METHOD', 12, "Method does not override an inherited method"); + + /** + * A setter with the override annotation does not override an existing setter. + */ + static final HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = new HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_SETTER', 13, "Setter does not override an inherited setter"); /** * It is not in best practice to declare a private method that happens to override the method in a @@ -667,24 +682,24 @@ class HintCode extends Enum implements ErrorCode { * @param memberName some private member name * @param className the class name where the member is overriding the functionality */ - static final HintCode OVERRIDDING_PRIVATE_MEMBER = new HintCode.con1('OVERRIDDING_PRIVATE_MEMBER', 11, "The %s '%s' does not override the definition from '%s' because it is private and in a different library"); + static final HintCode OVERRIDDING_PRIVATE_MEMBER = new HintCode.con1('OVERRIDDING_PRIVATE_MEMBER', 14, "The %s '%s' does not override the definition from '%s' because it is private and in a different library"); /** * Hint for classes that override equals, but not hashCode. * * @param className the name of the current class */ - static final HintCode OVERRIDE_EQUALS_BUT_NOT_HASH_CODE = new HintCode.con1('OVERRIDE_EQUALS_BUT_NOT_HASH_CODE', 12, "The class '%s' overrides 'operator==', but not 'get hashCode'"); + static final HintCode OVERRIDE_EQUALS_BUT_NOT_HASH_CODE = new HintCode.con1('OVERRIDE_EQUALS_BUT_NOT_HASH_CODE', 15, "The class '%s' overrides 'operator==', but not 'get hashCode'"); /** * Type checks of the type `x is! Null` should be done with `x != null`. */ - static final HintCode TYPE_CHECK_IS_NOT_NULL = new HintCode.con1('TYPE_CHECK_IS_NOT_NULL', 13, "Tests for non-null should be done with '!= null'"); + static final HintCode TYPE_CHECK_IS_NOT_NULL = new HintCode.con1('TYPE_CHECK_IS_NOT_NULL', 16, "Tests for non-null should be done with '!= null'"); /** * Type checks of the type `x is Null` should be done with `x == null`. */ - static final HintCode TYPE_CHECK_IS_NULL = new HintCode.con1('TYPE_CHECK_IS_NULL', 14, "Tests for null should be done with '== null'"); + static final HintCode TYPE_CHECK_IS_NULL = new HintCode.con1('TYPE_CHECK_IS_NULL', 17, "Tests for null should be done with '== null'"); /** * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_GETTER] or @@ -696,7 +711,7 @@ class HintCode extends Enum implements ErrorCode { * @see StaticTypeWarningCode#UNDEFINED_GETTER * @see StaticWarningCode#UNDEFINED_GETTER */ - static final HintCode UNDEFINED_GETTER = new HintCode.con1('UNDEFINED_GETTER', 15, StaticTypeWarningCode.UNDEFINED_GETTER.message); + static final HintCode UNDEFINED_GETTER = new HintCode.con1('UNDEFINED_GETTER', 18, StaticTypeWarningCode.UNDEFINED_GETTER.message); /** * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_METHOD] would @@ -706,7 +721,7 @@ class HintCode extends Enum implements ErrorCode { * @param typeName the resolved type name that the method lookup is happening on * @see StaticTypeWarningCode#UNDEFINED_METHOD */ - static final HintCode UNDEFINED_METHOD = new HintCode.con1('UNDEFINED_METHOD', 16, StaticTypeWarningCode.UNDEFINED_METHOD.message); + static final HintCode UNDEFINED_METHOD = new HintCode.con1('UNDEFINED_METHOD', 19, StaticTypeWarningCode.UNDEFINED_METHOD.message); /** * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_OPERATOR] @@ -716,7 +731,7 @@ class HintCode extends Enum implements ErrorCode { * @param enclosingType the name of the enclosing type where the operator is being looked for * @see StaticTypeWarningCode#UNDEFINED_OPERATOR */ - static final HintCode UNDEFINED_OPERATOR = new HintCode.con1('UNDEFINED_OPERATOR', 17, StaticTypeWarningCode.UNDEFINED_OPERATOR.message); + static final HintCode UNDEFINED_OPERATOR = new HintCode.con1('UNDEFINED_OPERATOR', 20, StaticTypeWarningCode.UNDEFINED_OPERATOR.message); /** * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_SETTER] or @@ -728,27 +743,27 @@ class HintCode extends Enum implements ErrorCode { * @see StaticTypeWarningCode#UNDEFINED_SETTER * @see StaticWarningCode#UNDEFINED_SETTER */ - static final HintCode UNDEFINED_SETTER = new HintCode.con1('UNDEFINED_SETTER', 18, StaticTypeWarningCode.UNDEFINED_SETTER.message); + static final HintCode UNDEFINED_SETTER = new HintCode.con1('UNDEFINED_SETTER', 21, StaticTypeWarningCode.UNDEFINED_SETTER.message); /** * Unnecessary cast. */ - static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 19, "Unnecessary cast"); + static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 22, "Unnecessary cast"); /** * Unnecessary type checks, the result is always true. */ - static final HintCode UNNECESSARY_TYPE_CHECK_FALSE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_FALSE', 20, "Unnecessary type check, the result is always false"); + static final HintCode UNNECESSARY_TYPE_CHECK_FALSE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_FALSE', 23, "Unnecessary type check, the result is always false"); /** * Unnecessary type checks, the result is always false. */ - static final HintCode UNNECESSARY_TYPE_CHECK_TRUE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_TRUE', 21, "Unnecessary type check, the result is always true"); + static final HintCode UNNECESSARY_TYPE_CHECK_TRUE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_TRUE', 24, "Unnecessary type check, the result is always true"); /** * Unused imports are imports which are never not used. */ - static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 22, "Unused import"); + static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 25, "Unused import"); /** * Hint for cases where the source expects a method or function to return a non-void result, but @@ -756,7 +771,7 @@ class HintCode extends Enum implements ErrorCode { * * @param name the name of the method or function that returns void */ - static final HintCode USE_OF_VOID_RESULT = new HintCode.con1('USE_OF_VOID_RESULT', 23, "The result of '%s' is being used, even though it is declared to be 'void'"); + static final HintCode USE_OF_VOID_RESULT = new HintCode.con1('USE_OF_VOID_RESULT', 26, "The result of '%s' is being used, even though it is declared to be 'void'"); static final List values = [ DEAD_CODE, @@ -770,6 +785,9 @@ class HintCode extends Enum implements ErrorCode { IS_NOT_DOUBLE, IS_NOT_INT, MISSING_RETURN, + OVERRIDE_ON_NON_OVERRIDING_GETTER, + OVERRIDE_ON_NON_OVERRIDING_METHOD, + OVERRIDE_ON_NON_OVERRIDING_SETTER, OVERRIDDING_PRIVATE_MEMBER, OVERRIDE_EQUALS_BUT_NOT_HASH_CODE, TYPE_CHECK_IS_NOT_NULL, @@ -2421,7 +2439,7 @@ class StaticWarningCode extends Enum implements ErrorCode { * to be thrown, because no setter is defined for it. The assignment will also give rise to a * static warning for the same reason. */ - static final StaticWarningCode ASSIGNMENT_TO_FINAL = new StaticWarningCode.con1('ASSIGNMENT_TO_FINAL', 3, "Final variables cannot be assigned a value"); + static final StaticWarningCode ASSIGNMENT_TO_FINAL = new StaticWarningCode.con1('ASSIGNMENT_TO_FINAL', 3, "'%s' cannot be used as a setter, it is final"); /** * 12.18 Assignment: Let T be the static type of e1. It is a static type @@ -2871,7 +2889,7 @@ class StaticWarningCode extends Enum implements ErrorCode { * @param memberName the name of the fourth member * @param additionalCount the number of additional missing members that aren't listed */ - static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS', 49, "Missing inherited members: '%s', '%s', '%s', '%s' and %d more"); + static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS', 49, "Missing concrete implementation of '%s', '%s', '%s', '%s' and %d more"); /** * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an @@ -2890,7 +2908,7 @@ class StaticWarningCode extends Enum implements ErrorCode { * @param memberName the name of the third member * @param memberName the name of the fourth member */ - static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR', 50, "Missing inherited members: '%s', '%s', '%s' and '%s'"); + static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR', 50, "Missing concrete implementation of '%s', '%s', '%s' and '%s'"); /** * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an @@ -2906,7 +2924,7 @@ class StaticWarningCode extends Enum implements ErrorCode { * * @param memberName the name of the member */ - static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE', 51, "Missing inherited member '%s'"); + static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE', 51, "Missing concrete implementation of '%s'"); /** * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an @@ -2924,7 +2942,7 @@ class StaticWarningCode extends Enum implements ErrorCode { * @param memberName the name of the second member * @param memberName the name of the third member */ - static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE', 52, "Missing inherited members: '%s', '%s' and '%s'"); + static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE', 52, "Missing concrete implementation of '%s', '%s' and '%s'"); /** * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an @@ -2941,7 +2959,7 @@ class StaticWarningCode extends Enum implements ErrorCode { * @param memberName the name of the first member * @param memberName the name of the second member */ - static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO', 53, "Missing inherited members: '%s' and '%s'"); + static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO', 53, "Missing concrete implementation of '%s' and '%s'"); /** * 13.11 Try: An on-catch clause of the form on T catch (p1, p2) s or @@ -3389,7 +3407,7 @@ class StaticTypeWarningCode extends Enum implements Error * * Otherwise none of the members m1, …, mk is inherited. * */ - static final StaticTypeWarningCode INCONSISTENT_METHOD_INHERITANCE = new StaticTypeWarningCode.con1('INCONSISTENT_METHOD_INHERITANCE', 3, "'%s' is inherited by at least two interfaces inconsistently"); + static final StaticTypeWarningCode INCONSISTENT_METHOD_INHERITANCE = new StaticTypeWarningCode.con1('INCONSISTENT_METHOD_INHERITANCE', 3, "'%s' is inherited by at least two interfaces inconsistently, from %s"); /** * 12.15.1 Ordinary Invocation: It is a static type warning if T does not have an diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart index 2d511c13169..85708aaeb6b 100644 --- a/pkg/analyzer/lib/src/generated/html.dart +++ b/pkg/analyzer/lib/src/generated/html.dart @@ -165,29 +165,6 @@ class RawXmlExpression extends XmlExpression { } } -/** - * Instances of `HtmlParseResult` hold the result of parsing an HTML file. - * - * @coverage dart.engine.html - */ -class HtmlParseResult extends HtmlScanResult { - /** - * The unit containing the parsed information (not `null`). - */ - HtmlUnit _unit; - - HtmlParseResult(int modificationTime, Token token, List lineStarts, HtmlUnit unit) : super(modificationTime, token, lineStarts) { - this._unit = unit; - } - - /** - * Answer the unit generated by parsing the source - * - * @return the unit (not `null`) - */ - HtmlUnit get htmlUnit => _unit; -} - /** * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that will recursively * visit all of the nodes in an XML structure. For example, using an instance of this class to visit @@ -975,30 +952,6 @@ abstract class AbstractScanner { } } -/** - * Instances of `HtmlScanResult` hold the result of scanning an HTML file. - * - * @coverage dart.engine.html - */ -class HtmlScanResult { - /** - * The time at which the contents of the source were last set. - */ - final int modificationTime; - - /** - * The first token in the token stream (not `null`). - */ - final Token token; - - /** - * The line start information that was produced. - */ - final List lineStarts; - - HtmlScanResult(this.modificationTime, this.token, this.lineStarts); -} - /** * Instances of the class `StringScanner` implement a scanner that reads from a string. The * scanning logic is in the superclass. @@ -1365,65 +1318,6 @@ class XmlExpression_Reference { } } -/** - * Instances of `HtmlScanner` receive and scan HTML content from a [Source].
- * For example, the following code scans HTML source and returns the result: - * - *
- *   HtmlScanner scanner = new HtmlScanner(source);
- *   source.getContents(scanner);
- *   return scanner.getResult();
- * 
- * - * @coverage dart.engine.html - */ -class HtmlScanner implements Source_ContentReceiver { - List _SCRIPT_TAG = ["script"]; - - /** - * The source being scanned (not `null`) - */ - Source _source; - - /** - * The time at which the contents of the source were last set. - */ - int _modificationTime = 0; - - /** - * The scanner used to scan the source - */ - AbstractScanner _scanner; - - /** - * The first token in the token stream. - */ - Token _token; - - /** - * Construct a new instance to scan the specified source. - * - * @param source the source to be scanned (not `null`) - */ - HtmlScanner(Source source) { - this._source = source; - } - - void accept(String contents, int modificationTime) { - this._modificationTime = modificationTime; - _scanner = new StringScanner(_source, contents); - _scanner.passThroughElements = _SCRIPT_TAG; - _token = _scanner.tokenize(); - } - - /** - * Answer the result of scanning the source - * - * @return the result (not `null`) - */ - HtmlScanResult get result => new HtmlScanResult(_modificationTime, _token, _scanner.lineStarts); -} - /** * Instances of the class `XmlParser` are used to parse tokens into a AST structure comprised * of [XmlNode]s. @@ -1491,22 +1385,20 @@ class XmlParser { List parseTopTagNodes(Token firstToken) { _currentToken = firstToken; List tagNodes = new List(); - while (true) { - while (true) { - if (_currentToken.type == TokenType.LT) { - tagNodes.add(parseTagNode()); - } else if (_currentToken.type == TokenType.DECLARATION || _currentToken.type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) { - // ignored tokens - _currentToken = _currentToken.next; - } else if (_currentToken.type == TokenType.EOF) { - return tagNodes; - } else { - reportUnexpectedToken(); - _currentToken = _currentToken.next; - } - break; + TokenType type = _currentToken.type; + while (type != TokenType.EOF) { + if (identical(type, TokenType.LT)) { + tagNodes.add(parseTagNode()); + } else if (identical(type, TokenType.DECLARATION) || identical(type, TokenType.DIRECTIVE) || identical(type, TokenType.COMMENT)) { + // ignored tokens + _currentToken = _currentToken.next; + } else { + reportUnexpectedToken(); + _currentToken = _currentToken.next; } + type = _currentToken.type; } + return tagNodes; } /** @@ -1572,19 +1464,16 @@ class XmlParser { return XmlTagNode.NO_ATTRIBUTES; } List attributes = new List(); - while (true) { - while (true) { - if (_currentToken.type == TokenType.GT || _currentToken.type == TokenType.SLASH_GT || _currentToken.type == TokenType.EOF) { - return attributes; - } else if (_currentToken.type == TokenType.TAG) { - attributes.add(parseAttribute()); - } else { - reportUnexpectedToken(); - _currentToken = _currentToken.next; - } - break; + while (type != TokenType.GT && type != TokenType.SLASH_GT && type != TokenType.EOF) { + if (identical(type, TokenType.TAG)) { + attributes.add(parseAttribute()); + } else { + reportUnexpectedToken(); + _currentToken = _currentToken.next; } + type = _currentToken.type; } + return attributes; } /** @@ -1599,22 +1488,19 @@ class XmlParser { return XmlTagNode.NO_TAG_NODES; } List nodes = new List(); - while (true) { - while (true) { - if (_currentToken.type == TokenType.LT) { - nodes.add(parseTagNode()); - } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.type == TokenType.EOF) { - return nodes; - } else if (_currentToken.type == TokenType.COMMENT) { - // ignored token - _currentToken = _currentToken.next; - } else { - reportUnexpectedToken(); - _currentToken = _currentToken.next; - } - break; + while (type != TokenType.LT_SLASH && type != TokenType.EOF) { + if (identical(type, TokenType.LT)) { + nodes.add(parseTagNode()); + } else if (identical(type, TokenType.COMMENT)) { + // ignored token + _currentToken = _currentToken.next; + } else { + reportUnexpectedToken(); + _currentToken = _currentToken.next; } + type = _currentToken.type; } + return nodes; } /** @@ -1997,30 +1883,16 @@ class HtmlParser extends XmlParser { } /** - * Parse the tokens specified by the given scan result. + * Parse the given tokens. * - * @param scanResult the result of scanning an HTML source (not `null`) + * @param token the first token in the stream of tokens to be parsed + * @param lineInfo the line information created by the scanner * @return the parse result (not `null`) */ - HtmlParseResult parse(HtmlScanResult scanResult) { - List lineStarts = scanResult.lineStarts; - _lineInfo = new LineInfo(lineStarts); - Token firstToken = scanResult.token; - List tagNodes = parseTopTagNodes(firstToken); - HtmlUnit unit = new HtmlUnit(firstToken, tagNodes, currentToken); - return new HtmlParseResult(scanResult.modificationTime, firstToken, scanResult.lineStarts, unit); - } - - /** - * Scan then parse the specified source. - * - * @param source the source to be scanned and parsed (not `null`) - * @return the parse result (not `null`) - */ - HtmlParseResult parse2(Source source) { - HtmlScanner scanner = new HtmlScanner(source); - source.getContents(scanner); - return parse(scanner.result); + HtmlUnit parse(Token token, LineInfo lineInfo) { + this._lineInfo = lineInfo; + List tagNodes = parseTopTagNodes(token); + return new HtmlUnit(token, tagNodes, currentToken); } XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) => new XmlAttributeNode(name, equals, value); diff --git a/pkg/analyzer/lib/src/generated/index.dart b/pkg/analyzer/lib/src/generated/index.dart index 12d012ac234..397a4e03682 100644 --- a/pkg/analyzer/lib/src/generated/index.dart +++ b/pkg/analyzer/lib/src/generated/index.dart @@ -1212,6 +1212,16 @@ abstract class IndexConstants { * location (the right operand). This is used for methods. */ static final Relationship IS_INVOKED_BY_UNQUALIFIED = Relationship.getRelationship("is-invoked-by-unqualified"); + + /** + * Reference to some [AngularElement]. + */ + static final Relationship ANGULAR_REFERENCE = Relationship.getRelationship("angular-reference"); + + /** + * Reference to some closing tag of an XML element. + */ + static final Relationship ANGULAR_CLOSING_TAG_REFERENCE = Relationship.getRelationship("angular-closing-tag-reference"); } /** @@ -1248,7 +1258,7 @@ class AngularHtmlIndexContributor extends ExpressionVisitor { SimpleIdentifier identifier = expression; Element element = identifier.bestElement; if (element is AngularElement) { - _store.recordRelationship(element, IndexConstants.IS_REFERENCED_BY, createLocation(identifier)); + _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, createLocation(identifier)); return; } } @@ -1268,7 +1278,7 @@ class AngularHtmlIndexContributor extends ExpressionVisitor { if (element != null) { ht.Token nameToken = node.nameToken; Location location = createLocation2(nameToken); - _store.recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); + _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, location); } return super.visitXmlAttributeNode(node); } @@ -1276,9 +1286,18 @@ class AngularHtmlIndexContributor extends ExpressionVisitor { Object visitXmlTagNode(ht.XmlTagNode node) { Element element = node.element; if (element != null) { - ht.Token tagToken = node.tagToken; - Location location = createLocation2(tagToken); - _store.recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); + // tag + { + ht.Token tagToken = node.tagToken; + Location location = createLocation2(tagToken); + _store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, location); + } + // maybe add closing tag range + ht.Token closingTag = node.closingTag; + if (closingTag != null) { + Location location = createLocation2(closingTag); + _store.recordRelationship(element, IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, location); + } } return super.visitXmlTagNode(node); } @@ -1299,7 +1318,7 @@ class IndexContributor_AngularHtmlIndexContributor extends IndexContributor { AngularElement angularElement = AngularHtmlUnitResolver.getAngularElement(element); if (angularElement != null) { element = angularElement; - relationship = IndexConstants.IS_REFERENCED_BY; + relationship = IndexConstants.ANGULAR_REFERENCE; } super.recordRelationship(element, relationship, location); } @@ -1564,13 +1583,17 @@ class IndexContributor extends GeneralizingASTVisitor { Element usedElement = null; if (parent is PrefixedIdentifier) { PrefixedIdentifier prefixed = parent; - usedElement = prefixed.staticElement; - info._periodEnd = prefixed.period.end; + if (identical(prefixed.prefix, prefixNode)) { + usedElement = prefixed.staticElement; + info._periodEnd = prefixed.period.end; + } } if (parent is MethodInvocation) { MethodInvocation invocation = parent; - usedElement = invocation.methodName.staticElement; - info._periodEnd = invocation.period.end; + if (identical(invocation.target, prefixNode)) { + usedElement = invocation.methodName.staticElement; + info._periodEnd = invocation.period.end; + } } // we need used Element if (usedElement == null) { @@ -1740,6 +1763,14 @@ class IndexContributor extends GeneralizingASTVisitor { return location; } + /** + * @return `true` if given "node" is part of an import [Combinator]. + */ + static bool isIdentifierInImportCombinator(SimpleIdentifier node) { + ASTNode parent = node.parent; + return parent is Combinator; + } + /** * @return `true` if given "node" is part of [PrefixedIdentifier] "prefix.node". */ @@ -1923,6 +1954,11 @@ class IndexContributor extends GeneralizingASTVisitor { Object visitConstructorName(ConstructorName node) { ConstructorElement element = node.staticElement; + // in 'class B = A;' actually A constructors are invoked + if (element != null && element.isSynthetic && element.redirectedConstructor != null) { + element = element.redirectedConstructor; + } + // prepare location Location location; if (node.name != null) { int start = node.period.offset; @@ -1932,6 +1968,7 @@ class IndexContributor extends GeneralizingASTVisitor { int start = node.type.end; location = createLocation4(start, 0); } + // record relationship recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location); return super.visitConstructorName(node); } @@ -2240,6 +2277,9 @@ class IndexContributor extends GeneralizingASTVisitor { * top-level element and not qualified with import prefix. */ void recordImportElementReferenceWithoutPrefix(SimpleIdentifier node) { + if (isIdentifierInImportCombinator(node)) { + return; + } if (isIdentifierInPrefixedIdentifier(node)) { return; } @@ -2559,11 +2599,17 @@ class AngularDartIndexContributor extends GeneralizingASTVisitor { indexProperties(directive.properties); } + /** + * Index [FieldElement] references from [AngularPropertyElement]s. + */ void indexProperties(List properties) { for (AngularPropertyElement property in properties) { FieldElement field = property.field; if (field != null) { int offset = property.fieldNameOffset; + if (offset == -1) { + continue; + } int length = field.name.length; Location location = new Location(property, offset, length); // getter reference diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart index 255ea312dc1..2eb5f7fe798 100644 --- a/pkg/analyzer/lib/src/generated/java_core.dart +++ b/pkg/analyzer/lib/src/generated/java_core.dart @@ -284,7 +284,7 @@ class PrintStringWriter extends PrintWriter { } class StringUtils { - static List split(String s, String pattern) => s.split(pattern); + static List split(String s, [String pattern = '']) => s.split(pattern); static String replace(String s, String from, String to) => s.replaceAll(from, to); static String repeat(String s, int n) { StringBuffer sb = new StringBuffer(); diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart index 741568776ee..aef44256171 100644 --- a/pkg/analyzer/lib/src/generated/java_engine.dart +++ b/pkg/analyzer/lib/src/generated/java_engine.dart @@ -4,7 +4,7 @@ import 'java_core.dart'; class StringUtilities { static const String EMPTY = ''; - static const List EMPTY_ARRAY = const []; + static const List EMPTY_ARRAY = const []; static String intern(String s) => s; static bool isTagName(String s) { if (s == null || s.length == 0) { @@ -43,50 +43,37 @@ class StringUtilities { } static endsWith3(String str, int c1, int c2, int c3) { var length = str.length; - return length >= 3 && - str.codeUnitAt(length - 3) == c1 && - str.codeUnitAt(length - 2) == c2 && - str.codeUnitAt(length - 1) == c3; + return length >= 3 && str.codeUnitAt(length - 3) == c1 && str.codeUnitAt( + length - 2) == c2 && str.codeUnitAt(length - 1) == c3; } static startsWithChar(String str, int c) { return str.length != 0 && str.codeUnitAt(0) == c; } static startsWith2(String str, int start, int c1, int c2) { - return str.length - start >= 2 && - str.codeUnitAt(start) == c1 && + return str.length - start >= 2 && str.codeUnitAt(start) == c1 && str.codeUnitAt(start + 1) == c2; } static startsWith3(String str, int start, int c1, int c2, int c3) { - return str.length - start >= 3 && - str.codeUnitAt(start) == c1 && - str.codeUnitAt(start + 1) == c2 && - str.codeUnitAt(start + 2) == c3; + return str.length - start >= 3 && str.codeUnitAt(start) == c1 && + str.codeUnitAt(start + 1) == c2 && str.codeUnitAt(start + 2) == c3; } static startsWith4(String str, int start, int c1, int c2, int c3, int c4) { - return str.length - start >= 4 && - str.codeUnitAt(start) == c1 && - str.codeUnitAt(start + 1) == c2 && - str.codeUnitAt(start + 2) == c3 && + return str.length - start >= 4 && str.codeUnitAt(start) == c1 && + str.codeUnitAt(start + 1) == c2 && str.codeUnitAt(start + 2) == c3 && str.codeUnitAt(start + 3) == c4; } - static startsWith5(String str, int start, int c1, int c2, int c3, int c4, - int c5) { - return str.length - start >= 5 && - str.codeUnitAt(start) == c1 && - str.codeUnitAt(start + 1) == c2 && - str.codeUnitAt(start + 2) == c3 && - str.codeUnitAt(start + 3) == c4 && - str.codeUnitAt(start + 4) == c5; + static startsWith5(String str, int start, int c1, int c2, int c3, int c4, int + c5) { + return str.length - start >= 5 && str.codeUnitAt(start) == c1 && + str.codeUnitAt(start + 1) == c2 && str.codeUnitAt(start + 2) == c3 && + str.codeUnitAt(start + 3) == c4 && str.codeUnitAt(start + 4) == c5; } - static startsWith6(String str, int start, int c1, int c2, int c3, int c4, - int c5, int c6) { - return str.length - start >= 6 && - str.codeUnitAt(start) == c1 && - str.codeUnitAt(start + 1) == c2 && - str.codeUnitAt(start + 2) == c3 && - str.codeUnitAt(start + 3) == c4 && - str.codeUnitAt(start + 4) == c5 && + static startsWith6(String str, int start, int c1, int c2, int c3, int c4, int + c5, int c6) { + return str.length - start >= 6 && str.codeUnitAt(start) == c1 && + str.codeUnitAt(start + 1) == c2 && str.codeUnitAt(start + 2) == c3 && + str.codeUnitAt(start + 3) == c4 && str.codeUnitAt(start + 4) == c5 && str.codeUnitAt(start + 5) == c6; } static int indexOf1(String str, int start, int c) { @@ -111,29 +98,26 @@ class StringUtilities { } return -1; } - static int indexOf4(String string, int start, int c1, int c2, int c3, int c4) { + static int indexOf4(String string, int start, int c1, int c2, int c3, int c4) + { int index = start; int last = string.length - 3; while (index < last) { - if (string.codeUnitAt(index) == c1 && - string.codeUnitAt(index + 1) == c2 && - string.codeUnitAt(index + 2) == c3 && - string.codeUnitAt(index + 3) == c4) { + if (string.codeUnitAt(index) == c1 && string.codeUnitAt(index + 1) == c2 + && string.codeUnitAt(index + 2) == c3 && string.codeUnitAt(index + 3) == c4) { return index; } index++; } return -1; } - static int indexOf5(String str, int start, int c1, int c2, int c3, int c4, - int c5) { + static int indexOf5(String str, int start, int c1, int c2, int c3, int c4, int + c5) { int index = start; int last = str.length - 4; while (index < last) { - if (str.codeUnitAt(index) == c1 && - str.codeUnitAt(index + 1) == c2 && - str.codeUnitAt(index + 2) == c3 && - str.codeUnitAt(index + 3) == c4 && + if (str.codeUnitAt(index) == c1 && str.codeUnitAt(index + 1) == c2 && + str.codeUnitAt(index + 2) == c3 && str.codeUnitAt(index + 3) == c4 && str.codeUnitAt(index + 4) == c5) { return index; } @@ -151,6 +135,24 @@ class StringUtilities { } return str.substring(0, pos); } + + /** + * Return the index of the first not letter/digit character in the [string] + * that is at or after the [startIndex]. Return the length of the [string] if + * all characters to the end are letters/digits. + */ + static int indexOfFirstNotLetterDigit(String string, int startIndex) { + int index = startIndex; + int last = string.length; + while (index < last) { + int c = string.codeUnitAt(index); + if (!Character.isLetterOrDigit(c)) { + return index; + } + index++; + } + return last; + } } class FileNameUtilities { diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart index 4c93ace3bf6..ba8e00c82fd 100644 --- a/pkg/analyzer/lib/src/generated/parser.dart +++ b/pkg/analyzer/lib/src/generated/parser.dart @@ -308,7 +308,11 @@ class IncrementalParseDispatcher implements ASTVisitor { } else if (identical(_oldNode, node.implementsClause)) { return _parser.parseImplementsClause(); } else if (node.members.contains(_oldNode)) { - return _parser.parseClassMember(node.name.name); + ClassMember member = _parser.parseClassMember(node.name.name); + if (member == null) { + throw new InsufficientContextException(); + } + return member; } return notAChild(node); } @@ -1692,6 +1696,14 @@ class Parser { return parseOperator(commentAndMetadata, modifiers.externalKeyword, null); } reportError14(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []); + if (commentAndMetadata.comment != null || !commentAndMetadata.metadata.isEmpty) { + // + // We appear to have found an incomplete declaration at the end of the class. At this point + // it consists of a metadata, which we don't want to loose, so we'll treat it as a method + // declaration with a missing name, parameters and empty body. + // + return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, null, null, null, null, null, createSyntheticIdentifier(), new FormalParameterList(null, new List(), null, null, null), new EmptyFunctionBody(createSyntheticToken2(TokenType.SEMICOLON))); + } return null; } else if (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)) && matches4(peek2(3), TokenType.OPEN_PAREN)) { return parseConstructor(commentAndMetadata, modifiers.externalKeyword, validateModifiersForConstructor(modifiers), modifiers.factoryKeyword, parseSimpleIdentifier(), andAdvance, parseSimpleIdentifier(), parseFormalParameterList()); @@ -2771,6 +2783,21 @@ class Parser { return _currentToken; } + /** + * If [currentToken] is a semicolon, returns it; otherwise reports error and creates a + * synthetic one. + * + * TODO(scheglov) consider pushing this into [expect] + */ + Token expectSemicolon() { + if (matches5(TokenType.SEMICOLON)) { + return andAdvance; + } else { + reportError14(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [";"]); + return createSyntheticToken2(TokenType.SEMICOLON); + } + } + /** * Search the given list of ranges for a range that contains the given index. Return the range * that was found, or `null` if none of the ranges contain the index. @@ -3833,7 +3860,8 @@ class Parser { CommentReference parseCommentReference(String referenceSource, int sourceOffset) { // TODO(brianwilkerson) The errors are not getting the right offset/length and are being duplicated. if (referenceSource.length == 0) { - return null; + Token syntheticToken = new SyntheticStringToken(TokenType.IDENTIFIER, "", sourceOffset); + return new CommentReference(null, new SimpleIdentifier(syntheticToken)); } try { BooleanErrorListener listener = new BooleanErrorListener(); @@ -3900,19 +3928,32 @@ class Parser { while (leftIndex >= 0 && leftIndex + 1 < length) { List range = findRange(codeBlockRanges, leftIndex); if (range == null) { + int nameOffset = token.offset + leftIndex + 1; int rightIndex = JavaString.indexOf(comment, ']', leftIndex); if (rightIndex >= 0) { int firstChar = comment.codeUnitAt(leftIndex + 1); if (firstChar != 0x27 && firstChar != 0x22) { if (isLinkText(comment, rightIndex)) { } else { - CommentReference reference = parseCommentReference(comment.substring(leftIndex + 1, rightIndex), token.offset + leftIndex + 1); + CommentReference reference = parseCommentReference(comment.substring(leftIndex + 1, rightIndex), nameOffset); if (reference != null) { references.add(reference); } } } } else { + // terminating ']' is not typed yet + int charAfterLeft = comment.codeUnitAt(leftIndex + 1); + if (Character.isLetterOrDigit(charAfterLeft)) { + int nameEnd = StringUtilities.indexOfFirstNotLetterDigit(comment, leftIndex + 1); + String name = comment.substring(leftIndex + 1, nameEnd); + Token nameToken = new StringToken(TokenType.IDENTIFIER, name, nameOffset); + references.add(new CommentReference(null, new SimpleIdentifier(nameToken))); + } else { + Token nameToken = new SyntheticStringToken(TokenType.IDENTIFIER, "", nameOffset); + references.add(new CommentReference(null, new SimpleIdentifier(nameToken))); + } + // next character rightIndex = leftIndex + 1; } leftIndex = JavaString.indexOf(comment, '[', rightIndex); @@ -4322,7 +4363,7 @@ class Parser { Token exportKeyword = expect(Keyword.EXPORT); StringLiteral libraryUri = parseStringLiteral(); List combinators = parseCombinators(); - Token semicolon = expect2(TokenType.SEMICOLON); + Token semicolon = expectSemicolon(); return new ExportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, exportKeyword, libraryUri, combinators, semicolon); } @@ -4815,7 +4856,7 @@ class Parser { prefix = parseSimpleIdentifier(); } List combinators = parseCombinators(); - Token semicolon = expect2(TokenType.SEMICOLON); + Token semicolon = expectSemicolon(); return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon); } @@ -5472,9 +5513,7 @@ class Parser { if (!_currentToken.type.isIncrementOperator) { return operand; } - if (operand is Literal || operand is FunctionExpressionInvocation) { - reportError13(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []); - } + ensureAssignable(operand); Token operator = andAdvance; return new PostfixExpression(operand, operator); } @@ -6952,7 +6991,7 @@ class Parser { */ Token validateModifiersForConstructor(Modifiers modifiers) { if (modifiers.abstractKeyword != null) { - reportError13(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); + reportError14(ParserErrorCode.ABSTRACT_CLASS_MEMBER, modifiers.abstractKeyword, []); } if (modifiers.finalKeyword != null) { reportError14(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, []); diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index 3e6f1aaf36b..14b74b95650 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -64,6 +64,14 @@ class AngularCompilationUnitBuilder { if (node is! SimpleStringLiteral) { return null; } + SimpleStringLiteral literal = node as SimpleStringLiteral; + // maybe has AngularElement + { + Element element = literal.toolkitElement; + if (element is AngularElement) { + return element; + } + } // prepare enclosing ClassDeclaration ClassDeclaration classDeclaration = node.getAncestor(ClassDeclaration); if (classDeclaration == null) { @@ -83,17 +91,17 @@ class AngularCompilationUnitBuilder { return toolkitObject; } } + // try selector + if (toolkitObject is AngularHasSelectorElement) { + AngularHasSelectorElement hasSelector = toolkitObject; + AngularSelectorElement selector = hasSelector.selector; + if (isNameCoveredByLiteral(selector, node)) { + return selector; + } + } // try properties of AngularComponentElement if (toolkitObject is AngularComponentElement) { AngularComponentElement component = toolkitObject; - // try selector - { - AngularSelectorElement selector = component.selector; - if (isNameCoveredByLiteral(selector, node)) { - return selector; - } - } - // try properties properties = component.properties; } // try properties of AngularDirectiveElement @@ -129,11 +137,17 @@ class AngularCompilationUnitBuilder { static AngularSelectorElement parseSelector(int offset, String text) { // [attribute] if (StringUtilities.startsWithChar(text, 0x5B) && StringUtilities.endsWithChar(text, 0x5D)) { - int nameOffset = offset + "[".length; + int nameOffset = offset + 1; String attributeName = text.substring(1, text.length - 1); // TODO(scheglov) report warning if there are spaces between [ and identifier return new HasAttributeSelectorElementImpl(attributeName, nameOffset); } + // .class + if (StringUtilities.startsWithChar(text, 0x2E)) { + int nameOffset = offset + 1; + String className = text.substring(1, text.length); + return new AngularHasClassSelectorElementImpl(className, nameOffset); + } // tag[attribute] if (StringUtilities.endsWithChar(text, 0x5D)) { int index = StringUtilities.indexOf1(text, 0, 0x5B); @@ -147,7 +161,7 @@ class AngularCompilationUnitBuilder { } // tag if (StringUtilities.isTagName(text)) { - return new IsTagSelectorElementImpl(text, offset); + return new AngularTagSelectorElementImpl(text, offset); } return null; } @@ -214,6 +228,11 @@ class AngularCompilationUnitBuilder { */ Source _source; + /** + * The compilation unit with built Dart element models. + */ + CompilationUnit _unit; + /** * The [ClassDeclaration] that is currently being analyzed. */ @@ -239,20 +258,21 @@ class AngularCompilationUnitBuilder { * * @param errorListener the listener to which errors will be reported. * @param source the source containing the unit that will be analyzed + * @param unit the compilation unit with built Dart element models */ - AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source source) { + AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source source, CompilationUnit unit) { this._errorListener = errorListener; this._source = source; + this._unit = unit; } /** * Builds Angular specific element models and adds them to the existing Dart elements. - * - * @param unit the compilation unit with built Dart element models */ - void build(CompilationUnit unit) { + void build() { + parseViews(); // process classes - for (CompilationUnitMember unitMember in unit.declarations) { + for (CompilationUnitMember unitMember in _unit.declarations) { if (unitMember is ClassDeclaration) { this._classDeclaration = unitMember; this._classElement = _classDeclaration.element as ClassElementImpl; @@ -403,7 +423,8 @@ class AngularCompilationUnitBuilder { element.templateUriOffset = templateUriOffset; element.styleUri = styleUri; element.styleUriOffset = styleUriOffset; - element.properties = parseNgComponentProperties(true); + element.properties = parseNgComponentProperties(); + element.scopeProperties = parseScopeProperties(); _classToolkitObjects.add(element); } } @@ -411,12 +432,10 @@ class AngularCompilationUnitBuilder { /** * Parses [AngularPropertyElement]s from [annotation] and [classDeclaration]. */ - List parseNgComponentProperties(bool fromFields) { + List parseNgComponentProperties() { List properties = []; parseNgComponentProperties_fromMap(properties); - if (fromFields) { - parseNgComponentProperties_fromFields(properties); - } + parseNgComponentProperties_fromFields(properties); return new List.from(properties); } @@ -582,7 +601,7 @@ class AngularCompilationUnitBuilder { int offset = _annotation.offset; AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offset); element.selector = selector; - element.properties = parseNgComponentProperties(false); + element.properties = parseNgComponentProperties(); _classToolkitObjects.add(element); } } @@ -602,6 +621,25 @@ class AngularCompilationUnitBuilder { } } + List parseScopeProperties() { + List properties = []; + _classDeclaration.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseScopeProperties(properties)); + return new List.from(properties); + } + + /** + * Create [AngularViewElement] for each valid view('template.html') invocation, + * where view is ViewFactory. + */ + void parseViews() { + List views = []; + _unit.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseViews(views)); + if (!views.isEmpty) { + List viewArray = new List.from(views); + (_unit.element as CompilationUnitElementImpl).angularViews = viewArray; + } + } + void reportError(ASTNode node, ErrorCode errorCode, List arguments) { int offset = node.offset; int length = node.length; @@ -622,6 +660,130 @@ class AngularCompilationUnitBuilder { } } +class RecursiveASTVisitor_AngularCompilationUnitBuilder_parseScopeProperties extends RecursiveASTVisitor { + List properties; + + RecursiveASTVisitor_AngularCompilationUnitBuilder_parseScopeProperties(this.properties) : super(); + + Object visitAssignmentExpression(AssignmentExpression node) { + addProperty(node); + return super.visitAssignmentExpression(node); + } + + void addProperty(AssignmentExpression node) { + // try to find "name" in scope[name] + SimpleStringLiteral nameNode = getNameNode(node.leftHandSide); + if (nameNode == null) { + return; + } + // prepare unique + String name = nameNode.stringValue; + if (hasPropertyWithName(name)) { + return; + } + // do add property + int nameOffset = nameNode.valueOffset; + AngularScopePropertyElement property = new AngularScopePropertyElementImpl(name, nameOffset, node.rightHandSide.bestType); + nameNode.toolkitElement = property; + properties.add(property); + } + + SimpleStringLiteral getNameNode(Expression node) { + if (node is IndexExpression) { + IndexExpression indexExpression = node; + Expression target = indexExpression.target; + Expression index = indexExpression.index; + if (index is SimpleStringLiteral && isContext(target)) { + return index; + } + } + return null; + } + + bool hasPropertyWithName(String name) { + for (AngularScopePropertyElement property in properties) { + if (property.name == name) { + return true; + } + } + return false; + } + + bool isContext(Expression target) { + if (target is PrefixedIdentifier) { + PrefixedIdentifier prefixed = target; + SimpleIdentifier prefix = prefixed.prefix; + SimpleIdentifier identifier = prefixed.identifier; + return (identifier.name == "context") && isScope(prefix); + } + return false; + } + + bool isScope(Expression target) { + if (target != null) { + Type2 type = target.bestType; + if (type is InterfaceType) { + InterfaceType interfaceType = type; + return interfaceType.name == "Scope"; + } + } + return false; + } +} + +class RecursiveASTVisitor_AngularCompilationUnitBuilder_parseViews extends RecursiveASTVisitor { + List views; + + RecursiveASTVisitor_AngularCompilationUnitBuilder_parseViews(this.views) : super(); + + Object visitMethodInvocation(MethodInvocation node) { + addView(node); + return super.visitMethodInvocation(node); + } + + void addView(MethodInvocation node) { + // only one argument + List arguments = node.argumentList.arguments; + if (arguments.length != 1) { + return; + } + // String literal + Expression argument = arguments[0]; + if (argument is! SimpleStringLiteral) { + return; + } + SimpleStringLiteral literal = argument as SimpleStringLiteral; + // just view('template') + if (node.realTarget != null) { + return; + } + // should be ViewFactory + if (!isViewFactory(node.methodName)) { + return; + } + // add AngularViewElement + String templateUri = literal.stringValue; + int templateUriOffset = literal.valueOffset; + views.add(new AngularViewElementImpl(templateUri, templateUriOffset)); + } + + bool isViewFactory(Expression target) { + if (target is SimpleIdentifier) { + SimpleIdentifier identifier = target; + Element element = identifier.staticElement; + if (element is VariableElement) { + VariableElement variable = element; + Type2 type = variable.type; + if (type is InterfaceType) { + InterfaceType interfaceType = type; + return interfaceType.name == "ViewFactory"; + } + } + } + return false; + } +} + /** * Instances of the class `CompilationUnitBuilder` build an element model for a single * compilation unit. @@ -828,7 +990,7 @@ class ElementBuilder extends RecursiveASTVisitor { _inFunction = wasInFunction; } SimpleIdentifier constructorName = node.name; - ConstructorElementImpl element = new ConstructorElementImpl(constructorName); + ConstructorElementImpl element = new ConstructorElementImpl.con1(constructorName); if (node.factoryKeyword != null) { element.factory = true; } @@ -1327,7 +1489,7 @@ class ElementBuilder extends RecursiveASTVisitor { * @return the [ConstructorElement]s array with the single default constructor element */ List createDefaultConstructors(InterfaceTypeImpl interfaceType) { - ConstructorElementImpl constructor = new ConstructorElementImpl(null); + ConstructorElementImpl constructor = new ConstructorElementImpl.con1(null); constructor.synthetic = true; constructor.returnType = interfaceType; FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor); @@ -1855,7 +2017,7 @@ class HtmlUnitBuilder implements ht.XmlVisitor { * @return the HTML element that was built * @throws AnalysisException if the analysis could not be performed */ - HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, source.modificationStamp, _context.parseHtmlUnit(source)); + HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, _context.getModificationStamp(source), _context.parseHtmlUnit(source)); /** * Build the HTML element for the given source. @@ -1924,7 +2086,7 @@ class HtmlUnitBuilder implements ht.XmlVisitor { parseUriWithException(scriptSourcePath); Source scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath); script.scriptSource = scriptSource; - if (scriptSource == null || !scriptSource.exists()) { + if (!_context.exists(scriptSource)) { reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribute, [scriptSourcePath]); } } on URISyntaxException catch (exception) { @@ -2863,6 +3025,12 @@ class DeadCodeVerifier extends RecursiveASTVisitor { * expression, or simple infinite loop such as `while(true)`. */ class ExitDetector extends GeneralizingASTVisitor { + /** + * Set to `true` when a `break` is encountered, and reset to `false` when a + * `do`, `while`, `for` or `switch` block is entered. + */ + bool _enclosingBlockContainsBreak = false; + bool visitArgumentList(ArgumentList node) => visitExpressions(node.arguments); bool visitAsExpression(AsExpression node) => node.expression.accept(this); @@ -2903,7 +3071,10 @@ class ExitDetector extends GeneralizingASTVisitor { bool visitBlockFunctionBody(BlockFunctionBody node) => node.block.accept(this); - bool visitBreakStatement(BreakStatement node) => false; + bool visitBreakStatement(BreakStatement node) { + _enclosingBlockContainsBreak = true; + return false; + } bool visitCascadeExpression(CascadeExpression node) { Expression target = node.target; @@ -2931,37 +3102,74 @@ class ExitDetector extends GeneralizingASTVisitor { bool visitContinueStatement(ContinueStatement node) => false; bool visitDoStatement(DoStatement node) { - Expression conditionExpression = node.condition; - if (conditionExpression.accept(this)) { - return true; - } - // TODO(jwren) Do we want to take all constant expressions into account? - if (conditionExpression is BooleanLiteral) { - BooleanLiteral booleanLiteral = conditionExpression; - if (booleanLiteral.value) { - return node.body.accept(this); + bool outerBreakValue = _enclosingBlockContainsBreak; + _enclosingBlockContainsBreak = false; + try { + Expression conditionExpression = node.condition; + if (conditionExpression.accept(this)) { + return true; } + // TODO(jwren) Do we want to take all constant expressions into account? + if (conditionExpression is BooleanLiteral) { + BooleanLiteral booleanLiteral = conditionExpression; + // If do {} while (true), and the body doesn't return or the body doesn't have a break, then + // return true. + bool blockReturns = node.body.accept(this); + if (booleanLiteral.value && (blockReturns || !_enclosingBlockContainsBreak)) { + return true; + } + } + return false; + } finally { + _enclosingBlockContainsBreak = outerBreakValue; } - return false; } bool visitEmptyStatement(EmptyStatement node) => false; bool visitExpressionStatement(ExpressionStatement node) => node.expression.accept(this); - bool visitForEachStatement(ForEachStatement node) => node.iterator.accept(this); + bool visitForEachStatement(ForEachStatement node) { + bool outerBreakValue = _enclosingBlockContainsBreak; + _enclosingBlockContainsBreak = false; + try { + return node.iterator.accept(this); + } finally { + _enclosingBlockContainsBreak = outerBreakValue; + } + } bool visitForStatement(ForStatement node) { - if (node.variables != null && visitVariableDeclarations(node.variables.variables)) { - return true; + bool outerBreakValue = _enclosingBlockContainsBreak; + _enclosingBlockContainsBreak = false; + try { + if (node.variables != null && visitVariableDeclarations(node.variables.variables)) { + return true; + } + if (node.initialization != null && node.initialization.accept(this)) { + return true; + } + Expression conditionExpression = node.condition; + if (conditionExpression != null && conditionExpression.accept(this)) { + return true; + } + if (visitExpressions(node.updaters)) { + return true; + } + // TODO(jwren) Do we want to take all constant expressions into account? + // If for(; true; ) (or for(;;)), and the body doesn't return or the body doesn't have a + // break, then return true. + bool implicitOrExplictTrue = conditionExpression == null || (conditionExpression is BooleanLiteral && conditionExpression.value); + if (implicitOrExplictTrue) { + bool blockReturns = node.body.accept(this); + if (blockReturns || !_enclosingBlockContainsBreak) { + return true; + } + } + return false; + } finally { + _enclosingBlockContainsBreak = outerBreakValue; } - if (node.initialization != null && node.initialization.accept(this)) { - return true; - } - if (node.condition != null && node.condition.accept(this)) { - return true; - } - return visitExpressions(node.updaters); } bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) => false; @@ -3057,25 +3265,31 @@ class ExitDetector extends GeneralizingASTVisitor { bool visitSwitchDefault(SwitchDefault node) => visitStatements(node.statements); bool visitSwitchStatement(SwitchStatement node) { - bool hasDefault = false; - NodeList memberList = node.members; - List members = new List.from(memberList); - for (int i = 0; i < members.length; i++) { - SwitchMember switchMember = members[i]; - if (switchMember is SwitchDefault) { - hasDefault = true; - // If this is the last member and there are no statements, return false - if (switchMember.statements.isEmpty && i + 1 == members.length) { + bool outerBreakValue = _enclosingBlockContainsBreak; + _enclosingBlockContainsBreak = false; + try { + bool hasDefault = false; + NodeList memberList = node.members; + List members = new List.from(memberList); + for (int i = 0; i < members.length; i++) { + SwitchMember switchMember = members[i]; + if (switchMember is SwitchDefault) { + hasDefault = true; + // If this is the last member and there are no statements, return false + if (switchMember.statements.isEmpty && i + 1 == members.length) { + return false; + } + } + // For switch members with no statements, don't visit the children, otherwise, return false if + // no return is found in the children statements + if (!switchMember.statements.isEmpty && !switchMember.accept(this)) { return false; } } - // For switch members with no statements, don't visit the children, otherwise, return false if - // no return is found in the children statements - if (!switchMember.statements.isEmpty && !switchMember.accept(this)) { - return false; - } + return hasDefault; + } finally { + _enclosingBlockContainsBreak = outerBreakValue; } - return hasDefault; } bool visitThisExpression(ThisExpression node) => false; @@ -3116,18 +3330,27 @@ class ExitDetector extends GeneralizingASTVisitor { } bool visitWhileStatement(WhileStatement node) { - Expression conditionExpression = node.condition; - if (conditionExpression.accept(this)) { - return true; - } - // TODO(jwren) Do we want to take all constant expressions into account? - if (conditionExpression is BooleanLiteral) { - BooleanLiteral booleanLiteral = conditionExpression; - if (booleanLiteral.value) { - return node.body.accept(this); + bool outerBreakValue = _enclosingBlockContainsBreak; + _enclosingBlockContainsBreak = false; + try { + Expression conditionExpression = node.condition; + if (conditionExpression.accept(this)) { + return true; } + // TODO(jwren) Do we want to take all constant expressions into account? + if (conditionExpression is BooleanLiteral) { + BooleanLiteral booleanLiteral = conditionExpression; + // If while(true), and the body doesn't return or the body doesn't have a break, then return + // true. + bool blockReturns = node.body.accept(this); + if (booleanLiteral.value && (blockReturns || !_enclosingBlockContainsBreak)) { + return true; + } + } + return false; + } finally { + _enclosingBlockContainsBreak = outerBreakValue; } - return false; } bool visitExpressions(NodeList expressions) { @@ -3176,6 +3399,11 @@ class HintGenerator { bool _enableDart2JSHints = false; + /** + * The inheritance manager used to find overridden methods. + */ + InheritanceManager _manager; + HintGenerator(List compilationUnits, AnalysisContext context, AnalysisErrorListener errorListener) { this._compilationUnits = compilationUnits; this._context = context; @@ -3183,6 +3411,7 @@ class HintGenerator { LibraryElement library = compilationUnits[0].element.library; _importsVerifier = new ImportsVerifier(library); _enableDart2JSHints = context.analysisOptions.dart2jsHint; + _manager = new InheritanceManager(compilationUnits[0].element.library); } void generateForLibrary() { @@ -3210,15 +3439,16 @@ class HintGenerator { void generateForCompilationUnit(CompilationUnit unit, Source source) { ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); - _importsVerifier.visitCompilationUnit(unit); + unit.accept(_importsVerifier); // dead code analysis - new DeadCodeVerifier(errorReporter).visitCompilationUnit(unit); + unit.accept(new DeadCodeVerifier(errorReporter)); // dart2js analysis if (_enableDart2JSHints) { - new Dart2JSVerifier(errorReporter).visitCompilationUnit(unit); + unit.accept(new Dart2JSVerifier(errorReporter)); } // Dart best practices - new BestPracticesVerifier(errorReporter).visitCompilationUnit(unit); + unit.accept(new BestPracticesVerifier(errorReporter)); + unit.accept(new OverrideVerifier(_manager, errorReporter)); // Find to-do comments new ToDoFinder(errorReporter).findIn(unit); } @@ -3564,6 +3794,77 @@ class ImportsVerifier extends RecursiveASTVisitor { } } +/** + * Instances of the class `OverrideVerifier` visit all of the declarations in a compilation + * unit to verify that if they have an override annotation it is being used correctly. + */ +class OverrideVerifier extends RecursiveASTVisitor { + /** + * The inheritance manager used to find overridden methods. + */ + InheritanceManager _manager; + + /** + * The error reporter used to report errors. + */ + ErrorReporter _errorReporter; + + /** + * Initialize a newly created verifier to look for inappropriate uses of the override annotation. + * + * @param manager the inheritance manager used to find overridden methods + * @param errorReporter the error reporter used to report errors + */ + OverrideVerifier(InheritanceManager manager, ErrorReporter errorReporter) { + this._manager = manager; + this._errorReporter = errorReporter; + } + + Object visitMethodDeclaration(MethodDeclaration node) { + ExecutableElement element = node.element; + if (isOverride(element)) { + if (getOverriddenMember(element) == null) { + if (element is MethodElement) { + _errorReporter.reportError3(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, node.name, []); + } else if (element is PropertyAccessorElement) { + if (element.isGetter) { + _errorReporter.reportError3(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, node.name, []); + } else { + _errorReporter.reportError3(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, node.name, []); + } + } + } + } + return super.visitMethodDeclaration(node); + } + + /** + * Return the member that overrides the given member. + * + * @param member the member that overrides the returned member + * @return the member that overrides the given member + */ + ExecutableElement getOverriddenMember(ExecutableElement member) { + LibraryElement library = member.library; + if (library == null) { + return null; + } + ClassElement classElement = member.getAncestor(ClassElement); + if (classElement == null) { + return null; + } + return _manager.lookupInheritance(classElement, member.name); + } + + /** + * Return `true` if the given element has an override annotation associated with it. + * + * @param element the element being tested + * @return `true` if the element has an override annotation associated with it + */ + bool isOverride(Element element) => element != null && element.isOverride; +} + /** * Instances of the class `PubVerifier` traverse an AST structure looking for deviations from * pub best practices. @@ -3615,7 +3916,7 @@ class PubVerifier extends RecursiveASTVisitor { if (StringUtilities.startsWith4(fullName, fullNameIndex - 4, 0x2F, 0x6C, 0x69, 0x62)) { String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSPEC_YAML; Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePubspecPath); - if (pubspecSource != null && pubspecSource.exists()) { + if (_context.exists(pubspecSource)) { // Files inside the lib directory hierarchy should not reference files outside _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE, uriLiteral, []); } @@ -3657,7 +3958,7 @@ class PubVerifier extends RecursiveASTVisitor { Source source = getSource(uriLiteral); String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML; Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePubspecPath); - if (pubspecSource == null || !pubspecSource.exists()) { + if (!_context.exists(pubspecSource)) { return false; } String fullName = getSourceFullName(source); @@ -4971,33 +5272,36 @@ class ElementResolver extends SimpleASTVisitor { * Checks if the given expression is the reference to the type, if it is then the * [ClassElement] is returned, otherwise `null` is returned. * - * @param expr the expression to evaluate + * @param expression the expression to evaluate * @return the [ClassElement] if the given expression is the reference to the type, and * `null` otherwise */ - static ClassElementImpl getTypeReference(Expression expr) { - if (expr is Identifier) { - Identifier identifier = expr; - if (identifier.staticElement is ClassElementImpl) { - return identifier.staticElement as ClassElementImpl; + static ClassElementImpl getTypeReference(Expression expression) { + if (expression is Identifier) { + Element staticElement = expression.staticElement; + if (staticElement is ClassElementImpl) { + return staticElement; } } return null; } /** + * Return `true` if the given identifier is the return type of a constructor declaration. + * * @return `true` if the given identifier is the return type of a constructor declaration. */ - static bool isConstructorReturnType(SimpleIdentifier node) { - ASTNode parent = node.parent; + static bool isConstructorReturnType(SimpleIdentifier identifier) { + ASTNode parent = identifier.parent; if (parent is ConstructorDeclaration) { - ConstructorDeclaration constructor = parent; - return identical(constructor.returnType, node); + return identical(parent.returnType, identifier); } return false; } /** + * Return `true` if the given identifier is the return type of a factory constructor. + * * @return `true` if the given identifier is the return type of a factory constructor * declaration. */ @@ -5011,10 +5315,10 @@ class ElementResolver extends SimpleASTVisitor { } /** - * Checks if the given 'super' expression is used in the valid context. + * Return `true` if the given 'super' expression is used in a valid context. * * @param node the 'super' expression to analyze - * @return `true` if the given 'super' expression is in the valid context + * @return `true` if the 'super' expression is in a valid context */ static bool isSuperInValidContext(SuperExpression node) { for (ASTNode n = node; n != null; n = n.parent) { @@ -5113,22 +5417,10 @@ class ElementResolver extends SimpleASTVisitor { Type2 propagatedType = getPropagatedType(leftHandSide); MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedType, methodName); node.propagatedElement = propagatedMethod; - bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod); - bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false; - // - // If we are about to generate the hint (propagated version of this warning), then check - // that the member is not in a subtype of the propagated type. - // - if (shouldReportMissingMember_propagated) { - if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) { - shouldReportMissingMember_propagated = false; - } - } - if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) { - ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_METHOD : HintCode.UNDEFINED_METHOD) as ErrorCode; - _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, operator, [ - methodName, - shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]); + if (shouldReportMissingMember(staticType, staticMethod)) { + _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.displayName]); + } else if (_enableHints && shouldReportMissingMember(propagatedType, propagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, false)) { + _resolver.reportErrorProxyConditionalAnalysisError3(propagatedType.element, HintCode.UNDEFINED_METHOD, operator, [methodName, propagatedType.displayName]); } } } @@ -5147,22 +5439,10 @@ class ElementResolver extends SimpleASTVisitor { Type2 propagatedType = getPropagatedType(leftOperand); MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedType, methodName); node.propagatedElement = propagatedMethod; - bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod); - bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false; - // - // If we are about to generate the hint (propagated version of this warning), then check - // that the member is not in a subtype of the propagated type. - // - if (shouldReportMissingMember_propagated) { - if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) { - shouldReportMissingMember_propagated = false; - } - } - if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) { - ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; - _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, operator, [ - methodName, - shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]); + if (shouldReportMissingMember(staticType, staticMethod)) { + _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]); + } else if (_enableHints && shouldReportMissingMember(propagatedType, propagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, false)) { + _resolver.reportErrorProxyConditionalAnalysisError3(propagatedType.element, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayName]); } } } @@ -5170,11 +5450,7 @@ class ElementResolver extends SimpleASTVisitor { } Object visitBreakStatement(BreakStatement node) { - SimpleIdentifier labelNode = node.label; - LabelElementImpl labelElement = lookupLabel(node, labelNode); - if (labelElement != null && labelElement.isOnSwitchMember) { - _resolver.reportError9(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []); - } + lookupLabel(node, node.label); return null; } @@ -5275,17 +5551,18 @@ class ElementResolver extends SimpleASTVisitor { ConstructorElement element = node.element; if (element is ConstructorElementImpl) { ConstructorElementImpl constructorElement = element; - // set redirected factory constructor ConstructorName redirectedNode = node.redirectedConstructor; if (redirectedNode != null) { + // set redirected factory constructor ConstructorElement redirectedElement = redirectedNode.staticElement; constructorElement.redirectedConstructor = redirectedElement; - } - // set redirected generate constructor - for (ConstructorInitializer initializer in node.initializers) { - if (initializer is RedirectingConstructorInvocation) { - ConstructorElement redirectedElement = initializer.staticElement; - constructorElement.redirectedConstructor = redirectedElement; + } else { + // set redirected generative constructor + for (ConstructorInitializer initializer in node.initializers) { + if (initializer is RedirectingConstructorInvocation) { + ConstructorElement redirectedElement = initializer.staticElement; + constructorElement.redirectedConstructor = redirectedElement; + } } } setMetadata(constructorElement, node); @@ -5298,11 +5575,6 @@ class ElementResolver extends SimpleASTVisitor { ClassElement enclosingClass = _resolver.enclosingClass; FieldElement fieldElement = enclosingClass.getField(fieldName.name); fieldName.staticElement = fieldElement; - if (fieldElement == null || fieldElement.isSynthetic) { - _resolver.reportError9(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD, node, [fieldName]); - } else if (fieldElement.isStatic) { - _resolver.reportError9(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]); - } return null; } @@ -5312,13 +5584,16 @@ class ElementResolver extends SimpleASTVisitor { return null; } else if (type is! InterfaceType) { // TODO(brianwilkerson) Report these errors. - ASTNode parent = node.parent; - if (parent is InstanceCreationExpression) { - if (parent.isConst) { - } else { - } - } else { - } + // ASTNode parent = node.getParent(); + // if (parent instanceof InstanceCreationExpression) { + // if (((InstanceCreationExpression) parent).isConst()) { + // // CompileTimeErrorCode.CONST_WITH_NON_TYPE + // } else { + // // StaticWarningCode.NEW_WITH_NON_TYPE + // } + // } else { + // // This is part of a redirecting factory constructor; not sure which error code to use + // } return null; } // look up ConstructorElement @@ -5336,11 +5611,7 @@ class ElementResolver extends SimpleASTVisitor { } Object visitContinueStatement(ContinueStatement node) { - SimpleIdentifier labelNode = node.label; - LabelElementImpl labelElement = lookupLabel(node, labelNode); - if (labelElement != null && labelElement.isOnSwitchStatement) { - _resolver.reportError9(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []); - } + lookupLabel(node, node.label); return null; } @@ -5362,38 +5633,6 @@ class ElementResolver extends SimpleASTVisitor { } Object visitFieldFormalParameter(FieldFormalParameter node) { - String fieldName = node.identifier.name; - ClassElement classElement = _resolver.enclosingClass; - if (classElement != null) { - FieldElement fieldElement = classElement.getField(fieldName); - if (fieldElement == null || fieldElement.isSynthetic) { - _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]); - } else { - ParameterElement parameterElement = node.element; - if (parameterElement is FieldFormalParameterElementImpl) { - FieldFormalParameterElementImpl fieldFormal = parameterElement; - Type2 declaredType = fieldFormal.type; - Type2 fieldType = fieldElement.type; - if (fieldElement.isSynthetic) { - _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]); - } else if (fieldElement.isStatic) { - _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]); - } else if (declaredType != null && fieldType != null && !declaredType.isAssignableTo(fieldType)) { - _resolver.reportError9(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]); - } - } else { - if (fieldElement.isSynthetic) { - _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]); - } else if (fieldElement.isStatic) { - _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]); - } - } - } - } - // else { - // // TODO(jwren) Report error, constructor initializer variable is a top level element - // // (Either here or in ErrorVerifier#checkForAllFinalInitializedErrorCodes) - // } setMetadata2(node.element, node); return super.visitFieldFormalParameter(node); } @@ -5673,22 +5912,10 @@ class ElementResolver extends SimpleASTVisitor { Type2 propagatedType = getPropagatedType(operand); MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, methodName); node.propagatedElement = propagatedMethod; - bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod); - bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false; - // - // If we are about to generate the hint (propagated version of this warning), then check - // that the member is not in a subtype of the propagated type. - // - if (shouldReportMissingMember_propagated) { - if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) { - shouldReportMissingMember_propagated = false; - } - } - if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) { - ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; - _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, node.operator, [ - methodName, - shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]); + if (shouldReportMissingMember(staticType, staticMethod)) { + _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.displayName]); + } else if (_enableHints && shouldReportMissingMember(propagatedType, propagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, false)) { + _resolver.reportErrorProxyConditionalAnalysisError3(propagatedType.element, HintCode.UNDEFINED_OPERATOR, node.operator, [methodName, propagatedType.displayName]); } return null; } @@ -5762,22 +5989,10 @@ class ElementResolver extends SimpleASTVisitor { Type2 propagatedType = getPropagatedType(operand); MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, methodName); node.propagatedElement = propagatedMethod; - bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod); - bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false; - // - // If we are about to generate the hint (propagated version of this warning), then check - // that the member is not in a subtype of the propagated type. - // - if (shouldReportMissingMember_propagated) { - if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) { - shouldReportMissingMember_propagated = false; - } - } - if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) { - ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; - _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, operator, [ - methodName, - shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]); + if (shouldReportMissingMember(staticType, staticMethod)) { + _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]); + } else if (_enableHints && shouldReportMissingMember(propagatedType, propagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, false)) { + _resolver.reportErrorProxyConditionalAnalysisError3(propagatedType.element, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayName]); } } return null; @@ -6054,16 +6269,7 @@ class ElementResolver extends SimpleASTVisitor { */ bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, String methodName, MethodElement staticMethod, MethodElement propagatedMethod, Type2 staticType, Type2 propagatedType) { bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod); - bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false; - // - // If we are about to generate the hint (propagated version of this warning), then check - // that the member is not in a subtype of the propagated type. - // - if (shouldReportMissingMember_propagated) { - if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) { - shouldReportMissingMember_propagated = false; - } - } + bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints && shouldReportMissingMember(propagatedType, propagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, false); if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) { sc.Token leftBracket = node.leftBracket; sc.Token rightBracket = node.rightBracket; @@ -6708,12 +6914,13 @@ class ElementResolver extends SimpleASTVisitor { return sc.TokenType.STAR; } else if (operator == sc.TokenType.TILDE_SLASH_EQ) { return sc.TokenType.TILDE_SLASH; + } else { + // Internal error: Unmapped assignment operator. + AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator"); + return operator; } break; } - // Internal error: Unmapped assignment operator. - AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator"); - return operator; } void resolveAnnotationConstructorInvocationArguments(Annotation annotation, ConstructorElement constructor) { @@ -7485,6 +7692,133 @@ class IncrementalResolver { * @coverage dart.engine.resolver */ class InheritanceManager { + /** + * Given some array of [ExecutableElement]s, this method creates a synthetic element as + * described in the Superinterfaces section of Inheritance and Overriding. + * + * TODO (jwren) Copy contents from the Spec into this javadoc. + * + * TODO (jwren) Associate a propagated type to the synthetic method element using least upper + * bound calls + */ + static ExecutableElement computeMergedExecutableElement(List elementArrayToMerge) { + int h = getNumOfPositionalParameters(elementArrayToMerge[0]); + int r = getNumOfRequiredParameters(elementArrayToMerge[0]); + Set namedParametersList = new Set(); + for (int i = 1; i < elementArrayToMerge.length; i++) { + ExecutableElement element = elementArrayToMerge[i]; + int numOfPositionalParams = getNumOfPositionalParameters(element); + if (h < numOfPositionalParams) { + h = numOfPositionalParams; + } + int numOfRequiredParams = getNumOfRequiredParameters(element); + if (r > numOfRequiredParams) { + r = numOfRequiredParams; + } + namedParametersList.addAll(getNamedParameterNames(element)); + } + if (r > h) { + return null; + } + return createSyntheticExecutableElement(elementArrayToMerge, elementArrayToMerge[0].displayName, r, h - r, new List.from(namedParametersList)); + } + + /** + * Used by [computeMergedExecutableElement] to actually create the + * synthetic element. + * + * @param elementArrayToMerge the array used to create the synthetic element + * @param name the name of the method, getter or setter + * @param numOfRequiredParameters the number of required parameters + * @param numOfPositionalParameters the number of positional parameters + * @param namedParameters the list of [String]s that are the named parameters + * @return the created synthetic element + */ + static ExecutableElement createSyntheticExecutableElement(List elementArrayToMerge, String name, int numOfRequiredParameters, int numOfPositionalParameters, List namedParameters) { + DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; + SimpleIdentifier nameIdentifier = new SimpleIdentifier(new sc.StringToken(sc.TokenType.IDENTIFIER, name, 0)); + ExecutableElementImpl executable; + if (elementArrayToMerge[0] is MethodElement) { + MultiplyInheritedMethodElementImpl unionedMethod = new MultiplyInheritedMethodElementImpl(nameIdentifier); + unionedMethod.inheritedElements = elementArrayToMerge; + executable = unionedMethod; + } else { + MultiplyInheritedPropertyAccessorElementImpl unionedPropertyAccessor = new MultiplyInheritedPropertyAccessorElementImpl(nameIdentifier); + unionedPropertyAccessor.getter = (elementArrayToMerge[0] as PropertyAccessorElement).isGetter; + unionedPropertyAccessor.setter = (elementArrayToMerge[0] as PropertyAccessorElement).isSetter; + unionedPropertyAccessor.inheritedElements = elementArrayToMerge; + executable = unionedPropertyAccessor; + } + int numOfParameters = numOfRequiredParameters + numOfPositionalParameters + namedParameters.length; + List parameters = new List(numOfParameters); + int i = 0; + for (int j = 0; j < numOfRequiredParameters; j++, i++) { + ParameterElementImpl parameter = new ParameterElementImpl.con2("", 0); + parameter.type = dynamicType; + parameter.parameterKind = ParameterKind.REQUIRED; + parameters[i] = parameter; + } + for (int k = 0; k < numOfPositionalParameters; k++, i++) { + ParameterElementImpl parameter = new ParameterElementImpl.con2("", 0); + parameter.type = dynamicType; + parameter.parameterKind = ParameterKind.POSITIONAL; + parameters[i] = parameter; + } + for (int m = 0; m < namedParameters.length; m++, i++) { + ParameterElementImpl parameter = new ParameterElementImpl.con2(namedParameters[m], 0); + parameter.type = dynamicType; + parameter.parameterKind = ParameterKind.NAMED; + parameters[i] = parameter; + } + executable.returnType = dynamicType; + executable.parameters = parameters; + FunctionTypeImpl methodType = new FunctionTypeImpl.con1(executable); + executable.type = methodType; + return executable; + } + + /** + * Given some [ExecutableElement], return the list of named parameters. + */ + static List getNamedParameterNames(ExecutableElement executableElement) { + List namedParameterNames = new List(); + List parameters = executableElement.parameters; + for (int i = 0; i < parameters.length; i++) { + ParameterElement parameterElement = parameters[i]; + if (identical(parameterElement.parameterKind, ParameterKind.NAMED)) { + namedParameterNames.add(parameterElement.name); + } + } + return namedParameterNames; + } + + /** + * Given some [ExecutableElement] return the number of parameters of the specified kind. + */ + static int getNumOfParameters(ExecutableElement executableElement, ParameterKind parameterKind) { + int parameterCount = 0; + List parameters = executableElement.parameters; + for (int i = 0; i < parameters.length; i++) { + ParameterElement parameterElement = parameters[i]; + if (identical(parameterElement.parameterKind, parameterKind)) { + parameterCount++; + } + } + return parameterCount; + } + + /** + * Given some [ExecutableElement] return the number of positional parameters. + * + * Note: by positional we mean [ParameterKind#REQUIRED] or [ParameterKind#POSITIONAL]. + */ + static int getNumOfPositionalParameters(ExecutableElement executableElement) => getNumOfParameters(executableElement, ParameterKind.REQUIRED) + getNumOfParameters(executableElement, ParameterKind.POSITIONAL); + + /** + * Given some [ExecutableElement] return the number of required parameters. + */ + static int getNumOfRequiredParameters(ExecutableElement executableElement) => getNumOfParameters(executableElement, ParameterKind.REQUIRED); + /** * The [LibraryElement] that is managed by this manager. */ @@ -7700,7 +8034,7 @@ class InheritanceManager { // List mixins = classElt.mixins; for (int i = mixins.length - 1; i >= 0; i--) { - recordMapWithClassMembers(resultMap, mixins[i]); + recordMapWithClassMembersFromMixin(resultMap, mixins[i]); } _classLookup[classElt] = resultMap; return resultMap; @@ -7868,37 +8202,75 @@ class InheritanceManager { return resultMap; } // - // Union all of the maps together, grouping the ExecutableElements into sets. + // Union all of the lookupMaps together into unionMap, grouping the ExecutableElements into a + // list where none of the elements are equal where equality is determined by having equal + // function types. (We also take note too of the kind of the element: ()->int and () -> int may + // not be equal if one is a getter and the other is a method.) // - Map> unionMap = new Map>(); + Map> unionMap = new Map>(); for (MemberMap lookupMap in lookupMaps) { - for (int i = 0; i < lookupMap.size; i++) { + int lookupMapSize = lookupMap.size; + for (int i = 0; i < lookupMapSize; i++) { + // Get the string key, if null, break. String key = lookupMap.getKey(i); if (key == null) { break; } - Set set = unionMap[key]; - if (set == null) { - set = new Set(); - unionMap[key] = set; + // Get the list value out of the unionMap + List list = unionMap[key]; + // If we haven't created such a map for this key yet, do create it and put the list entry + // into the unionMap. + if (list == null) { + list = new List(); + unionMap[key] = list; + } + // Fetch the entry out of this lookupMap + ExecutableElement newExecutableElementEntry = lookupMap.getValue(i); + if (list.isEmpty) { + // If the list is empty, just the new value + list.add(newExecutableElementEntry); + } else { + // Otherwise, only add the newExecutableElementEntry if it isn't already in the list, this + // covers situation where a class inherits two methods (or two getters) that are + // identical. + bool alreadyInList = false; + bool isMethod1 = newExecutableElementEntry is MethodElement; + for (ExecutableElement executableElementInList in list) { + bool isMethod2 = executableElementInList is MethodElement; + if (identical(isMethod1, isMethod2) && executableElementInList.type == newExecutableElementEntry.type) { + alreadyInList = true; + break; + } + } + if (!alreadyInList) { + list.add(newExecutableElementEntry); + } } - set.add(lookupMap.getValue(i)); } } // - // Loop through the entries in the union map, adding them to the resultMap appropriately. + // Loop through the entries in the unionMap, adding them to the resultMap appropriately. // - for (MapEntry> entry in getMapEntrySet(unionMap)) { + for (MapEntry> entry in getMapEntrySet(unionMap)) { String key = entry.getKey(); - Set set = entry.getValue(); - int numOfEltsWithMatchingNames = set.length; + List list = entry.getValue(); + int numOfEltsWithMatchingNames = list.length; if (numOfEltsWithMatchingNames == 1) { - resultMap.put(key, new JavaIterator(set).next()); + // + // Example: class A inherits only 1 method named 'm'. Since it is the only such method, it + // is inherited. + // Another example: class A inherits 2 methods named 'm' from 2 different interfaces, but + // they both have the same signature, so it is the method inherited. + // + resultMap.put(key, list[0]); } else { + // + // Then numOfEltsWithMatchingNames > 1, check for the warning cases. + // bool allMethods = true; bool allSetters = true; bool allGetters = true; - for (ExecutableElement executableElement in set) { + for (ExecutableElement executableElement in list) { if (executableElement is PropertyAccessorElement) { allMethods = false; if (executableElement.isSetter) { @@ -7911,14 +8283,20 @@ class InheritanceManager { allSetters = false; } } + // + // If there isn't a mixture of methods with getters, then continue, otherwise create a + // warning. + // if (allMethods || allGetters || allSetters) { + // // Compute the element whose type is the subtype of all of the other types. - List elements = new List.from(set); + // + List elements = new List.from(list); List executableElementTypes = new List(numOfEltsWithMatchingNames); for (int i = 0; i < numOfEltsWithMatchingNames; i++) { executableElementTypes[i] = elements[i].type; } - bool foundSubtypeOfAllTypes = false; + List subtypesOfAllOtherTypesIndexes = new List(); for (int i = 0; i < numOfEltsWithMatchingNames; i++) { FunctionType subtype = executableElementTypes[i]; if (subtype == null) { @@ -7934,19 +8312,49 @@ class InheritanceManager { } } if (subtypeOfAllTypes) { - foundSubtypeOfAllTypes = true; - resultMap.put(key, elements[i]); - break; + subtypesOfAllOtherTypesIndexes.add(i); } } - if (!foundSubtypeOfAllTypes) { - reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key]); + // + // The following is split into three cases determined by the number of elements in subtypesOfAllOtherTypes + // + if (subtypesOfAllOtherTypesIndexes.length == 1) { + // + // Example: class A inherited only 2 method named 'm'. One has the function type + // '() -> dynamic' and one has the function type '([int]) -> dynamic'. Since the second + // method is a subtype of all the others, it is the inherited method. + // Tests: InheritanceManagerTest.test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_* + // + resultMap.put(key, elements[subtypesOfAllOtherTypesIndexes[0]]); + } else { + if (subtypesOfAllOtherTypesIndexes.isEmpty) { + // + // Example: class A inherited only 2 method named 'm'. One has the function type + // '() -> int' and one has the function type '() -> String'. Since neither is a subtype + // of the other, we create a warning, and have this class inherit nothing. + // + String firstTwoFuntionTypesStr = "${executableElementTypes[0].toString()}, ${executableElementTypes[1].toString()}"; + reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFuntionTypesStr]); + } else { + // + // Example: class A inherits 2 methods named 'm'. One has the function type + // '(int) -> dynamic' and one has the function type '(num) -> dynamic'. Since they are + // both a subtype of the other, a synthetic function '(dynamic) -> dynamic' is + // inherited. + // Tests: test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_* + // + List elementArrayToMerge = new List(subtypesOfAllOtherTypesIndexes.length); + for (int i = 0; i < elementArrayToMerge.length; i++) { + elementArrayToMerge[i] = elements[subtypesOfAllOtherTypesIndexes[i]]; + } + ExecutableElement mergedExecutableElement = computeMergedExecutableElement(elementArrayToMerge); + if (mergedExecutableElement != null) { + resultMap.put(key, mergedExecutableElement); + } + } } } else { - if (!allMethods && !allGetters) { - reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]); - } - resultMap.remove(entry.getKey()); + reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]); } } } @@ -8002,6 +8410,38 @@ class InheritanceManager { } } + /** + * Similar to [recordMapWithClassMembers], but only puts values + * into the map if the additional executable doesn't replace a concrete member with an abstract + * member, ex: NonErrorResolverTest.test_nonAbstractClassInheritsAbstractMemberOne_mixin_*() + * + * @param map some non-`null` map to put the methods and accessors from the passed + * [ClassElement] into + * @param type the type that will be recorded into the passed map + */ + void recordMapWithClassMembersFromMixin(MemberMap map, InterfaceType type) { + List methods = type.methods; + for (MethodElement method in methods) { + if (method.isAccessibleIn(_library) && !method.isStatic) { + String methodName = method.name; + ExecutableElement elementInMap = map.get(methodName); + if (elementInMap == null || (elementInMap != null && !method.isAbstract)) { + map.put(methodName, method); + } + } + } + List accessors = type.accessors; + for (PropertyAccessorElement accessor in accessors) { + if (accessor.isAccessibleIn(_library) && !accessor.isStatic) { + String accessorName = accessor.name; + ExecutableElement elementInMap = map.get(accessorName); + if (elementInMap == null || (elementInMap != null && !accessor.isAbstract)) { + map.put(accessorName, accessor); + } + } + } + } + /** * This method is used to report errors on when they are found computing inheritance information. * See [ErrorVerifier#checkForInconsistentMethodInheritance] to see where these generated @@ -8292,7 +8732,7 @@ class Library { try { parseUriWithException(uriContent); Source source = _analysisContext.sourceFactory.resolveUri(librarySource, uriContent); - if (source == null || !source.exists()) { + if (!_analysisContext.exists(source)) { _errorListener.onError(new AnalysisError.con2(librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent])); } return source; @@ -8371,7 +8811,7 @@ class LibraryElementBuilder { /** * The name of the function used as an entry point. */ - static String _ENTRY_POINT_NAME = "main"; + static String ENTRY_POINT_NAME = "main"; /** * Initialize a newly created library element builder. @@ -8417,7 +8857,7 @@ class LibraryElementBuilder { PartDirective partDirective = directive; StringLiteral partUri = partDirective.uri; Source partSource = library.getSource(partDirective); - if (partSource != null && partSource.exists()) { + if (_analysisContext.exists(partSource)) { hasPartDirective = true; CompilationUnitElementImpl part = builder.buildCompilationUnit(partSource, library.getAST(partSource)); part.uri = library.getUri(partDirective); @@ -8493,7 +8933,7 @@ class LibraryElementBuilder { */ FunctionElement findEntryPoint(CompilationUnitElementImpl element) { for (FunctionElement function in element.functions) { - if (function.name == _ENTRY_POINT_NAME) { + if (function.name == ENTRY_POINT_NAME) { return function; } } @@ -8955,6 +9395,13 @@ class LibraryResolver { LibraryElementImpl libraryElement = library.libraryElement; libraryElement.imports = new List.from(imports); libraryElement.exports = new List.from(exports); + if (libraryElement.entryPoint == null) { + Namespace namespace = new NamespaceBuilder().createExportNamespace2(libraryElement); + Element element = namespace.get(LibraryElementBuilder.ENTRY_POINT_NAME); + if (element is FunctionElement) { + libraryElement.entryPoint = element; + } + } } } @@ -9126,7 +9573,6 @@ class LibraryResolver { */ Library createLibrary(Source librarySource) { Library library = new Library(analysisContext, _errorListener, librarySource); - library.definingCompilationUnit; _libraryMap[librarySource] = library; return library; } @@ -9158,7 +9604,7 @@ class LibraryResolver { * @return the library object that was created */ Library createLibraryOrNull(Source librarySource) { - if (!librarySource.exists()) { + if (!analysisContext.exists(librarySource)) { return null; } Library library = new Library(analysisContext, _errorListener, librarySource); @@ -9247,7 +9693,7 @@ class LibraryResolver { try { for (Source source in library.compilationUnitSources) { CompilationUnit ast = library.getAST(source); - new AngularCompilationUnitBuilder(_errorListener, source).build(ast); + new AngularCompilationUnitBuilder(_errorListener, source, ast).build(); } } finally { timeCounter.stop(); @@ -9449,14 +9895,6 @@ class MemberMap { * instead of multiple lists of *ConditionalErrorCodes. */ class ProxyConditionalAnalysisError { - /** - * Return `true` if the given element represents a class that has the proxy annotation. - * - * @param element the class being tested - * @return `true` if the given element represents a class that has the proxy annotation - */ - static bool classHasProxyAnnotation(Element element) => (element is ClassElement) && element.isProxy; - /** * The enclosing [ClassElement], this is what will determine if the error code should, or * should not, be generated on the source. @@ -9469,8 +9907,8 @@ class ProxyConditionalAnalysisError { final AnalysisError analysisError; /** - * Instantiate a new ProxyConditionalErrorCode with some enclosing element and the conditional - * analysis error. + * Instantiate a new [ProxyConditionalAnalysisError] with some enclosing element and the + * conditional analysis error. * * @param enclosingElement the enclosing element * @param analysisError the conditional analysis error @@ -9484,7 +9922,12 @@ class ProxyConditionalAnalysisError { * * @return `true` iff the enclosing class has the proxy annotation */ - bool shouldIncludeErrorCode() => !classHasProxyAnnotation(_enclosingElement); + bool shouldIncludeErrorCode() { + if (_enclosingElement is ClassElement) { + return !(_enclosingElement as ClassElement).isOrInheritsProxy; + } + return true; + } } /** @@ -13888,6 +14331,24 @@ class TypeResolverVisitor extends ScopedVisitor { } if (classElement != null && superclassType != null) { classElement.supertype = superclassType; + ClassElement superclassElement = superclassType.element; + if (superclassElement != null) { + List constructors = superclassElement.constructors; + int count = constructors.length; + if (count > 0) { + List parameterTypes = TypeParameterTypeImpl.getTypes(superclassType.typeParameters); + List argumentTypes = getArgumentTypes(node.superclass.typeArguments, parameterTypes); + InterfaceType classType = classElement.type; + List implicitConstructors = new List(); + for (int i = 0; i < count; i++) { + ConstructorElement explicitConstructor = constructors[i]; + if (!explicitConstructor.isFactory) { + implicitConstructors.add(createImplicitContructor(classType, explicitConstructor, parameterTypes, argumentTypes)); + } + } + classElement.constructors = new List.from(implicitConstructors); + } + } } resolve(classElement, node.withClause, node.implementsClause); return null; @@ -14327,6 +14788,73 @@ class TypeResolverVisitor extends ScopedVisitor { } } + /** + * Create an implicit constructor that is copied from the given constructor, but that is in the + * given class. + * + * @param classType the class in which the implicit constructor is defined + * @param explicitConstructor the constructor on which the implicit constructor is modeled + * @param parameterTypes the types to be replaced when creating parameters + * @param argumentTypes the types with which the parameters are to be replaced + * @return the implicit constructor that was created + */ + ConstructorElement createImplicitContructor(InterfaceType classType, ConstructorElement explicitConstructor, List parameterTypes, List argumentTypes) { + ConstructorElementImpl implicitConstructor = new ConstructorElementImpl.con2(explicitConstructor.name, -1); + implicitConstructor.synthetic = true; + implicitConstructor.redirectedConstructor = explicitConstructor; + implicitConstructor.const2 = explicitConstructor.isConst; + implicitConstructor.returnType = classType; + List explicitParameters = explicitConstructor.parameters; + int count = explicitParameters.length; + if (count > 0) { + List implicitParameters = new List(count); + for (int i = 0; i < count; i++) { + ParameterElement explicitParameter = explicitParameters[i]; + ParameterElementImpl implicitParameter = new ParameterElementImpl.con2(explicitParameter.name, -1); + implicitParameter.const3 = explicitParameter.isConst; + implicitParameter.final2 = explicitParameter.isFinal; + implicitParameter.parameterKind = explicitParameter.parameterKind; + implicitParameter.synthetic = true; + implicitParameter.type = explicitParameter.type.substitute2(argumentTypes, parameterTypes); + implicitParameters[i] = implicitParameter; + } + implicitConstructor.parameters = implicitParameters; + } + FunctionTypeImpl type = new FunctionTypeImpl.con1(implicitConstructor); + type.typeArguments = classType.typeArguments; + implicitConstructor.type = type; + return implicitConstructor; + } + + /** + * Return an array of argument types that corresponds to the array of parameter types and that are + * derived from the given list of type arguments. + * + * @param typeArguments the type arguments from which the types will be taken + * @param parameterTypes the parameter types that must be matched by the type arguments + * @return the argument types that correspond to the parameter types + */ + List getArgumentTypes(TypeArgumentList typeArguments, List parameterTypes) { + DynamicTypeImpl dynamic = DynamicTypeImpl.instance; + int parameterCount = parameterTypes.length; + List types = new List(parameterCount); + if (typeArguments == null) { + for (int i = 0; i < parameterCount; i++) { + types[i] = dynamic; + } + } else { + NodeList arguments = typeArguments.arguments; + int argumentCount = Math.min(arguments.length, parameterCount); + for (int i = 0; i < argumentCount; i++) { + types[i] = arguments[i].type; + } + for (int i = argumentCount; i < parameterCount; i++) { + types[i] = dynamic; + } + } + return types; + } + /** * Return the class element that represents the class whose name was provided. * @@ -16432,16 +16960,16 @@ class ErrorVerifier extends RecursiveASTVisitor { ExecutableElement _enclosingFunction; /** - * The number of return statements found in the method or function that we are currently visiting - * that have a return value. + * The return statements found in the method or function that we are currently visiting that have + * a return value. */ - int _returnWithCount = 0; + List _returnsWith = new List(); /** - * The number of return statements found in the method or function that we are currently visiting - * that do not have a return value. + * The return statements found in the method or function that we are currently visiting that do + * not have a return value. */ - int _returnWithoutCount = 0; + List _returnsWithout = new List(); /** * This map is initialized when visiting the contents of a class declaration. If the visitor is @@ -16544,16 +17072,27 @@ class ErrorVerifier extends RecursiveASTVisitor { } Object visitBlockFunctionBody(BlockFunctionBody node) { - int previousReturnWithCount = _returnWithCount; - int previousReturnWithoutCount = _returnWithoutCount; + List previousReturnsWith = _returnsWith; + List previousReturnsWithout = _returnsWithout; try { - _returnWithCount = 0; - _returnWithoutCount = 0; + _returnsWith = new List(); + _returnsWithout = new List(); super.visitBlockFunctionBody(node); checkForMixedReturns(node); } finally { - _returnWithCount = previousReturnWithCount; - _returnWithoutCount = previousReturnWithoutCount; + _returnsWith = previousReturnsWith; + _returnsWithout = previousReturnsWithout; + } + return null; + } + + Object visitBreakStatement(BreakStatement node) { + SimpleIdentifier labelNode = node.label; + if (labelNode != null) { + Element labelElement = labelNode.staticElement; + if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) { + _errorReporter.reportError3(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []); + } } return null; } @@ -16669,6 +17208,7 @@ class ErrorVerifier extends RecursiveASTVisitor { Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { _isInConstructorInitializer = true; try { + checkForInvalidField(node); checkForFieldInitializerNotAssignable(node); return super.visitConstructorFieldInitializer(node); } finally { @@ -16676,6 +17216,17 @@ class ErrorVerifier extends RecursiveASTVisitor { } } + Object visitContinueStatement(ContinueStatement node) { + SimpleIdentifier labelNode = node.label; + if (labelNode != null) { + Element labelElement = labelNode.staticElement; + if (labelElement is LabelElementImpl && labelElement.isOnSwitchStatement) { + _errorReporter.reportError3(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []); + } + } + return null; + } + Object visitDefaultFormalParameter(DefaultFormalParameter node) { checkForInvalidAssignment2(node.identifier, node.defaultValue); checkForDefaultValueInFunctionTypedParameter(node); @@ -16711,7 +17262,7 @@ class ErrorVerifier extends RecursiveASTVisitor { _isInStaticVariableDeclaration = node.isStatic; _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration; try { - checkForAllInvalidOverrideErrorCodes2(node); + checkForAllInvalidOverrideErrorCodes3(node); return super.visitFieldDeclaration(node); } finally { _isInStaticVariableDeclaration = false; @@ -16720,6 +17271,7 @@ class ErrorVerifier extends RecursiveASTVisitor { } Object visitFieldFormalParameter(FieldFormalParameter node) { + checkForValidField(node); checkForConstFormalParameter(node); checkForPrivateOptionalParameter(node); checkForFieldInitializingFormalRedirectingConstructor(node); @@ -16892,7 +17444,7 @@ class ErrorVerifier extends RecursiveASTVisitor { checkForConflictingInstanceMethodSetter(node); } checkForConcreteClassWithAbstractMember(node); - checkForAllInvalidOverrideErrorCodes3(node); + checkForAllInvalidOverrideErrorCodes4(node); return super.visitMethodDeclaration(node); } finally { _enclosingFunction = previousFunction; @@ -16978,9 +17530,9 @@ class ErrorVerifier extends RecursiveASTVisitor { Object visitReturnStatement(ReturnStatement node) { if (node.expression == null) { - _returnWithoutCount++; + _returnsWithout.add(node); } else { - _returnWithCount++; + _returnsWith.add(node); } checkForAllReturnStatementErrorCodes(node); return super.visitReturnStatement(node); @@ -17195,6 +17747,7 @@ class ErrorVerifier extends RecursiveASTVisitor { * This checks the passed executable element against override-error codes. * * @param executableElement a non-null [ExecutableElement] to evaluate + * @param overriddenExecutable the element that the executableElement is overriding * @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 @@ -17210,10 +17763,7 @@ class ErrorVerifier extends RecursiveASTVisitor { * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES */ - bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, List parameters, List parameterLocations, SimpleIdentifier errorNameTarget) { - String executableElementName = executableElement.name; - bool executableElementPrivate = Identifier.isPrivateName(executableElementName); - ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritance(_enclosingClass, executableElementName); + bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, ExecutableElement overriddenExecutable, List parameters, List parameterLocations, SimpleIdentifier errorNameTarget) { bool isGetter = false; bool isSetter = false; if (executableElement is PropertyAccessorElement) { @@ -17221,12 +17771,14 @@ class ErrorVerifier extends RecursiveASTVisitor { isGetter = accessorElement.isGetter; isSetter = accessorElement.isSetter; } + String executableElementName = executableElement.name; // SWC.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC if (overriddenExecutable == null) { if (!isGetter && !isSetter && !executableElement.isOperator) { Set visitedClasses = new Set(); InterfaceType superclassType = _enclosingClass.supertype; ClassElement superclassElement = superclassType == null ? null : superclassType.element; + bool executableElementPrivate = Identifier.isPrivateName(executableElementName); while (superclassElement != null && !visitedClasses.contains(superclassElement)) { visitedClasses.add(superclassElement); LibraryElement superclassLibrary = superclassElement.library; @@ -17466,6 +18018,43 @@ class ErrorVerifier extends RecursiveASTVisitor { return foundError; } + /** + * This checks the passed executable element against override-error codes. This method computes + * the passed executableElement is overriding and calls + * [checkForAllInvalidOverrideErrorCodes] + * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement], this + * method loops through the array in the [MultiplyInheritedExecutableElement]. + * + * @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 + */ + bool checkForAllInvalidOverrideErrorCodes2(ExecutableElement executableElement, List parameters, List parameterLocations, SimpleIdentifier errorNameTarget) { + // + // Compute the overridden executable from the InheritanceManager + // + ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritance(_enclosingClass, executableElement.name); + // + // If the result is a MultiplyInheritedExecutableElement call + // checkForAllInvalidOverrideErrorCodes on all of the elements, until an error is found. + // + if (overriddenExecutable is MultiplyInheritedExecutableElement) { + MultiplyInheritedExecutableElement multiplyInheritedElement = overriddenExecutable; + List overriddenElement = multiplyInheritedElement.inheritedElements; + for (int i = 0; i < overriddenElement.length; i++) { + if (checkForAllInvalidOverrideErrorCodes(executableElement, overriddenElement[i], parameters, parameterLocations, errorNameTarget)) { + return true; + } + } + return false; + } + // + // Otherwise, just call checkForAllInvalidOverrideErrorCodes. + // + return checkForAllInvalidOverrideErrorCodes(executableElement, overriddenExecutable, parameters, parameterLocations, errorNameTarget); + } + /** * This checks the passed field declaration against override-error codes. * @@ -17473,7 +18062,7 @@ class ErrorVerifier extends RecursiveASTVisitor { * @return `true` if and only if an error code is generated on the passed node * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) */ - bool checkForAllInvalidOverrideErrorCodes2(FieldDeclaration node) { + bool checkForAllInvalidOverrideErrorCodes3(FieldDeclaration node) { if (_enclosingClass == null || node.isStatic) { return false; } @@ -17488,10 +18077,10 @@ class ErrorVerifier extends RecursiveASTVisitor { PropertyAccessorElement setter = element.setter; SimpleIdentifier fieldName = field.name; if (getter != null) { - hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideErrorCodes(getter, ParameterElementImpl.EMPTY_ARRAY, ASTNode.EMPTY_ARRAY, fieldName)); + hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideErrorCodes2(getter, ParameterElementImpl.EMPTY_ARRAY, ASTNode.EMPTY_ARRAY, fieldName)); } if (setter != null) { - hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideErrorCodes(setter, setter.parameters, [fieldName], fieldName)); + hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideErrorCodes2(setter, setter.parameters, [fieldName], fieldName)); } } return hasProblems; @@ -17504,7 +18093,7 @@ class ErrorVerifier extends RecursiveASTVisitor { * @return `true` if and only if an error code is generated on the passed node * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) */ - bool checkForAllInvalidOverrideErrorCodes3(MethodDeclaration node) { + bool checkForAllInvalidOverrideErrorCodes4(MethodDeclaration node) { if (_enclosingClass == null || node.isStatic || node.body is NativeFunctionBody) { return false; } @@ -17519,7 +18108,7 @@ class ErrorVerifier extends RecursiveASTVisitor { FormalParameterList formalParameterList = node.parameters; NodeList parameterList = formalParameterList != null ? formalParameterList.parameters : null; List parameters = parameterList != null ? new List.from(parameterList) : null; - return checkForAllInvalidOverrideErrorCodes(executableElement, executableElement.parameters, parameters, methodName); + return checkForAllInvalidOverrideErrorCodes2(executableElement, executableElement.parameters, parameters, methodName); } /** @@ -17831,7 +18420,7 @@ class ErrorVerifier extends RecursiveASTVisitor { return true; } if (variable.isFinal) { - _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_FINAL, expression, []); + _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_FINAL, expression, [variable.name]); return true; } return false; @@ -18807,11 +19396,11 @@ class ErrorVerifier extends RecursiveASTVisitor { */ bool checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node) { // prepare field element - Element fieldNameElement = node.fieldName.staticElement; - if (fieldNameElement is! FieldElement) { + Element staticElement = node.fieldName.staticElement; + if (staticElement is! FieldElement) { return false; } - FieldElement fieldElement = fieldNameElement as FieldElement; + FieldElement fieldElement = staticElement as FieldElement; // prepare field type Type2 fieldType = fieldElement.type; // prepare expression type @@ -19214,7 +19803,13 @@ class ErrorVerifier extends RecursiveASTVisitor { return false; } if (!rightType.isAssignableTo(leftType)) { - _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, node.rightHandSide, [rightType.displayName, leftType.displayName]); + String leftName = leftType.displayName; + String rightName = rightType.displayName; + if (leftName == rightName) { + leftName = getExtendedDisplayName(leftType); + rightName = getExtendedDisplayName(rightType); + } + _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, node.rightHandSide, [rightName, leftName]); return true; } return false; @@ -19237,7 +19832,13 @@ class ErrorVerifier extends RecursiveASTVisitor { Type2 staticRightType = getStaticType(rhs); bool isStaticAssignable = staticRightType.isAssignableTo(leftType); if (!isStaticAssignable) { - _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [staticRightType.displayName, leftType.displayName]); + String leftName = leftType.displayName; + String rightName = staticRightType.displayName; + if (leftName == rightName) { + leftName = getExtendedDisplayName(leftType); + rightName = getExtendedDisplayName(staticRightType); + } + _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightName, leftName]); return true; } // TODO(brianwilkerson) Define a hint corresponding to the warning and report it if appropriate. @@ -19254,6 +19855,27 @@ class ErrorVerifier extends RecursiveASTVisitor { return false; } + /** + * Check the given initializer to ensure that the field being initialized is a valid field. + * + * @param node the field initializer being checked + */ + void checkForInvalidField(ConstructorFieldInitializer node) { + SimpleIdentifier fieldName = node.fieldName; + Element staticElement = fieldName.staticElement; + if (staticElement is FieldElement) { + FieldElement fieldElement = staticElement; + if (fieldElement.isSynthetic) { + _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD, node, [fieldName]); + } else if (fieldElement.isStatic) { + _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]); + } + } else { + _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD, node, [fieldName]); + return; + } + } + /** * This verifies that the usage of the passed 'this' is valid. * @@ -19488,8 +20110,15 @@ class ErrorVerifier extends RecursiveASTVisitor { * @see StaticWarningCode#MIXED_RETURN_TYPES */ bool checkForMixedReturns(BlockFunctionBody node) { - if (_returnWithCount > 0 && _returnWithoutCount > 0) { - _errorReporter.reportError3(StaticWarningCode.MIXED_RETURN_TYPES, node, []); + int withCount = _returnsWith.length; + int withoutCount = _returnsWithout.length; + if (withCount > 0 && withoutCount > 0) { + for (int i = 0; i < withCount; i++) { + _errorReporter.reportError6(StaticWarningCode.MIXED_RETURN_TYPES, _returnsWith[i].keyword, []); + } + for (int i = 0; i < withoutCount; i++) { + _errorReporter.reportError6(StaticWarningCode.MIXED_RETURN_TYPES, _returnsWithout[i].keyword, []); + } return true; } return false; @@ -19702,8 +20331,8 @@ class ErrorVerifier extends RecursiveASTVisitor { if (memberName == null) { break; } - // If the element is defined in Object, skip it. - if ((executableElt.enclosingElement as ClassElement).type.isObject) { + // If the element is not synthetic and can be determined to be defined in Object, skip it. + if (executableElt.enclosingElement != null && (executableElt.enclosingElement as ClassElement).type.isObject) { continue; } // Reference the type of the enclosing class @@ -19747,7 +20376,12 @@ class ErrorVerifier extends RecursiveASTVisitor { List missingOverridesArray = new List.from(missingOverrides); List stringMembersArrayListSet = new List(); for (int i = 0; i < missingOverridesArray.length; i++) { - String newStrMember = "${missingOverridesArray[i].enclosingElement.displayName}.${missingOverridesArray[i].displayName}"; + String newStrMember; + if (missingOverridesArray[i].enclosingElement != null) { + newStrMember = "${missingOverridesArray[i].enclosingElement.displayName}.${missingOverridesArray[i].displayName}"; + } else { + newStrMember = missingOverridesArray[i].displayName; + } if (!stringMembersArrayListSet.contains(newStrMember)) { stringMembersArrayListSet.add(newStrMember); } @@ -20533,6 +21167,36 @@ class ErrorVerifier extends RecursiveASTVisitor { return true; } + void checkForValidField(FieldFormalParameter node) { + ParameterElement element = node.element; + if (element is FieldFormalParameterElement) { + FieldElement fieldElement = element.field; + if (fieldElement == null || fieldElement.isSynthetic) { + _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); + } else { + ParameterElement parameterElement = node.element; + if (parameterElement is FieldFormalParameterElementImpl) { + FieldFormalParameterElementImpl fieldFormal = parameterElement; + Type2 declaredType = fieldFormal.type; + Type2 fieldType = fieldElement.type; + if (fieldElement.isSynthetic) { + _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); + } else if (fieldElement.isStatic) { + _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]); + } else if (declaredType != null && fieldType != null && !declaredType.isAssignableTo(fieldType)) { + _errorReporter.reportError3(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]); + } + } else { + if (fieldElement.isSynthetic) { + _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); + } else if (fieldElement.isStatic) { + _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]); + } + } + } + } + } + /** * This verifies the passed operator-method declaration, has correct number of parameters. * @@ -20659,6 +21323,24 @@ class ErrorVerifier extends RecursiveASTVisitor { return hasProblem; } + /** + * Return a display name for the given type that includes the path to the compilation unit in + * which the type is defined. + * + * @param type the type for which an extended display name is to be returned + * @return a display name that can help distiguish between two types with the same name + */ + String getExtendedDisplayName(Type2 type) { + Element element = type.element; + if (element != null) { + Source source = element.source; + if (source != null) { + return "${type.displayName} (${source.fullName})"; + } + } + return type.displayName; + } + /** * Returns the Type (return type) for a given getter. * @@ -20932,88 +21614,6 @@ class ErrorVerifier extends RecursiveASTVisitor { } bool isUserDefinedObject(EvaluationResultImpl result) => result == null || (result is ValidResult && result.isUserDefinedObject); - - /** - * Return `true` iff the passed [ClassElement] has a concrete implementation of the - * passed accessor name in the superclass chain. - */ - bool memberHasConcreteAccessorImplementationInSuperclassChain(ClassElement classElement, String accessorName, List superclassChain) { - if (superclassChain.contains(classElement)) { - return false; - } else { - superclassChain.add(classElement); - } - for (PropertyAccessorElement accessor in classElement.accessors) { - if (accessor.name == accessorName) { - if (!accessor.isAbstract) { - return true; - } - } - } - for (InterfaceType mixinType in classElement.mixins) { - if (mixinType != null) { - ClassElement mixinElement = mixinType.element; - if (mixinElement != null) { - for (PropertyAccessorElement accessor in mixinElement.accessors) { - if (accessor.name == accessorName) { - if (!accessor.isAbstract) { - return true; - } - } - } - } - } - } - InterfaceType superType = classElement.supertype; - if (superType != null) { - ClassElement superClassElt = superType.element; - if (superClassElt != null) { - return memberHasConcreteAccessorImplementationInSuperclassChain(superClassElt, accessorName, superclassChain); - } - } - return false; - } - - /** - * Return `true` iff the passed [ClassElement] has a concrete implementation of the - * passed method name in the superclass chain. - */ - bool memberHasConcreteMethodImplementationInSuperclassChain(ClassElement classElement, String methodName, List superclassChain) { - if (superclassChain.contains(classElement)) { - return false; - } else { - superclassChain.add(classElement); - } - for (MethodElement method in classElement.methods) { - if (method.name == methodName) { - if (!method.isAbstract) { - return true; - } - } - } - for (InterfaceType mixinType in classElement.mixins) { - if (mixinType != null) { - ClassElement mixinElement = mixinType.element; - if (mixinElement != null) { - for (MethodElement method in mixinElement.methods) { - if (method.name == methodName) { - if (!method.isAbstract) { - return true; - } - } - } - } - } - } - InterfaceType superType = classElement.supertype; - if (superType != null) { - ClassElement superClassElt = superType.element; - if (superClassElt != null) { - return memberHasConcreteMethodImplementationInSuperclassChain(superClassElt, methodName, superclassChain); - } - } - return false; - } } /** diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart index 82d89fb0c00..07a71dd5890 100644 --- a/pkg/analyzer/lib/src/generated/sdk.dart +++ b/pkg/analyzer/lib/src/generated/sdk.dart @@ -208,6 +208,11 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveASTVisitor { */ static String _IMPLEMENTATION = "implementation"; + /** + * The name of the optional parameter used to specify the path used when compiling for dart2js. + */ + static String _DART2JS_PATH = "dart2jsPath"; + /** * The name of the optional parameter used to indicate whether the library is documented. */ @@ -230,11 +235,34 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveASTVisitor { */ static String _VM_PLATFORM = "VM_PLATFORM"; + /** + * A flag indicating whether the dart2js path should be used when it is available. + */ + bool _useDart2jsPaths = false; + /** * The library map that is populated by visiting the AST structure parsed from the contents of * the libraries file. */ - final LibraryMap librariesMap = new LibraryMap(); + LibraryMap _librariesMap = new LibraryMap(); + + /** + * Initialize a newly created library builder to use the dart2js path if the given value is + * `true`. + * + * @param useDart2jsPaths `true` if the dart2js path should be used when it is available + */ + SdkLibrariesReader_LibraryBuilder(bool useDart2jsPaths) { + this._useDart2jsPaths = useDart2jsPaths; + } + + /** + * Return the library map that was populated by visiting the AST structure parsed from the + * contents of the libraries file. + * + * @return the library map describing the contents of the SDK + */ + LibraryMap get librariesMap => _librariesMap; Object visitMapLiteralEntry(MapLiteralEntry node) { String libraryName = null; @@ -267,10 +295,14 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveASTVisitor { library.setDart2JsLibrary(); } } + } else if (_useDart2jsPaths && name == _DART2JS_PATH) { + if (expression is SimpleStringLiteral) { + library.path = expression.value; + } } } } - librariesMap.setLibrary(libraryName, library); + _librariesMap.setLibrary(libraryName, library); } return null; } @@ -352,13 +384,12 @@ abstract class DartSdk { /** * Return the source representing the file with the given URI. * - * @param contentCache the content cache used to access the contents of the mapped source * @param kind the kind of URI that was originally resolved in order to produce an encoding with * the given URI * @param uri the URI of the file to be returned * @return the source representing the specified file */ - Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri); + Source fromEncoding(UriKind kind, Uri uri); /** * Return the [AnalysisContext] used for all of the sources in this [DartSdk]. diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart index 896a15da634..51dfe8e839f 100644 --- a/pkg/analyzer/lib/src/generated/sdk_io.dart +++ b/pkg/analyzer/lib/src/generated/sdk_io.dart @@ -176,12 +176,20 @@ class DirectoryBasedDartSdk implements DartSdk { * * @param sdkDirectory the directory containing the SDK */ - DirectoryBasedDartSdk(JavaFile sdkDirectory) { + DirectoryBasedDartSdk(JavaFile sdkDirectory) : this.con1(sdkDirectory, false); + + /** + * Initialize a newly created SDK to represent the Dart SDK installed in the given directory. + * + * @param sdkDirectory the directory containing the SDK + * @param useDart2jsPaths `true` if the dart2js path should be used when it is available + */ + DirectoryBasedDartSdk.con1(JavaFile sdkDirectory, bool useDart2jsPaths) { this._sdkDirectory = sdkDirectory.getAbsoluteFile(); initializeSdk(); - initializeLibraryMap(); + initializeLibraryMap(useDart2jsPaths); _analysisContext = new AnalysisContextImpl(); - _analysisContext.sourceFactory = new SourceFactory.con2([new DartUriResolver(this)]); + _analysisContext.sourceFactory = new SourceFactory([new DartUriResolver(this)]); List uris = this.uris; ChangeSet changeSet = new ChangeSet(); for (String uri in uris) { @@ -190,7 +198,7 @@ class DirectoryBasedDartSdk implements DartSdk { _analysisContext.applyChanges(changeSet); } - Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) => new FileBasedSource.con2(contentCache, new JavaFile.fromUri(uri), kind); + Source fromEncoding(UriKind kind, Uri uri) => new FileBasedSource.con2(new JavaFile.fromUri(uri), kind); AnalysisContext get context => _analysisContext; @@ -342,7 +350,7 @@ class DirectoryBasedDartSdk implements DartSdk { if (library == null) { return null; } - return new FileBasedSource.con2(_analysisContext.sourceFactory.contentCache, new JavaFile.relative(libraryDirectory, library.path), UriKind.DART_URI); + return new FileBasedSource.con2(new JavaFile.relative(libraryDirectory, library.path), UriKind.DART_URI); } /** @@ -382,12 +390,14 @@ class DirectoryBasedDartSdk implements DartSdk { /** * Read all of the configuration files to initialize the library maps. + * + * @param useDart2jsPaths `true` if the dart2js path should be used when it is available */ - void initializeLibraryMap() { + void initializeLibraryMap(bool useDart2jsPaths) { JavaFile librariesFile = new JavaFile.relative(new JavaFile.relative(libraryDirectory, _INTERNAL_DIR), _LIBRARIES_FILE); try { String contents = librariesFile.readAsStringSync(); - _libraryMap = new SdkLibrariesReader().readFrom(librariesFile, contents); + _libraryMap = new SdkLibrariesReader(useDart2jsPaths).readFrom(librariesFile, contents); } on JavaException catch (exception) { AnalysisEngine.instance.logger.logError2("Could not initialize the library map from ${librariesFile.getAbsolutePath()}", exception); _libraryMap = new LibraryMap(); @@ -430,6 +440,21 @@ class DirectoryBasedDartSdk implements DartSdk { * @coverage dart.engine.sdk */ class SdkLibrariesReader { + /** + * A flag indicating whether the dart2js path should be used when it is available. + */ + bool _useDart2jsPaths = false; + + /** + * Initialize a newly created library reader to use the dart2js path if the given value is + * `true`. + * + * @param useDart2jsPaths `true` if the dart2js path should be used when it is available + */ + SdkLibrariesReader(bool useDart2jsPaths) { + this._useDart2jsPaths = useDart2jsPaths; + } + /** * Return the library map read from the given source. * @@ -437,7 +462,7 @@ class SdkLibrariesReader { * @param libraryFileContents the contents from the library file * @return the library map read from the given source */ - LibraryMap readFrom(JavaFile file, String libraryFileContents) => readFrom2(new FileBasedSource.con2(null, file, UriKind.FILE_URI), libraryFileContents); + LibraryMap readFrom(JavaFile file, String libraryFileContents) => readFrom2(new FileBasedSource.con2(file, UriKind.FILE_URI), libraryFileContents); /** * Return the library map read from the given source. @@ -451,7 +476,7 @@ class SdkLibrariesReader { Scanner scanner = new Scanner(source, new CharSequenceReader(libraryFileContents), errorListener); Parser parser = new Parser(source, errorListener); CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize()); - SdkLibrariesReader_LibraryBuilder libraryBuilder = new SdkLibrariesReader_LibraryBuilder(); + SdkLibrariesReader_LibraryBuilder libraryBuilder = new SdkLibrariesReader_LibraryBuilder(_useDart2jsPaths); // If any syntactic errors were found then don't try to visit the AST structure. if (!errorListener.errorReported) { unit.accept(libraryBuilder); diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart index af3110c15a0..2af88e1d26d 100644 --- a/pkg/analyzer/lib/src/generated/source.dart +++ b/pkg/analyzer/lib/src/generated/source.dart @@ -9,7 +9,7 @@ library engine.source; import 'java_core.dart'; import 'sdk.dart' show DartSdk; -import 'engine.dart' show AnalysisContext; +import 'engine.dart' show AnalysisContext, TimestampedData; /** * Instances of interface `LocalSourcePredicate` are used to determine if the given @@ -67,11 +67,6 @@ class SourceFactory { */ AnalysisContext context; - /** - * A cache of content used to override the default content of a source. - */ - ContentCache _contentCache; - /** * The resolvers used to resolve absolute URI's. */ @@ -80,27 +75,17 @@ class SourceFactory { /** * The predicate to determine is [Source] is local. */ - LocalSourcePredicate _localSourcePredicate; + LocalSourcePredicate _localSourcePredicate = LocalSourcePredicate.NOT_SDK; /** * Initialize a newly created source factory. * - * @param contentCache the cache holding content used to override the default content of a source * @param resolvers the resolvers used to resolve absolute URI's */ - SourceFactory.con1(ContentCache contentCache, List resolvers) { - this._contentCache = contentCache; + SourceFactory(List resolvers) { this._resolvers = resolvers; - this._localSourcePredicate = LocalSourcePredicate.NOT_SDK; } - /** - * Initialize a newly created source factory. - * - * @param resolvers the resolvers used to resolve absolute URI's - */ - SourceFactory.con2(List resolvers) : this.con1(new ContentCache(), resolvers); - /** * Return a source object representing the given absolute URI, or `null` if the URI is not a * valid URI or if it is not an absolute URI. @@ -138,7 +123,7 @@ class SourceFactory { try { Uri uri = parseUriWithException(encoding.substring(1)); for (UriResolver resolver in _resolvers) { - Source result = resolver.fromEncoding(_contentCache, kind, uri); + Source result = resolver.fromEncoding(kind, uri); if (result != null) { return result; } @@ -149,13 +134,6 @@ class SourceFactory { } } - /** - * Return a cache of content used to override the default content of a source. - * - * @return a cache of content used to override the default content of a source - */ - ContentCache get contentCache => _contentCache; - /** * Return the [DartSdk] associated with this [SourceFactory], or `null` if there * is no such SDK. @@ -219,17 +197,6 @@ class SourceFactory { return null; } - /** - * Set the contents of the given source to the given contents. This has the effect of overriding - * the default contents of the source. If the contents are `null` the override is removed so - * that the default contents will be returned. - * - * @param source the source whose contents are being overridden - * @param contents the new contents of the source - * @return the original cached contents or `null` if none - */ - String setContents(Source source, String contents) => _contentCache.setContents(source, contents); - /** * Sets the [LocalSourcePredicate]. * @@ -239,30 +206,6 @@ class SourceFactory { this._localSourcePredicate = localSourcePredicate; } - /** - * Return the contents of the given source, or `null` if this factory does not override the - * contents of the source. - * - * Note: This method is not intended to be used except by - * [FileBasedSource#getContents]. - * - * @param source the source whose content is to be returned - * @return the contents of the given source - */ - String getContents(Source source) => _contentCache.getContents(source); - - /** - * Return the modification stamp of the given source, or `null` if this factory does not - * override the contents of the source. - * - * Note: This method is not intended to be used except by - * [FileBasedSource#getModificationStamp]. - * - * @param source the source whose modification stamp is to be returned - * @return the modification stamp of the given source - */ - int getModificationStamp(Source source) => _contentCache.getModificationStamp(source); - /** * Return a source object representing the URI that results from resolving the given (possibly * relative) contained URI against the URI associated with an existing source object, or @@ -276,7 +219,7 @@ class SourceFactory { Source resolveUri2(Source containingSource, Uri containedUri) { if (containedUri.isAbsolute) { for (UriResolver resolver in _resolvers) { - Source result = resolver.resolveAbsolute(_contentCache, containedUri); + Source result = resolver.resolveAbsolute(containedUri); if (result != null) { return result; } @@ -302,23 +245,21 @@ abstract class UriResolver { * [Source] representing the file to which it was resolved, or `null` if it * could not be resolved. * - * @param contentCache the content cache used to access the contents of the returned source * @param kind the kind of URI that was originally resolved in order to produce an encoding with * the given URI * @param uri the URI to be resolved * @return a [Source] representing the file to which given URI was resolved */ - Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri); + Source fromEncoding(UriKind kind, Uri uri); /** * Resolve the given absolute URI. Return a [Source] representing the file to which * it was resolved, or `null` if it could not be resolved. * - * @param contentCache the content cache used to access the contents of the returned source * @param uri the URI to be resolved * @return a [Source] representing the file to which given URI was resolved */ - Source resolveAbsolute(ContentCache contentCache, Uri uri); + Source resolveAbsolute(Uri uri); /** * Return an absolute URI that represents the given source. @@ -355,20 +296,37 @@ abstract class Source { /** * Return `true` if this source exists. * + * Clients should consider using the the method [AnalysisContext#exists] because + * contexts can have local overrides of the content of a source that the source is not aware of + * and a source with local content is considered to exist even if there is no file on disk. + * * @return `true` if this source exists */ bool exists(); /** - * Get the contents of this source and pass it to the given receiver. Exactly one of the methods - * defined on the receiver will be invoked unless an exception is thrown. The method that will be - * invoked depends on which of the possible representations of the contents is the most efficient. - * Whichever method is invoked, it will be invoked before this method returns. + * Get the contents and timestamp of this source. + * + * Clients should consider using the the method [AnalysisContext#getContents] + * because contexts can have local overrides of the content of a source that the source is not + * aware of. + * + * @return the contents and timestamp of the source + * @throws Exception if the contents of this source could not be accessed + */ + TimestampedData get contents; + + /** + * Get the contents of this source and pass it to the given content receiver. + * + * Clients should consider using the the method + * [AnalysisContext#getContentsToReceiver] because contexts can have local + * overrides of the content of a source that the source is not aware of. * * @param receiver the content receiver to which the content of this source will be passed * @throws Exception if the contents of this source could not be accessed */ - void getContents(Source_ContentReceiver receiver); + void getContentsToReceiver(Source_ContentReceiver receiver); /** * Return an encoded representation of this source that can be used to create a source that is @@ -395,6 +353,10 @@ abstract class Source { * of the source have been modified one or more times (even if the net change is zero) the stamps * will be different. * + * Clients should consider using the the method + * [AnalysisContext#getModificationStamp] because contexts can have local overrides + * of the content of a source that the source is not aware of. + * * @return the modification stamp for this source */ int get modificationStamp; @@ -739,9 +701,9 @@ class DartUriResolver extends UriResolver { this._sdk = sdk; } - Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) { + Source fromEncoding(UriKind kind, Uri uri) { if (identical(kind, UriKind.DART_URI)) { - return _sdk.fromEncoding(contentCache, kind, uri); + return _sdk.fromEncoding(kind, uri); } return null; } @@ -753,7 +715,7 @@ class DartUriResolver extends UriResolver { */ DartSdk get dartSdk => _sdk; - Source resolveAbsolute(ContentCache contentCache, Uri uri) { + Source resolveAbsolute(Uri uri) { if (!isDartUri(uri)) { return null; } @@ -854,7 +816,7 @@ class ContentCache { * contents of the source. * * Note: This method is not intended to be used except by - * [SourceFactory#getContents]. + * [AnalysisContext#getContents]. * * @param source the source whose content is to be returned * @return the contents of the given source @@ -866,7 +828,7 @@ class ContentCache { * override the contents of the source. * * Note: This method is not intended to be used except by - * [SourceFactory#getModificationStamp]. + * [AnalysisContext#getModificationStamp]. * * @param source the source whose modification stamp is to be returned * @return the modification stamp of the given source diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart index ed1ae3b441f..64289d59245 100644 --- a/pkg/analyzer/lib/src/generated/source_io.dart +++ b/pkg/analyzer/lib/src/generated/source_io.dart @@ -10,7 +10,7 @@ library engine.source.io; import 'source.dart'; import 'java_core.dart'; import 'java_io.dart'; -import 'engine.dart' show AnalysisContext, AnalysisEngine; +import 'engine.dart' show AnalysisContext, AnalysisEngine, TimestampedData; export 'source.dart'; /** @@ -63,12 +63,6 @@ class LocalSourcePredicate_NOT_SDK implements LocalSourcePredicate { * @coverage dart.engine.source */ class FileBasedSource implements Source { - /** - * The content cache used to access the contents of this source if they have been overridden from - * what is on disk or cached. - */ - ContentCache _contentCache; - /** * The file represented by this source. */ @@ -88,41 +82,29 @@ class FileBasedSource implements Source { * Initialize a newly created source object. The source object is assumed to not be in a system * library. * - * @param contentCache the content cache used to access the contents of this source * @param file the file represented by this source */ - FileBasedSource.con1(ContentCache contentCache, JavaFile file) : this.con2(contentCache, file, UriKind.FILE_URI); + FileBasedSource.con1(JavaFile file) : this.con2(file, UriKind.FILE_URI); /** * Initialize a newly created source object. * - * @param contentCache the content cache used to access the contents of this source * @param file the file represented by this source * @param flags `true` if this source is in one of the system libraries */ - FileBasedSource.con2(ContentCache contentCache, JavaFile file, UriKind uriKind) { - this._contentCache = contentCache; + FileBasedSource.con2(JavaFile file, UriKind uriKind) { this._file = file; this._uriKind = uriKind; } bool operator ==(Object object) => object != null && this.runtimeType == object.runtimeType && _file == (object as FileBasedSource)._file; - bool exists() => _contentCache.getContents(this) != null || _file.isFile(); + bool exists() => _file.isFile(); - void getContents(Source_ContentReceiver receiver) { - // - // First check to see whether our content cache has an override for our contents. - // - String contents = _contentCache.getContents(this); - if (contents != null) { - receiver.accept(contents, _contentCache.getModificationStamp(this)); - return; - } - // - // If not, read the contents from the file using native I/O. - // - getContentsFromFile(receiver); + TimestampedData get contents => contentsFromFile; + + void getContentsToReceiver(Source_ContentReceiver receiver) { + getContentsFromFileToReceiver(receiver); } String get encoding { @@ -134,13 +116,7 @@ class FileBasedSource implements Source { String get fullName => _file.getAbsolutePath(); - int get modificationStamp { - int stamp = _contentCache.getModificationStamp(this); - if (stamp != null) { - return stamp; - } - return _file.lastModified(); - } + int get modificationStamp => _file.lastModified(); String get shortName => _file.getName(); @@ -153,7 +129,7 @@ class FileBasedSource implements Source { Source resolveRelative(Uri containedUri) { try { Uri resolvedUri = file.toURI().resolveUri(containedUri); - return new FileBasedSource.con2(_contentCache, new JavaFile.fromUri(resolvedUri), _uriKind); + return new FileBasedSource.con2(new JavaFile.fromUri(resolvedUri), _uriKind); } on JavaException catch (exception) { } return null; @@ -167,24 +143,34 @@ class FileBasedSource implements Source { } /** - * Get the contents of underlying file and pass it to the given receiver. Exactly one of the - * methods defined on the receiver will be invoked unless an exception is thrown. The method that - * will be invoked depends on which of the possible representations of the contents is the most - * efficient. Whichever method is invoked, it will be invoked before this method returns. + * Get the contents and timestamp of the underlying file. + * + * Clients should consider using the the method [AnalysisContext#getContents] + * because contexts can have local overrides of the content of a source that the source is not + * aware of. + * + * @return the contents of the source paired with the modification stamp of the source + * @throws Exception if the contents of this source could not be accessed + * @see #getContents() + */ + TimestampedData get contentsFromFile { + return new TimestampedData(_file.lastModified(), _file.readAsStringSync()); + } + + /** + * Get the contents of underlying file and pass it to the given receiver. * * @param receiver the content receiver to which the content of this source will be passed * @throws Exception if the contents of this source could not be accessed - * @see #getContents(com.google.dart.engine.source.Source.ContentReceiver) + * @see #getContentsToReceiver(ContentReceiver) */ - void getContentsFromFile(Source_ContentReceiver receiver) { - { - } - receiver.accept(file.readAsStringSync(), file.lastModified()); + void getContentsFromFileToReceiver(Source_ContentReceiver receiver) { + throw new UnsupportedOperationException(); } /** * Return the file represented by this source. This is an internal method that is only intended to - * be used by [UriResolver]. + * be used by subclasses of [UriResolver] that are designed to work with file-based sources. * * @return the file represented by this source */ @@ -239,14 +225,14 @@ class PackageUriResolver extends UriResolver { this._packagesDirectories = packagesDirectories; } - Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) { + Source fromEncoding(UriKind kind, Uri uri) { if (identical(kind, UriKind.PACKAGE_SELF_URI) || identical(kind, UriKind.PACKAGE_URI)) { - return new FileBasedSource.con2(contentCache, new JavaFile.fromUri(uri), kind); + return new FileBasedSource.con2(new JavaFile.fromUri(uri), kind); } return null; } - Source resolveAbsolute(ContentCache contentCache, Uri uri) { + Source resolveAbsolute(Uri uri) { if (!isPackageUri(uri)) { return null; } @@ -277,10 +263,10 @@ class PackageUriResolver extends UriResolver { if (resolvedFile.exists()) { JavaFile canonicalFile = getCanonicalFile(packagesDirectory, pkgName, relPath); UriKind uriKind = isSelfReference(packagesDirectory, canonicalFile) ? UriKind.PACKAGE_SELF_URI : UriKind.PACKAGE_URI; - return new FileBasedSource.con2(contentCache, canonicalFile, uriKind); + return new FileBasedSource.con2(canonicalFile, uriKind); } } - return new FileBasedSource.con2(contentCache, getCanonicalFile(_packagesDirectories[0], pkgName, relPath), UriKind.PACKAGE_URI); + return new FileBasedSource.con2(getCanonicalFile(_packagesDirectories[0], pkgName, relPath), UriKind.PACKAGE_URI); } Uri restoreAbsolute(Source source) { @@ -425,17 +411,17 @@ class FileUriResolver extends UriResolver { */ static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME; - Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) { + Source fromEncoding(UriKind kind, Uri uri) { if (identical(kind, UriKind.FILE_URI)) { - return new FileBasedSource.con2(contentCache, new JavaFile.fromUri(uri), kind); + return new FileBasedSource.con2(new JavaFile.fromUri(uri), kind); } return null; } - Source resolveAbsolute(ContentCache contentCache, Uri uri) { + Source resolveAbsolute(Uri uri) { if (!isFileUri(uri)) { return null; } - return new FileBasedSource.con1(contentCache, new JavaFile.fromUri(uri)); + return new FileBasedSource.con1(new JavaFile.fromUri(uri)); } } \ No newline at end of file diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart index 8653603a2ed..dd0779263b9 100644 --- a/pkg/analyzer/lib/src/generated/utilities_collection.dart +++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart @@ -123,8 +123,9 @@ class ListUtilities { * @param elements the elements to be added to the list */ static void addAll(List list, List elements) { - for (Object element in elements) { - list.add(element); + int count = elements.length; + for (int i = 0; i < count; i++) { + list.add(elements[i]); } } } \ No newline at end of file diff --git a/pkg/analyzer/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart index 7123bb45902..e3e91c717ce 100644 --- a/pkg/analyzer/lib/src/string_source.dart +++ b/pkg/analyzer/lib/src/string_source.dart @@ -5,6 +5,7 @@ library analyzer.string_source; import 'generated/source.dart'; +import 'generated/engine.dart' show TimestampedData; /// An implementation of [Source] that's based on an in-memory Dart string. class StringSource implements Source { @@ -25,9 +26,11 @@ class StringSource implements Source { bool exists() => true; - void getContents(Source_ContentReceiver receiver) => + void getContentsToReceiver(Source_ContentReceiver receiver) => receiver.accept(_contents, modificationStamp); + TimestampedData get contents => new TimestampedData(modificationStamp, _contents); + String get encoding => throw new UnsupportedError("StringSource doesn't support " "encoding."); diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml index 52ff8997d3c..832ab5e9ad1 100644 --- a/pkg/analyzer/pubspec.yaml +++ b/pkg/analyzer/pubspec.yaml @@ -1,5 +1,5 @@ name: analyzer -version: 0.12.2 +version: 0.13.0-dev author: Dart Team description: Static analyzer for Dart. homepage: http://www.dartlang.org diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart index 198d57d7551..f48f8eec5c7 100644 --- a/pkg/analyzer/test/generated/ast_test.dart +++ b/pkg/analyzer/test/generated/ast_test.dart @@ -870,6 +870,7 @@ class SimpleIdentifierTest extends ParserTestCase { expression = ASTFactory.propertyAccess2(expression, "_"); } else if (wrapper == WrapperKind.PROPERTY_RIGHT) { expression = ASTFactory.propertyAccess(ASTFactory.identifier3("_"), identifier); + } else if (wrapper == WrapperKind.NONE) { } break; } @@ -892,6 +893,7 @@ class SimpleIdentifierTest extends ParserTestCase { ASTFactory.assignmentExpression(expression, TokenType.EQ, ASTFactory.identifier3("_")); } else if (assignment == AssignmentKind.SIMPLE_RIGHT) { ASTFactory.assignmentExpression(ASTFactory.identifier3("_"), TokenType.EQ, expression); + } else if (assignment == AssignmentKind.NONE) { } break; } diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart index 974e35d1140..99246b90fbf 100644 --- a/pkg/analyzer/test/generated/element_test.dart +++ b/pkg/analyzer/test/generated/element_test.dart @@ -281,8 +281,8 @@ class LibraryElementImplTest extends EngineTestCase { AnalysisContext context = createAnalysisContext(); LibraryElementImpl library = ElementFactory.library(context, "test"); CompilationUnitElement unitLib = library.definingCompilationUnit; - CompilationUnitElementImpl unitA = ElementFactory.compilationUnit(context, "unit_a.dart"); - CompilationUnitElementImpl unitB = ElementFactory.compilationUnit(context, "unit_b.dart"); + CompilationUnitElementImpl unitA = ElementFactory.compilationUnit("unit_a.dart"); + CompilationUnitElementImpl unitB = ElementFactory.compilationUnit("unit_b.dart"); library.parts = [unitA, unitB]; EngineTestCase.assertEqualsIgnoreOrder( [unitLib, unitA, unitB], library.units); } @@ -348,9 +348,9 @@ class LibraryElementImplTest extends EngineTestCase { void test_isUpToDate() { AnalysisContext context = createAnalysisContext(); - context.sourceFactory = new SourceFactory.con2([]); + context.sourceFactory = new SourceFactory([]); LibraryElement library = ElementFactory.library(context, "foo"); - context.sourceFactory.setContents(library.definingCompilationUnit.source, "sdfsdff"); + context.setContents(library.definingCompilationUnit.source, "sdfsdff"); // Assert that we are not up to date if the target has an old time stamp. JUnitTestCase.assertFalse(library.isUpToDate2(0)); // Assert that we are up to date with a target modification time in the future. @@ -2486,8 +2486,8 @@ class ElementFactory { static ClassElementImpl classElement2(String typeName, List parameterNames) => classElement(typeName, object.type, parameterNames); - static CompilationUnitElementImpl compilationUnit(AnalysisContext context, String fileName) { - FileBasedSource source = new FileBasedSource.con1(context.sourceFactory.contentCache, FileUtilities2.createFile(fileName)); + static CompilationUnitElementImpl compilationUnit(String fileName) { + FileBasedSource source = new FileBasedSource.con1(FileUtilities2.createFile(fileName)); CompilationUnitElementImpl unit = new CompilationUnitElementImpl(fileName); unit.source = source; return unit; @@ -2495,7 +2495,7 @@ class ElementFactory { static ConstructorElementImpl constructorElement(ClassElement definingClass, String name, bool isConst, List argumentTypes) { Type2 type = definingClass.type; - ConstructorElementImpl constructor = new ConstructorElementImpl(name == null ? null : ASTFactory.identifier3(name)); + ConstructorElementImpl constructor = new ConstructorElementImpl.con1(name == null ? null : ASTFactory.identifier3(name)); constructor.const2 = isConst; int count = argumentTypes.length; List parameters = new List(count); @@ -2654,7 +2654,7 @@ class ElementFactory { } static HtmlElementImpl htmlUnit(AnalysisContext context, String fileName) { - FileBasedSource source = new FileBasedSource.con1(context.sourceFactory.contentCache, FileUtilities2.createFile(fileName)); + FileBasedSource source = new FileBasedSource.con1(FileUtilities2.createFile(fileName)); HtmlElementImpl unit = new HtmlElementImpl(context, fileName); unit.source = source; return unit; @@ -2670,7 +2670,7 @@ class ElementFactory { static LibraryElementImpl library(AnalysisContext context, String libraryName) { String fileName = "/${libraryName}.dart"; - CompilationUnitElementImpl unit = compilationUnit(context, fileName); + CompilationUnitElementImpl unit = compilationUnit(fileName); LibraryElementImpl library = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2([libraryName])); library.definingCompilationUnit = unit; return library; diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart index 68e4cbafd16..2e4791a750c 100644 --- a/pkg/analyzer/test/generated/parser_test.dart +++ b/pkg/analyzer/test/generated/parser_test.dart @@ -296,7 +296,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseAdditiveExpression_normal() { - BinaryExpression expression = ParserTestCase.parse5("parseAdditiveExpression", "x + y", []); + BinaryExpression expression = ParserTestCase.parse4("parseAdditiveExpression", "x + y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.PLUS, expression.operator.type); @@ -304,7 +304,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseAdditiveExpression_super() { - BinaryExpression expression = ParserTestCase.parse5("parseAdditiveExpression", "super + y", []); + BinaryExpression expression = ParserTestCase.parse4("parseAdditiveExpression", "super + y", []); EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.PLUS, expression.operator.type); @@ -312,7 +312,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseAnnotation_n1() { - Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A", []); + Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A", []); JUnitTestCase.assertNotNull(annotation.atSign); JUnitTestCase.assertNotNull(annotation.name); JUnitTestCase.assertNull(annotation.period); @@ -321,7 +321,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseAnnotation_n1_a() { - Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A(x,y)", []); + Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A(x,y)", []); JUnitTestCase.assertNotNull(annotation.atSign); JUnitTestCase.assertNotNull(annotation.name); JUnitTestCase.assertNull(annotation.period); @@ -330,7 +330,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseAnnotation_n2() { - Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B", []); + Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B", []); JUnitTestCase.assertNotNull(annotation.atSign); JUnitTestCase.assertNotNull(annotation.name); JUnitTestCase.assertNull(annotation.period); @@ -339,7 +339,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseAnnotation_n2_a() { - Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B(x,y)", []); + Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B(x,y)", []); JUnitTestCase.assertNotNull(annotation.atSign); JUnitTestCase.assertNotNull(annotation.name); JUnitTestCase.assertNull(annotation.period); @@ -348,7 +348,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseAnnotation_n3() { - Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B.C", []); + Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B.C", []); JUnitTestCase.assertNotNull(annotation.atSign); JUnitTestCase.assertNotNull(annotation.name); JUnitTestCase.assertNotNull(annotation.period); @@ -357,7 +357,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseAnnotation_n3_a() { - Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B.C(x,y)", []); + Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B.C(x,y)", []); JUnitTestCase.assertNotNull(annotation.atSign); JUnitTestCase.assertNotNull(annotation.name); JUnitTestCase.assertNotNull(annotation.period); @@ -366,7 +366,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseArgument_named() { - NamedExpression expression = ParserTestCase.parse5("parseArgument", "n: x", []); + NamedExpression expression = ParserTestCase.parse4("parseArgument", "n: x", []); Label name = expression.name; JUnitTestCase.assertNotNull(name); JUnitTestCase.assertNotNull(name.label); @@ -376,42 +376,42 @@ class SimpleParserTest extends ParserTestCase { void test_parseArgument_unnamed() { String lexeme = "x"; - SimpleIdentifier identifier = ParserTestCase.parse5("parseArgument", lexeme, []); + SimpleIdentifier identifier = ParserTestCase.parse4("parseArgument", lexeme, []); JUnitTestCase.assertEquals(lexeme, identifier.name); } void test_parseArgumentDefinitionTest() { - ArgumentDefinitionTest test = ParserTestCase.parse5("parseArgumentDefinitionTest", "?x", [ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST]); + ArgumentDefinitionTest test = ParserTestCase.parse4("parseArgumentDefinitionTest", "?x", [ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST]); JUnitTestCase.assertNotNull(test.question); JUnitTestCase.assertNotNull(test.identifier); } void test_parseArgumentList_empty() { - ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "()", []); + ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "()", []); NodeList arguments = argumentList.arguments; EngineTestCase.assertSize(0, arguments); } void test_parseArgumentList_mixed() { - ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(w, x, y: y, z: z)", []); + ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(w, x, y: y, z: z)", []); NodeList arguments = argumentList.arguments; EngineTestCase.assertSize(4, arguments); } void test_parseArgumentList_noNamed() { - ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(x, y, z)", []); + ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(x, y, z)", []); NodeList arguments = argumentList.arguments; EngineTestCase.assertSize(3, arguments); } void test_parseArgumentList_onlyNamed() { - ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(x: x, y: y)", []); + ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(x: x, y: y)", []); NodeList arguments = argumentList.arguments; EngineTestCase.assertSize(2, arguments); } void test_parseAssertStatement() { - AssertStatement statement = ParserTestCase.parse5("parseAssertStatement", "assert (x);", []); + AssertStatement statement = ParserTestCase.parse4("parseAssertStatement", "assert (x);", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.condition); @@ -510,7 +510,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseBitwiseAndExpression_normal() { - BinaryExpression expression = ParserTestCase.parse5("parseBitwiseAndExpression", "x & y", []); + BinaryExpression expression = ParserTestCase.parse4("parseBitwiseAndExpression", "x & y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.AMPERSAND, expression.operator.type); @@ -518,7 +518,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseBitwiseAndExpression_super() { - BinaryExpression expression = ParserTestCase.parse5("parseBitwiseAndExpression", "super & y", []); + BinaryExpression expression = ParserTestCase.parse4("parseBitwiseAndExpression", "super & y", []); EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.AMPERSAND, expression.operator.type); @@ -526,7 +526,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseBitwiseOrExpression_normal() { - BinaryExpression expression = ParserTestCase.parse5("parseBitwiseOrExpression", "x | y", []); + BinaryExpression expression = ParserTestCase.parse4("parseBitwiseOrExpression", "x | y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.BAR, expression.operator.type); @@ -534,7 +534,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseBitwiseOrExpression_super() { - BinaryExpression expression = ParserTestCase.parse5("parseBitwiseOrExpression", "super | y", []); + BinaryExpression expression = ParserTestCase.parse4("parseBitwiseOrExpression", "super | y", []); EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.BAR, expression.operator.type); @@ -542,7 +542,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseBitwiseXorExpression_normal() { - BinaryExpression expression = ParserTestCase.parse5("parseBitwiseXorExpression", "x ^ y", []); + BinaryExpression expression = ParserTestCase.parse4("parseBitwiseXorExpression", "x ^ y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.CARET, expression.operator.type); @@ -550,7 +550,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseBitwiseXorExpression_super() { - BinaryExpression expression = ParserTestCase.parse5("parseBitwiseXorExpression", "super ^ y", []); + BinaryExpression expression = ParserTestCase.parse4("parseBitwiseXorExpression", "super ^ y", []); EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.CARET, expression.operator.type); @@ -558,35 +558,35 @@ class SimpleParserTest extends ParserTestCase { } void test_parseBlock_empty() { - Block block = ParserTestCase.parse5("parseBlock", "{}", []); + Block block = ParserTestCase.parse4("parseBlock", "{}", []); JUnitTestCase.assertNotNull(block.leftBracket); EngineTestCase.assertSize(0, block.statements); JUnitTestCase.assertNotNull(block.rightBracket); } void test_parseBlock_nonEmpty() { - Block block = ParserTestCase.parse5("parseBlock", "{;}", []); + Block block = ParserTestCase.parse4("parseBlock", "{;}", []); JUnitTestCase.assertNotNull(block.leftBracket); EngineTestCase.assertSize(1, block.statements); JUnitTestCase.assertNotNull(block.rightBracket); } void test_parseBreakStatement_label() { - BreakStatement statement = ParserTestCase.parse5("parseBreakStatement", "break foo;", []); + BreakStatement statement = ParserTestCase.parse4("parseBreakStatement", "break foo;", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.label); JUnitTestCase.assertNotNull(statement.semicolon); } void test_parseBreakStatement_noLabel() { - BreakStatement statement = ParserTestCase.parse5("parseBreakStatement", "break;", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]); + BreakStatement statement = ParserTestCase.parse4("parseBreakStatement", "break;", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNull(statement.label); JUnitTestCase.assertNotNull(statement.semicolon); } void test_parseCascadeSection_i() { - IndexExpression section = ParserTestCase.parse5("parseCascadeSection", "..[i]", []); + IndexExpression section = ParserTestCase.parse4("parseCascadeSection", "..[i]", []); JUnitTestCase.assertNull(section.target); JUnitTestCase.assertNotNull(section.leftBracket); JUnitTestCase.assertNotNull(section.index); @@ -594,13 +594,13 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCascadeSection_ia() { - FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..[i](b)", []); + FunctionExpressionInvocation section = ParserTestCase.parse4("parseCascadeSection", "..[i](b)", []); EngineTestCase.assertInstanceOf(IndexExpression, section.function); JUnitTestCase.assertNotNull(section.argumentList); } void test_parseCascadeSection_ii() { - MethodInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b).c(d)", []); + MethodInvocation section = ParserTestCase.parse4("parseCascadeSection", "..a(b).c(d)", []); EngineTestCase.assertInstanceOf(MethodInvocation, section.target); JUnitTestCase.assertNotNull(section.period); JUnitTestCase.assertNotNull(section.methodName); @@ -609,14 +609,14 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCascadeSection_p() { - PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..a", []); + PropertyAccess section = ParserTestCase.parse4("parseCascadeSection", "..a", []); JUnitTestCase.assertNull(section.target); JUnitTestCase.assertNotNull(section.operator); JUnitTestCase.assertNotNull(section.propertyName); } void test_parseCascadeSection_p_assign() { - AssignmentExpression section = ParserTestCase.parse5("parseCascadeSection", "..a = 3", []); + AssignmentExpression section = ParserTestCase.parse4("parseCascadeSection", "..a = 3", []); JUnitTestCase.assertNotNull(section.leftHandSide); JUnitTestCase.assertNotNull(section.operator); Expression rhs = section.rightHandSide; @@ -624,7 +624,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCascadeSection_p_assign_withCascade() { - AssignmentExpression section = ParserTestCase.parse5("parseCascadeSection", "..a = 3..m()", []); + AssignmentExpression section = ParserTestCase.parse4("parseCascadeSection", "..a = 3..m()", []); JUnitTestCase.assertNotNull(section.leftHandSide); JUnitTestCase.assertNotNull(section.operator); Expression rhs = section.rightHandSide; @@ -632,14 +632,14 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCascadeSection_p_builtIn() { - PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..as", []); + PropertyAccess section = ParserTestCase.parse4("parseCascadeSection", "..as", []); JUnitTestCase.assertNull(section.target); JUnitTestCase.assertNotNull(section.operator); JUnitTestCase.assertNotNull(section.propertyName); } void test_parseCascadeSection_pa() { - MethodInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)", []); + MethodInvocation section = ParserTestCase.parse4("parseCascadeSection", "..a(b)", []); JUnitTestCase.assertNull(section.target); JUnitTestCase.assertNotNull(section.period); JUnitTestCase.assertNotNull(section.methodName); @@ -648,21 +648,21 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCascadeSection_paa() { - FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)(c)", []); + FunctionExpressionInvocation section = ParserTestCase.parse4("parseCascadeSection", "..a(b)(c)", []); EngineTestCase.assertInstanceOf(MethodInvocation, section.function); JUnitTestCase.assertNotNull(section.argumentList); EngineTestCase.assertSize(1, section.argumentList.arguments); } void test_parseCascadeSection_paapaa() { - FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)(c).d(e)(f)", []); + FunctionExpressionInvocation section = ParserTestCase.parse4("parseCascadeSection", "..a(b)(c).d(e)(f)", []); EngineTestCase.assertInstanceOf(MethodInvocation, section.function); JUnitTestCase.assertNotNull(section.argumentList); EngineTestCase.assertSize(1, section.argumentList.arguments); } void test_parseCascadeSection_pap() { - PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..a(b).c", []); + PropertyAccess section = ParserTestCase.parse4("parseCascadeSection", "..a(b).c", []); JUnitTestCase.assertNotNull(section.target); JUnitTestCase.assertNotNull(section.operator); JUnitTestCase.assertNotNull(section.propertyName); @@ -1204,7 +1204,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCombinators_h() { - List combinators = ParserTestCase.parse5("parseCombinators", "hide a;", []); + List combinators = ParserTestCase.parse4("parseCombinators", "hide a;", []); EngineTestCase.assertSize(1, combinators); HideCombinator combinator = combinators[0] as HideCombinator; JUnitTestCase.assertNotNull(combinator); @@ -1213,7 +1213,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCombinators_hs() { - List combinators = ParserTestCase.parse5("parseCombinators", "hide a show b;", []); + List combinators = ParserTestCase.parse4("parseCombinators", "hide a show b;", []); EngineTestCase.assertSize(2, combinators); HideCombinator hideCombinator = combinators[0] as HideCombinator; JUnitTestCase.assertNotNull(hideCombinator); @@ -1226,12 +1226,12 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCombinators_hshs() { - List combinators = ParserTestCase.parse5("parseCombinators", "hide a show b hide c show d;", []); + List combinators = ParserTestCase.parse4("parseCombinators", "hide a show b hide c show d;", []); EngineTestCase.assertSize(4, combinators); } void test_parseCombinators_s() { - List combinators = ParserTestCase.parse5("parseCombinators", "show a;", []); + List combinators = ParserTestCase.parse4("parseCombinators", "show a;", []); EngineTestCase.assertSize(1, combinators); ShowCombinator combinator = combinators[0] as ShowCombinator; JUnitTestCase.assertNotNull(combinator); @@ -1240,61 +1240,61 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCommentAndMetadata_c() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ void", []); JUnitTestCase.assertNotNull(commentAndMetadata.comment); EngineTestCase.assertSize(0, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_cmc() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ void", []); JUnitTestCase.assertNotNull(commentAndMetadata.comment); EngineTestCase.assertSize(1, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_cmcm() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ @B void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ @B void", []); JUnitTestCase.assertNotNull(commentAndMetadata.comment); EngineTestCase.assertSize(2, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_cmm() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A @B void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ @A @B void", []); JUnitTestCase.assertNotNull(commentAndMetadata.comment); EngineTestCase.assertSize(2, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_m() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A void", []); JUnitTestCase.assertNull(commentAndMetadata.comment); EngineTestCase.assertSize(1, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_mcm() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A /** 1 */ @B void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A /** 1 */ @B void", []); JUnitTestCase.assertNotNull(commentAndMetadata.comment); EngineTestCase.assertSize(2, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_mcmc() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A /** 1 */ @B /** 2 */ void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A /** 1 */ @B /** 2 */ void", []); JUnitTestCase.assertNotNull(commentAndMetadata.comment); EngineTestCase.assertSize(2, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_mm() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A @B(x) void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A @B(x) void", []); JUnitTestCase.assertNull(commentAndMetadata.comment); EngineTestCase.assertSize(2, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_none() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "void", []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "void", []); JUnitTestCase.assertNull(commentAndMetadata.comment); EngineTestCase.assertSize(0, commentAndMetadata.metadata); } void test_parseCommentAndMetadata_singleLine() { - CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", EngineTestCase.createSource(["/// 1", "/// 2", "void"]), []); + CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", EngineTestCase.createSource(["/// 1", "/// 2", "void"]), []); JUnitTestCase.assertNotNull(commentAndMetadata.comment); EngineTestCase.assertSize(0, commentAndMetadata.metadata); } @@ -1343,6 +1343,16 @@ class SimpleParserTest extends ParserTestCase { JUnitTestCase.assertEquals(5, identifier.offset); } + void test_parseCommentReference_synthetic() { + CommentReference reference = ParserTestCase.parse("parseCommentReference", ["", 5], ""); + SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier); + JUnitTestCase.assertNotNull(identifier); + JUnitTestCase.assertTrue(identifier.isSynthetic); + JUnitTestCase.assertNotNull(identifier.token); + JUnitTestCase.assertEquals("", identifier.name); + JUnitTestCase.assertEquals(5, identifier.offset); + } + void test_parseCommentReferences_multiLine() { List tokens = [new StringToken(TokenType.MULTI_LINE_COMMENT, "/** xxx [a] yyy [b] zzz */", 3)]; List references = ParserTestCase.parse("parseCommentReferences", [tokens], ""); @@ -1357,6 +1367,28 @@ class SimpleParserTest extends ParserTestCase { JUnitTestCase.assertEquals(20, reference.offset); } + void test_parseCommentReferences_notClosed_noIdentifier() { + List tokens = [new StringToken(TokenType.MULTI_LINE_COMMENT, "/** [ some text", 5)]; + List references = ParserTestCase.parse("parseCommentReferences", [tokens], ""); + EngineTestCase.assertSize(1, references); + CommentReference reference = references[0]; + JUnitTestCase.assertNotNull(reference); + JUnitTestCase.assertNotNull(reference.identifier); + JUnitTestCase.assertTrue(reference.identifier.isSynthetic); + JUnitTestCase.assertEquals("", reference.identifier.name); + } + + void test_parseCommentReferences_notClosed_withIdentifier() { + List tokens = [new StringToken(TokenType.MULTI_LINE_COMMENT, "/** [namePrefix some text", 5)]; + List references = ParserTestCase.parse("parseCommentReferences", [tokens], ""); + EngineTestCase.assertSize(1, references); + CommentReference reference = references[0]; + JUnitTestCase.assertNotNull(reference); + JUnitTestCase.assertNotNull(reference.identifier); + JUnitTestCase.assertFalse(reference.identifier.isSynthetic); + JUnitTestCase.assertEquals("namePrefix", reference.identifier.name); + } + void test_parseCommentReferences_singleLine() { List tokens = [ new StringToken(TokenType.SINGLE_LINE_COMMENT, "/// xxx [a] yyy [b] zzz", 3), @@ -1428,74 +1460,74 @@ class SimpleParserTest extends ParserTestCase { } void test_parseCompilationUnit_abstractAsPrefix_parameterized() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "abstract _abstract = new abstract.A();", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "abstract _abstract = new abstract.A();", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(0, unit.directives); EngineTestCase.assertSize(1, unit.declarations); } void test_parseCompilationUnit_builtIn_asFunctionName() { - ParserTestCase.parse5("parseCompilationUnit", "abstract(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "as(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "dynamic(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "export(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "external(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "factory(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "get(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "implements(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "import(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "library(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "operator(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "part(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "set(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "static(x) => 0;", []); - ParserTestCase.parse5("parseCompilationUnit", "typedef(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "abstract(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "as(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "dynamic(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "export(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "external(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "factory(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "get(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "implements(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "import(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "library(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "operator(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "part(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "set(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "static(x) => 0;", []); + ParserTestCase.parse4("parseCompilationUnit", "typedef(x) => 0;", []); } void test_parseCompilationUnit_directives_multiple() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library l;\npart 'a.dart';", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "library l;\npart 'a.dart';", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(2, unit.directives); EngineTestCase.assertSize(0, unit.declarations); } void test_parseCompilationUnit_directives_single() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library l;", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "library l;", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(1, unit.directives); EngineTestCase.assertSize(0, unit.declarations); } void test_parseCompilationUnit_empty() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(0, unit.directives); EngineTestCase.assertSize(0, unit.declarations); } void test_parseCompilationUnit_exportAsPrefix() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "export.A _export = new export.A();", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "export.A _export = new export.A();", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(0, unit.directives); EngineTestCase.assertSize(1, unit.declarations); } void test_parseCompilationUnit_exportAsPrefix_parameterized() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "export _export = new export.A();", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "export _export = new export.A();", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(0, unit.directives); EngineTestCase.assertSize(1, unit.declarations); } void test_parseCompilationUnit_operatorAsPrefix_parameterized() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "operator _operator = new operator.A();", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "operator _operator = new operator.A();", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(0, unit.directives); EngineTestCase.assertSize(1, unit.declarations); } void test_parseCompilationUnit_script() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "#! /bin/dart", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "#! /bin/dart", []); JUnitTestCase.assertNotNull(unit.scriptTag); EngineTestCase.assertSize(0, unit.directives); EngineTestCase.assertSize(0, unit.declarations); @@ -1503,20 +1535,20 @@ class SimpleParserTest extends ParserTestCase { void test_parseCompilationUnit_skipFunctionBody_withInterpolation() { ParserTestCase._parseFunctionBodies = false; - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "f() { '\${n}'; }", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "f() { '\${n}'; }", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(1, unit.declarations); } void test_parseCompilationUnit_topLevelDeclaration() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "class A {}", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "class A {}", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(0, unit.directives); EngineTestCase.assertSize(1, unit.declarations); } void test_parseCompilationUnit_typedefAsPrefix() { - CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "typedef.A _typedef = new typedef.A();", []); + CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "typedef.A _typedef = new typedef.A();", []); JUnitTestCase.assertNull(unit.scriptTag); EngineTestCase.assertSize(0, unit.directives); EngineTestCase.assertSize(1, unit.declarations); @@ -1713,7 +1745,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConditionalExpression() { - ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? y : z", []); + ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? y : z", []); JUnitTestCase.assertNotNull(expression.condition); JUnitTestCase.assertNotNull(expression.question); JUnitTestCase.assertNotNull(expression.thenExpression); @@ -1722,7 +1754,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConstExpression_instanceCreation() { - InstanceCreationExpression expression = ParserTestCase.parse5("parseConstExpression", "const A()", []); + InstanceCreationExpression expression = ParserTestCase.parse4("parseConstExpression", "const A()", []); JUnitTestCase.assertNotNull(expression.keyword); ConstructorName name = expression.constructorName; JUnitTestCase.assertNotNull(name); @@ -1733,7 +1765,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConstExpression_listLiteral_typed() { - ListLiteral literal = ParserTestCase.parse5("parseConstExpression", "const []", []); + ListLiteral literal = ParserTestCase.parse4("parseConstExpression", "const []", []); JUnitTestCase.assertNotNull(literal.constKeyword); JUnitTestCase.assertNotNull(literal.typeArguments); JUnitTestCase.assertNotNull(literal.leftBracket); @@ -1742,7 +1774,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConstExpression_listLiteral_untyped() { - ListLiteral literal = ParserTestCase.parse5("parseConstExpression", "const []", []); + ListLiteral literal = ParserTestCase.parse4("parseConstExpression", "const []", []); JUnitTestCase.assertNotNull(literal.constKeyword); JUnitTestCase.assertNull(literal.typeArguments); JUnitTestCase.assertNotNull(literal.leftBracket); @@ -1751,7 +1783,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConstExpression_mapLiteral_typed() { - MapLiteral literal = ParserTestCase.parse5("parseConstExpression", "const {}", []); + MapLiteral literal = ParserTestCase.parse4("parseConstExpression", "const {}", []); JUnitTestCase.assertNotNull(literal.leftBracket); EngineTestCase.assertSize(0, literal.entries); JUnitTestCase.assertNotNull(literal.rightBracket); @@ -1759,7 +1791,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConstExpression_mapLiteral_untyped() { - MapLiteral literal = ParserTestCase.parse5("parseConstExpression", "const {}", []); + MapLiteral literal = ParserTestCase.parse4("parseConstExpression", "const {}", []); JUnitTestCase.assertNotNull(literal.leftBracket); EngineTestCase.assertSize(0, literal.entries); JUnitTestCase.assertNotNull(literal.rightBracket); @@ -1770,7 +1802,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConstructorFieldInitializer_qualified() { - ConstructorFieldInitializer invocation = ParserTestCase.parse5("parseConstructorFieldInitializer", "this.a = b", []); + ConstructorFieldInitializer invocation = ParserTestCase.parse4("parseConstructorFieldInitializer", "this.a = b", []); JUnitTestCase.assertNotNull(invocation.equals); JUnitTestCase.assertNotNull(invocation.expression); JUnitTestCase.assertNotNull(invocation.fieldName); @@ -1779,7 +1811,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConstructorFieldInitializer_unqualified() { - ConstructorFieldInitializer invocation = ParserTestCase.parse5("parseConstructorFieldInitializer", "a = b", []); + ConstructorFieldInitializer invocation = ParserTestCase.parse4("parseConstructorFieldInitializer", "a = b", []); JUnitTestCase.assertNotNull(invocation.equals); JUnitTestCase.assertNotNull(invocation.expression); JUnitTestCase.assertNotNull(invocation.fieldName); @@ -1788,42 +1820,42 @@ class SimpleParserTest extends ParserTestCase { } void test_parseConstructorName_named_noPrefix() { - ConstructorName name = ParserTestCase.parse5("parseConstructorName", "A.n;", []); + ConstructorName name = ParserTestCase.parse4("parseConstructorName", "A.n;", []); JUnitTestCase.assertNotNull(name.type); JUnitTestCase.assertNull(name.period); JUnitTestCase.assertNull(name.name); } void test_parseConstructorName_named_prefixed() { - ConstructorName name = ParserTestCase.parse5("parseConstructorName", "p.A.n;", []); + ConstructorName name = ParserTestCase.parse4("parseConstructorName", "p.A.n;", []); JUnitTestCase.assertNotNull(name.type); JUnitTestCase.assertNotNull(name.period); JUnitTestCase.assertNotNull(name.name); } void test_parseConstructorName_unnamed_noPrefix() { - ConstructorName name = ParserTestCase.parse5("parseConstructorName", "A;", []); + ConstructorName name = ParserTestCase.parse4("parseConstructorName", "A;", []); JUnitTestCase.assertNotNull(name.type); JUnitTestCase.assertNull(name.period); JUnitTestCase.assertNull(name.name); } void test_parseConstructorName_unnamed_prefixed() { - ConstructorName name = ParserTestCase.parse5("parseConstructorName", "p.A;", []); + ConstructorName name = ParserTestCase.parse4("parseConstructorName", "p.A;", []); JUnitTestCase.assertNotNull(name.type); JUnitTestCase.assertNull(name.period); JUnitTestCase.assertNull(name.name); } void test_parseContinueStatement_label() { - ContinueStatement statement = ParserTestCase.parse5("parseContinueStatement", "continue foo;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]); + ContinueStatement statement = ParserTestCase.parse4("parseContinueStatement", "continue foo;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.label); JUnitTestCase.assertNotNull(statement.semicolon); } void test_parseContinueStatement_noLabel() { - ContinueStatement statement = ParserTestCase.parse5("parseContinueStatement", "continue;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]); + ContinueStatement statement = ParserTestCase.parse4("parseContinueStatement", "continue;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNull(statement.label); JUnitTestCase.assertNotNull(statement.semicolon); @@ -1870,14 +1902,14 @@ class SimpleParserTest extends ParserTestCase { } void test_parseDocumentationComment_block() { - Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/** */ class", []); + Comment comment = ParserTestCase.parse4("parseDocumentationComment", "/** */ class", []); JUnitTestCase.assertFalse(comment.isBlock); JUnitTestCase.assertTrue(comment.isDocumentation); JUnitTestCase.assertFalse(comment.isEndOfLine); } void test_parseDocumentationComment_block_withReference() { - Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/** [a] */ class", []); + Comment comment = ParserTestCase.parse4("parseDocumentationComment", "/** [a] */ class", []); JUnitTestCase.assertFalse(comment.isBlock); JUnitTestCase.assertTrue(comment.isDocumentation); JUnitTestCase.assertFalse(comment.isEndOfLine); @@ -1889,14 +1921,14 @@ class SimpleParserTest extends ParserTestCase { } void test_parseDocumentationComment_endOfLine() { - Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/// \n/// \n class", []); + Comment comment = ParserTestCase.parse4("parseDocumentationComment", "/// \n/// \n class", []); JUnitTestCase.assertFalse(comment.isBlock); JUnitTestCase.assertTrue(comment.isDocumentation); JUnitTestCase.assertFalse(comment.isEndOfLine); } void test_parseDoStatement() { - DoStatement statement = ParserTestCase.parse5("parseDoStatement", "do {} while (x);", []); + DoStatement statement = ParserTestCase.parse4("parseDoStatement", "do {} while (x);", []); JUnitTestCase.assertNotNull(statement.doKeyword); JUnitTestCase.assertNotNull(statement.body); JUnitTestCase.assertNotNull(statement.whileKeyword); @@ -1907,12 +1939,12 @@ class SimpleParserTest extends ParserTestCase { } void test_parseEmptyStatement() { - EmptyStatement statement = ParserTestCase.parse5("parseEmptyStatement", ";", []); + EmptyStatement statement = ParserTestCase.parse4("parseEmptyStatement", ";", []); JUnitTestCase.assertNotNull(statement.semicolon); } void test_parseEqualityExpression_normal() { - BinaryExpression expression = ParserTestCase.parse5("parseEqualityExpression", "x == y", []); + BinaryExpression expression = ParserTestCase.parse4("parseEqualityExpression", "x == y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type); @@ -1920,7 +1952,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseEqualityExpression_super() { - BinaryExpression expression = ParserTestCase.parse5("parseEqualityExpression", "super == y", []); + BinaryExpression expression = ParserTestCase.parse4("parseEqualityExpression", "super == y", []); EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type); @@ -1969,7 +2001,7 @@ class SimpleParserTest extends ParserTestCase { void test_parseExpression_assign() { // TODO(brianwilkerson) Implement more tests for this method. - AssignmentExpression expression = ParserTestCase.parse5("parseExpression", "x = y", []); + AssignmentExpression expression = ParserTestCase.parse4("parseExpression", "x = y", []); JUnitTestCase.assertNotNull(expression.leftHandSide); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.EQ, expression.operator.type); @@ -1977,7 +2009,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseExpression_comparison() { - BinaryExpression expression = ParserTestCase.parse5("parseExpression", "--a.b == c", []); + BinaryExpression expression = ParserTestCase.parse4("parseExpression", "--a.b == c", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type); @@ -1985,7 +2017,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseExpression_invokeFunctionExpression() { - FunctionExpressionInvocation invocation = ParserTestCase.parse5("parseExpression", "(a) {return a + a;} (3)", []); + FunctionExpressionInvocation invocation = ParserTestCase.parse4("parseExpression", "(a) {return a + a;} (3)", []); EngineTestCase.assertInstanceOf(FunctionExpression, invocation.function); FunctionExpression expression = invocation.function as FunctionExpression; JUnitTestCase.assertNotNull(expression.parameters); @@ -1996,25 +2028,25 @@ class SimpleParserTest extends ParserTestCase { } void test_parseExpression_superMethodInvocation() { - MethodInvocation invocation = ParserTestCase.parse5("parseExpression", "super.m()", []); + MethodInvocation invocation = ParserTestCase.parse4("parseExpression", "super.m()", []); JUnitTestCase.assertNotNull(invocation.target); JUnitTestCase.assertNotNull(invocation.methodName); JUnitTestCase.assertNotNull(invocation.argumentList); } void test_parseExpressionList_multiple() { - List result = ParserTestCase.parse5("parseExpressionList", "1, 2, 3", []); + List result = ParserTestCase.parse4("parseExpressionList", "1, 2, 3", []); EngineTestCase.assertSize(3, result); } void test_parseExpressionList_single() { - List result = ParserTestCase.parse5("parseExpressionList", "1", []); + List result = ParserTestCase.parse4("parseExpressionList", "1", []); EngineTestCase.assertSize(1, result); } void test_parseExpressionWithoutCascade_assign() { // TODO(brianwilkerson) Implement more tests for this method. - AssignmentExpression expression = ParserTestCase.parse5("parseExpressionWithoutCascade", "x = y", []); + AssignmentExpression expression = ParserTestCase.parse4("parseExpressionWithoutCascade", "x = y", []); JUnitTestCase.assertNotNull(expression.leftHandSide); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.EQ, expression.operator.type); @@ -2022,7 +2054,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseExpressionWithoutCascade_comparison() { - BinaryExpression expression = ParserTestCase.parse5("parseExpressionWithoutCascade", "--a.b == c", []); + BinaryExpression expression = ParserTestCase.parse4("parseExpressionWithoutCascade", "--a.b == c", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type); @@ -2030,14 +2062,14 @@ class SimpleParserTest extends ParserTestCase { } void test_parseExpressionWithoutCascade_superMethodInvocation() { - MethodInvocation invocation = ParserTestCase.parse5("parseExpressionWithoutCascade", "super.m()", []); + MethodInvocation invocation = ParserTestCase.parse4("parseExpressionWithoutCascade", "super.m()", []); JUnitTestCase.assertNotNull(invocation.target); JUnitTestCase.assertNotNull(invocation.methodName); JUnitTestCase.assertNotNull(invocation.argumentList); } void test_parseExtendsClause() { - ExtendsClause clause = ParserTestCase.parse5("parseExtendsClause", "extends B", []); + ExtendsClause clause = ParserTestCase.parse4("parseExtendsClause", "extends B", []); JUnitTestCase.assertNotNull(clause.keyword); JUnitTestCase.assertNotNull(clause.superclass); EngineTestCase.assertInstanceOf(TypeName, clause.superclass); @@ -2227,7 +2259,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_empty() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "()", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "()", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNull(parameterList.leftDelimiter); EngineTestCase.assertSize(0, parameterList.parameters); @@ -2236,7 +2268,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_named_multiple() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "({A a : 1, B b, C c : 3})", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "({A a : 1, B b, C c : 3})", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNotNull(parameterList.leftDelimiter); EngineTestCase.assertSize(3, parameterList.parameters); @@ -2245,7 +2277,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_named_single() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "({A a})", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "({A a})", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNotNull(parameterList.leftDelimiter); EngineTestCase.assertSize(1, parameterList.parameters); @@ -2254,7 +2286,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_normal_multiple() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, B b, C c)", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, B b, C c)", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNull(parameterList.leftDelimiter); EngineTestCase.assertSize(3, parameterList.parameters); @@ -2263,7 +2295,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_normal_named() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, {B b})", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, {B b})", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNotNull(parameterList.leftDelimiter); EngineTestCase.assertSize(2, parameterList.parameters); @@ -2272,7 +2304,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_normal_positional() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, [B b])", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, [B b])", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNotNull(parameterList.leftDelimiter); EngineTestCase.assertSize(2, parameterList.parameters); @@ -2281,7 +2313,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_normal_single() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a)", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a)", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNull(parameterList.leftDelimiter); EngineTestCase.assertSize(1, parameterList.parameters); @@ -2290,7 +2322,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_positional_multiple() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "([A a = null, B b, C c = null])", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "([A a = null, B b, C c = null])", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNotNull(parameterList.leftDelimiter); EngineTestCase.assertSize(3, parameterList.parameters); @@ -2299,7 +2331,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFormalParameterList_positional_single() { - FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "([A a = null])", []); + FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "([A a = null])", []); JUnitTestCase.assertNotNull(parameterList.leftParenthesis); JUnitTestCase.assertNotNull(parameterList.leftDelimiter); EngineTestCase.assertSize(1, parameterList.parameters); @@ -2308,7 +2340,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_each_identifier() { - ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (element in list) {}", []); + ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (element in list) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNull(statement.loopVariable); @@ -2320,7 +2352,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_each_noType_metadata() { - ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (@A var element in list) {}", []); + ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (@A var element in list) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.loopVariable); @@ -2333,7 +2365,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_each_type() { - ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (A element in list) {}", []); + ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (A element in list) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.loopVariable); @@ -2345,7 +2377,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_each_var() { - ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (var element in list) {}", []); + ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (var element in list) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.loopVariable); @@ -2357,7 +2389,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_c() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (; i < count;) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (; i < count;) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNull(statement.variables); @@ -2371,7 +2403,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_cu() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (; i < count; i++) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (; i < count; i++) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNull(statement.variables); @@ -2385,7 +2417,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_ecu() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (i--; i < count; i++) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (i--; i < count; i++) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNull(statement.variables); @@ -2399,7 +2431,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_i() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0;;) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (var i = 0;;) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); VariableDeclarationList variables = statement.variables; @@ -2416,7 +2448,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_i_withMetadata() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (@A var i = 0;;) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (@A var i = 0;;) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); VariableDeclarationList variables = statement.variables; @@ -2433,7 +2465,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_ic() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0; i < count;) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (var i = 0; i < count;) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); VariableDeclarationList variables = statement.variables; @@ -2449,7 +2481,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_icu() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0; i < count; i++) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (var i = 0; i < count; i++) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); VariableDeclarationList variables = statement.variables; @@ -2465,7 +2497,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_iicuu() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (int i = 0, j = count; i < j; i++, j--) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (int i = 0, j = count; i < j; i++, j--) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); VariableDeclarationList variables = statement.variables; @@ -2481,7 +2513,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_iu() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0;; i++) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (var i = 0;; i++) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); VariableDeclarationList variables = statement.variables; @@ -2497,7 +2529,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseForStatement_loop_u() { - ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (;; i++) {}", []); + ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (;; i++) {}", []); JUnitTestCase.assertNotNull(statement.forKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNull(statement.variables); @@ -2595,19 +2627,19 @@ class SimpleParserTest extends ParserTestCase { } void test_parseFunctionDeclarationStatement() { - FunctionDeclarationStatement statement = ParserTestCase.parse5("parseFunctionDeclarationStatement", "void f(int p) => p * 2;", []); + FunctionDeclarationStatement statement = ParserTestCase.parse4("parseFunctionDeclarationStatement", "void f(int p) => p * 2;", []); JUnitTestCase.assertNotNull(statement.functionDeclaration); } void test_parseFunctionExpression_body_inExpression() { - FunctionExpression expression = ParserTestCase.parse5("parseFunctionExpression", "(int i) => i++", []); + FunctionExpression expression = ParserTestCase.parse4("parseFunctionExpression", "(int i) => i++", []); JUnitTestCase.assertNotNull(expression.body); JUnitTestCase.assertNotNull(expression.parameters); JUnitTestCase.assertNull((expression.body as ExpressionFunctionBody).semicolon); } void test_parseFunctionExpression_minimal() { - FunctionExpression expression = ParserTestCase.parse5("parseFunctionExpression", "() {}", []); + FunctionExpression expression = ParserTestCase.parse4("parseFunctionExpression", "() {}", []); JUnitTestCase.assertNotNull(expression.body); JUnitTestCase.assertNotNull(expression.parameters); } @@ -2648,17 +2680,17 @@ class SimpleParserTest extends ParserTestCase { } void test_parseIdentifierList_multiple() { - List list = ParserTestCase.parse5("parseIdentifierList", "a, b, c", []); + List list = ParserTestCase.parse4("parseIdentifierList", "a, b, c", []); EngineTestCase.assertSize(3, list); } void test_parseIdentifierList_single() { - List list = ParserTestCase.parse5("parseIdentifierList", "a", []); + List list = ParserTestCase.parse4("parseIdentifierList", "a", []); EngineTestCase.assertSize(1, list); } void test_parseIfStatement_else_block() { - IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) {} else {}", []); + IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) {} else {}", []); JUnitTestCase.assertNotNull(statement.ifKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.condition); @@ -2669,7 +2701,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseIfStatement_else_statement() { - IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) f(x); else f(y);", []); + IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) f(x); else f(y);", []); JUnitTestCase.assertNotNull(statement.ifKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.condition); @@ -2680,7 +2712,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseIfStatement_noElse_block() { - IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) {}", []); + IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) {}", []); JUnitTestCase.assertNotNull(statement.ifKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.condition); @@ -2691,7 +2723,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseIfStatement_noElse_statement() { - IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) f(x);", []); + IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) f(x);", []); JUnitTestCase.assertNotNull(statement.ifKeyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.condition); @@ -2702,13 +2734,13 @@ class SimpleParserTest extends ParserTestCase { } void test_parseImplementsClause_multiple() { - ImplementsClause clause = ParserTestCase.parse5("parseImplementsClause", "implements A, B, C", []); + ImplementsClause clause = ParserTestCase.parse4("parseImplementsClause", "implements A, B, C", []); EngineTestCase.assertSize(3, clause.interfaces); JUnitTestCase.assertNotNull(clause.keyword); } void test_parseImplementsClause_single() { - ImplementsClause clause = ParserTestCase.parse5("parseImplementsClause", "implements A", []); + ImplementsClause clause = ParserTestCase.parse4("parseImplementsClause", "implements A", []); EngineTestCase.assertSize(1, clause.interfaces); JUnitTestCase.assertNotNull(clause.keyword); } @@ -2868,13 +2900,13 @@ class SimpleParserTest extends ParserTestCase { void test_parseLibraryIdentifier_multiple() { String name = "a.b.c"; - LibraryIdentifier identifier = ParserTestCase.parse5("parseLibraryIdentifier", name, []); + LibraryIdentifier identifier = ParserTestCase.parse4("parseLibraryIdentifier", name, []); JUnitTestCase.assertEquals(name, identifier.name); } void test_parseLibraryIdentifier_single() { String name = "a"; - LibraryIdentifier identifier = ParserTestCase.parse5("parseLibraryIdentifier", name, []); + LibraryIdentifier identifier = ParserTestCase.parse4("parseLibraryIdentifier", name, []); JUnitTestCase.assertEquals(name, identifier.name); } @@ -2955,7 +2987,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseLogicalAndExpression() { - BinaryExpression expression = ParserTestCase.parse5("parseLogicalAndExpression", "x && y", []); + BinaryExpression expression = ParserTestCase.parse4("parseLogicalAndExpression", "x && y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.AMPERSAND_AMPERSAND, expression.operator.type); @@ -2963,7 +2995,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseLogicalOrExpression() { - BinaryExpression expression = ParserTestCase.parse5("parseLogicalOrExpression", "x || y", []); + BinaryExpression expression = ParserTestCase.parse4("parseLogicalOrExpression", "x || y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.BAR_BAR, expression.operator.type); @@ -2998,63 +3030,63 @@ class SimpleParserTest extends ParserTestCase { } void test_parseMapLiteralEntry_complex() { - MapLiteralEntry entry = ParserTestCase.parse5("parseMapLiteralEntry", "2 + 2 : y", []); + MapLiteralEntry entry = ParserTestCase.parse4("parseMapLiteralEntry", "2 + 2 : y", []); JUnitTestCase.assertNotNull(entry.key); JUnitTestCase.assertNotNull(entry.separator); JUnitTestCase.assertNotNull(entry.value); } void test_parseMapLiteralEntry_int() { - MapLiteralEntry entry = ParserTestCase.parse5("parseMapLiteralEntry", "0 : y", []); + MapLiteralEntry entry = ParserTestCase.parse4("parseMapLiteralEntry", "0 : y", []); JUnitTestCase.assertNotNull(entry.key); JUnitTestCase.assertNotNull(entry.separator); JUnitTestCase.assertNotNull(entry.value); } void test_parseMapLiteralEntry_string() { - MapLiteralEntry entry = ParserTestCase.parse5("parseMapLiteralEntry", "'x' : y", []); + MapLiteralEntry entry = ParserTestCase.parse4("parseMapLiteralEntry", "'x' : y", []); JUnitTestCase.assertNotNull(entry.key); JUnitTestCase.assertNotNull(entry.separator); JUnitTestCase.assertNotNull(entry.value); } void test_parseModifiers_abstract() { - Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "abstract A", []); + Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "abstract A", []); JUnitTestCase.assertNotNull(modifiers.abstractKeyword); } void test_parseModifiers_const() { - Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "const A", []); + Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "const A", []); JUnitTestCase.assertNotNull(modifiers.constKeyword); } void test_parseModifiers_external() { - Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "external A", []); + Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "external A", []); JUnitTestCase.assertNotNull(modifiers.externalKeyword); } void test_parseModifiers_factory() { - Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "factory A", []); + Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "factory A", []); JUnitTestCase.assertNotNull(modifiers.factoryKeyword); } void test_parseModifiers_final() { - Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "final A", []); + Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "final A", []); JUnitTestCase.assertNotNull(modifiers.finalKeyword); } void test_parseModifiers_static() { - Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "static A", []); + Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "static A", []); JUnitTestCase.assertNotNull(modifiers.staticKeyword); } void test_parseModifiers_var() { - Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "var A", []); + Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "var A", []); JUnitTestCase.assertNotNull(modifiers.varKeyword); } void test_parseMultiplicativeExpression_normal() { - BinaryExpression expression = ParserTestCase.parse5("parseMultiplicativeExpression", "x * y", []); + BinaryExpression expression = ParserTestCase.parse4("parseMultiplicativeExpression", "x * y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.STAR, expression.operator.type); @@ -3062,7 +3094,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseMultiplicativeExpression_super() { - BinaryExpression expression = ParserTestCase.parse5("parseMultiplicativeExpression", "super * y", []); + BinaryExpression expression = ParserTestCase.parse4("parseMultiplicativeExpression", "super * y", []); EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.STAR, expression.operator.type); @@ -3070,7 +3102,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNewExpression() { - InstanceCreationExpression expression = ParserTestCase.parse5("parseNewExpression", "new A()", []); + InstanceCreationExpression expression = ParserTestCase.parse4("parseNewExpression", "new A()", []); JUnitTestCase.assertNotNull(expression.keyword); ConstructorName name = expression.constructorName; JUnitTestCase.assertNotNull(name); @@ -3081,65 +3113,65 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNonLabeledStatement_const_list_empty() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const [];", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const [];", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_const_list_nonEmpty() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const [1, 2];", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const [1, 2];", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_const_map_empty() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const {};", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const {};", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_const_map_nonEmpty() { // TODO(brianwilkerson) Implement more tests for this method. - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const {'a' : 1};", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const {'a' : 1};", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_const_object() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const A();", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const A();", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_const_object_named_typeParameters() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const A.c();", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const A.c();", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_constructorInvocation() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "new C().m();", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "new C().m();", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_false() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "false;", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "false;", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_functionDeclaration() { - ParserTestCase.parse5("parseNonLabeledStatement", "f() {};", []); + ParserTestCase.parse4("parseNonLabeledStatement", "f() {};", []); } void test_parseNonLabeledStatement_functionDeclaration_arguments() { - ParserTestCase.parse5("parseNonLabeledStatement", "f(void g()) {};", []); + ParserTestCase.parse4("parseNonLabeledStatement", "f(void g()) {};", []); } void test_parseNonLabeledStatement_functionExpressionIndex() { - ParserTestCase.parse5("parseNonLabeledStatement", "() {}[0] = null;", []); + ParserTestCase.parse4("parseNonLabeledStatement", "() {}[0] = null;", []); } void test_parseNonLabeledStatement_functionInvocation() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "f();", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "f();", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_invokeFunctionExpression() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "(a) {return a + a;} (3);", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "(a) {return a + a;} (3);", []); EngineTestCase.assertInstanceOf(FunctionExpressionInvocation, statement.expression); FunctionExpressionInvocation invocation = statement.expression as FunctionExpressionInvocation; EngineTestCase.assertInstanceOf(FunctionExpression, invocation.function); @@ -3152,27 +3184,27 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNonLabeledStatement_null() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "null;", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "null;", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_startingWithBuiltInIdentifier() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "library.getName();", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "library.getName();", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_true() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "true;", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "true;", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNonLabeledStatement_typeCast() { - ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "double.NAN as num;", []); + ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "double.NAN as num;", []); JUnitTestCase.assertNotNull(statement.expression); } void test_parseNormalFormalParameter_field_const_noType() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const this.a)", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "const this.a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3180,7 +3212,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_field_const_type() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const A this.a)", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "const A this.a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNotNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3188,7 +3220,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_field_final_noType() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final this.a)", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "final this.a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3196,7 +3228,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_field_final_type() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final A this.a)", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "final A this.a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNotNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3204,7 +3236,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_field_function_nested() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "this.a(B b))", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "this.a(B b))", []); JUnitTestCase.assertNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3214,7 +3246,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_field_function_noNested() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "this.a())", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "this.a())", []); JUnitTestCase.assertNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3224,7 +3256,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_field_noType() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "this.a)", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "this.a)", []); JUnitTestCase.assertNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3232,7 +3264,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_field_type() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A this.a)", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "A this.a)", []); JUnitTestCase.assertNull(parameter.keyword); JUnitTestCase.assertNotNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3240,7 +3272,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_field_var() { - FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "var this.a)", []); + FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "var this.a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3248,63 +3280,63 @@ class SimpleParserTest extends ParserTestCase { } void test_parseNormalFormalParameter_function_noType() { - FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "a())", []); + FunctionTypedFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "a())", []); JUnitTestCase.assertNull(parameter.returnType); JUnitTestCase.assertNotNull(parameter.identifier); JUnitTestCase.assertNotNull(parameter.parameters); } void test_parseNormalFormalParameter_function_type() { - FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A a())", []); + FunctionTypedFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "A a())", []); JUnitTestCase.assertNotNull(parameter.returnType); JUnitTestCase.assertNotNull(parameter.identifier); JUnitTestCase.assertNotNull(parameter.parameters); } void test_parseNormalFormalParameter_function_void() { - FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "void a())", []); + FunctionTypedFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "void a())", []); JUnitTestCase.assertNotNull(parameter.returnType); JUnitTestCase.assertNotNull(parameter.identifier); JUnitTestCase.assertNotNull(parameter.parameters); } void test_parseNormalFormalParameter_simple_const_noType() { - SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const a)", []); + SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "const a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); } void test_parseNormalFormalParameter_simple_const_type() { - SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const A a)", []); + SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "const A a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNotNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); } void test_parseNormalFormalParameter_simple_final_noType() { - SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final a)", []); + SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "final a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); } void test_parseNormalFormalParameter_simple_final_type() { - SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final A a)", []); + SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "final A a)", []); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNotNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); } void test_parseNormalFormalParameter_simple_noType() { - SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "a)", []); + SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "a)", []); JUnitTestCase.assertNull(parameter.keyword); JUnitTestCase.assertNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); } void test_parseNormalFormalParameter_simple_type() { - SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A a)", []); + SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "A a)", []); JUnitTestCase.assertNull(parameter.keyword); JUnitTestCase.assertNotNull(parameter.type); JUnitTestCase.assertNotNull(parameter.identifier); @@ -3344,167 +3376,167 @@ class SimpleParserTest extends ParserTestCase { } void test_parsePostfixExpression_decrement() { - PostfixExpression expression = ParserTestCase.parse5("parsePostfixExpression", "i--", []); + PostfixExpression expression = ParserTestCase.parse4("parsePostfixExpression", "i--", []); JUnitTestCase.assertNotNull(expression.operand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.MINUS_MINUS, expression.operator.type); } void test_parsePostfixExpression_increment() { - PostfixExpression expression = ParserTestCase.parse5("parsePostfixExpression", "i++", []); + PostfixExpression expression = ParserTestCase.parse4("parsePostfixExpression", "i++", []); JUnitTestCase.assertNotNull(expression.operand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.PLUS_PLUS, expression.operator.type); } void test_parsePostfixExpression_none_indexExpression() { - IndexExpression expression = ParserTestCase.parse5("parsePostfixExpression", "a[0]", []); + IndexExpression expression = ParserTestCase.parse4("parsePostfixExpression", "a[0]", []); JUnitTestCase.assertNotNull(expression.target); JUnitTestCase.assertNotNull(expression.index); } void test_parsePostfixExpression_none_methodInvocation() { - MethodInvocation expression = ParserTestCase.parse5("parsePostfixExpression", "a.m()", []); + MethodInvocation expression = ParserTestCase.parse4("parsePostfixExpression", "a.m()", []); JUnitTestCase.assertNotNull(expression.target); JUnitTestCase.assertNotNull(expression.methodName); JUnitTestCase.assertNotNull(expression.argumentList); } void test_parsePostfixExpression_none_propertyAccess() { - PrefixedIdentifier expression = ParserTestCase.parse5("parsePostfixExpression", "a.b", []); + PrefixedIdentifier expression = ParserTestCase.parse4("parsePostfixExpression", "a.b", []); JUnitTestCase.assertNotNull(expression.prefix); JUnitTestCase.assertNotNull(expression.identifier); } void test_parsePrefixedIdentifier_noPrefix() { String lexeme = "bar"; - SimpleIdentifier identifier = ParserTestCase.parse5("parsePrefixedIdentifier", lexeme, []); + SimpleIdentifier identifier = ParserTestCase.parse4("parsePrefixedIdentifier", lexeme, []); JUnitTestCase.assertNotNull(identifier.token); JUnitTestCase.assertEquals(lexeme, identifier.name); } void test_parsePrefixedIdentifier_prefix() { String lexeme = "foo.bar"; - PrefixedIdentifier identifier = ParserTestCase.parse5("parsePrefixedIdentifier", lexeme, []); + PrefixedIdentifier identifier = ParserTestCase.parse4("parsePrefixedIdentifier", lexeme, []); JUnitTestCase.assertEquals("foo", identifier.prefix.name); JUnitTestCase.assertNotNull(identifier.period); JUnitTestCase.assertEquals("bar", identifier.identifier.name); } void test_parsePrimaryExpression_const() { - InstanceCreationExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "const A()", []); + InstanceCreationExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "const A()", []); JUnitTestCase.assertNotNull(expression); } void test_parsePrimaryExpression_double() { String doubleLiteral = "3.2e4"; - DoubleLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", doubleLiteral, []); + DoubleLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", doubleLiteral, []); JUnitTestCase.assertNotNull(literal.literal); JUnitTestCase.assertEquals(double.parse(doubleLiteral), literal.value); } void test_parsePrimaryExpression_false() { - BooleanLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "false", []); + BooleanLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "false", []); JUnitTestCase.assertNotNull(literal.literal); JUnitTestCase.assertFalse(literal.value); } void test_parsePrimaryExpression_function_arguments() { - FunctionExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "(int i) => i + 1", []); + FunctionExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "(int i) => i + 1", []); JUnitTestCase.assertNotNull(expression.parameters); JUnitTestCase.assertNotNull(expression.body); } void test_parsePrimaryExpression_function_noArguments() { - FunctionExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "() => 42", []); + FunctionExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "() => 42", []); JUnitTestCase.assertNotNull(expression.parameters); JUnitTestCase.assertNotNull(expression.body); } void test_parsePrimaryExpression_hex() { String hexLiteral = "3F"; - IntegerLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "0x${hexLiteral}", []); + IntegerLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "0x${hexLiteral}", []); JUnitTestCase.assertNotNull(literal.literal); JUnitTestCase.assertEquals(int.parse(hexLiteral, radix: 16), literal.value); } void test_parsePrimaryExpression_identifier() { - SimpleIdentifier identifier = ParserTestCase.parse5("parsePrimaryExpression", "a", []); + SimpleIdentifier identifier = ParserTestCase.parse4("parsePrimaryExpression", "a", []); JUnitTestCase.assertNotNull(identifier); } void test_parsePrimaryExpression_int() { String intLiteral = "472"; - IntegerLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", intLiteral, []); + IntegerLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", intLiteral, []); JUnitTestCase.assertNotNull(literal.literal); JUnitTestCase.assertEquals(int.parse(intLiteral), literal.value); } void test_parsePrimaryExpression_listLiteral() { - ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "[ ]", []); + ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "[ ]", []); JUnitTestCase.assertNotNull(literal); } void test_parsePrimaryExpression_listLiteral_index() { - ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "[]", []); + ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "[]", []); JUnitTestCase.assertNotNull(literal); } void test_parsePrimaryExpression_listLiteral_typed() { - ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "[ ]", []); + ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "[ ]", []); JUnitTestCase.assertNotNull(literal.typeArguments); EngineTestCase.assertSize(1, literal.typeArguments.arguments); } void test_parsePrimaryExpression_mapLiteral() { - MapLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "{}", []); + MapLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "{}", []); JUnitTestCase.assertNotNull(literal); } void test_parsePrimaryExpression_mapLiteral_typed() { - MapLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "{}", []); + MapLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "{}", []); JUnitTestCase.assertNotNull(literal.typeArguments); EngineTestCase.assertSize(2, literal.typeArguments.arguments); } void test_parsePrimaryExpression_new() { - InstanceCreationExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "new A()", []); + InstanceCreationExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "new A()", []); JUnitTestCase.assertNotNull(expression); } void test_parsePrimaryExpression_null() { - NullLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "null", []); + NullLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "null", []); JUnitTestCase.assertNotNull(literal.literal); } void test_parsePrimaryExpression_parenthesized() { - ParenthesizedExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "(x)", []); + ParenthesizedExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "(x)", []); JUnitTestCase.assertNotNull(expression); } void test_parsePrimaryExpression_string() { - SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "\"string\"", []); + SimpleStringLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "\"string\"", []); JUnitTestCase.assertFalse(literal.isMultiline); JUnitTestCase.assertFalse(literal.isRaw); JUnitTestCase.assertEquals("string", literal.value); } void test_parsePrimaryExpression_string_multiline() { - SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "'''string'''", []); + SimpleStringLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "'''string'''", []); JUnitTestCase.assertTrue(literal.isMultiline); JUnitTestCase.assertFalse(literal.isRaw); JUnitTestCase.assertEquals("string", literal.value); } void test_parsePrimaryExpression_string_raw() { - SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "r'string'", []); + SimpleStringLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "r'string'", []); JUnitTestCase.assertFalse(literal.isMultiline); JUnitTestCase.assertTrue(literal.isRaw); JUnitTestCase.assertEquals("string", literal.value); } void test_parsePrimaryExpression_super() { - PropertyAccess propertyAccess = ParserTestCase.parse5("parsePrimaryExpression", "super.x", []); + PropertyAccess propertyAccess = ParserTestCase.parse4("parsePrimaryExpression", "super.x", []); JUnitTestCase.assertTrue(propertyAccess.target is SuperExpression); JUnitTestCase.assertNotNull(propertyAccess.operator); JUnitTestCase.assertEquals(TokenType.PERIOD, propertyAccess.operator.type); @@ -3512,12 +3544,12 @@ class SimpleParserTest extends ParserTestCase { } void test_parsePrimaryExpression_this() { - ThisExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "this", []); + ThisExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "this", []); JUnitTestCase.assertNotNull(expression.keyword); } void test_parsePrimaryExpression_true() { - BooleanLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "true", []); + BooleanLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "true", []); JUnitTestCase.assertNotNull(literal.literal); JUnitTestCase.assertTrue(literal.value); } @@ -3527,7 +3559,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseRedirectingConstructorInvocation_named() { - RedirectingConstructorInvocation invocation = ParserTestCase.parse5("parseRedirectingConstructorInvocation", "this.a()", []); + RedirectingConstructorInvocation invocation = ParserTestCase.parse4("parseRedirectingConstructorInvocation", "this.a()", []); JUnitTestCase.assertNotNull(invocation.argumentList); JUnitTestCase.assertNotNull(invocation.constructorName); JUnitTestCase.assertNotNull(invocation.keyword); @@ -3535,7 +3567,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseRedirectingConstructorInvocation_unnamed() { - RedirectingConstructorInvocation invocation = ParserTestCase.parse5("parseRedirectingConstructorInvocation", "this()", []); + RedirectingConstructorInvocation invocation = ParserTestCase.parse4("parseRedirectingConstructorInvocation", "this()", []); JUnitTestCase.assertNotNull(invocation.argumentList); JUnitTestCase.assertNull(invocation.constructorName); JUnitTestCase.assertNotNull(invocation.keyword); @@ -3543,14 +3575,14 @@ class SimpleParserTest extends ParserTestCase { } void test_parseRelationalExpression_as() { - AsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x as Y", []); + AsExpression expression = ParserTestCase.parse4("parseRelationalExpression", "x as Y", []); JUnitTestCase.assertNotNull(expression.expression); JUnitTestCase.assertNotNull(expression.asOperator); JUnitTestCase.assertNotNull(expression.type); } void test_parseRelationalExpression_is() { - IsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x is y", []); + IsExpression expression = ParserTestCase.parse4("parseRelationalExpression", "x is y", []); JUnitTestCase.assertNotNull(expression.expression); JUnitTestCase.assertNotNull(expression.isOperator); JUnitTestCase.assertNull(expression.notOperator); @@ -3558,7 +3590,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseRelationalExpression_isNot() { - IsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x is! y", []); + IsExpression expression = ParserTestCase.parse4("parseRelationalExpression", "x is! y", []); JUnitTestCase.assertNotNull(expression.expression); JUnitTestCase.assertNotNull(expression.isOperator); JUnitTestCase.assertNotNull(expression.notOperator); @@ -3566,7 +3598,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseRelationalExpression_normal() { - BinaryExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x < y", []); + BinaryExpression expression = ParserTestCase.parse4("parseRelationalExpression", "x < y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.LT, expression.operator.type); @@ -3574,7 +3606,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseRelationalExpression_super() { - BinaryExpression expression = ParserTestCase.parse5("parseRelationalExpression", "super < y", []); + BinaryExpression expression = ParserTestCase.parse4("parseRelationalExpression", "super < y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.LT, expression.operator.type); @@ -3582,32 +3614,32 @@ class SimpleParserTest extends ParserTestCase { } void test_parseRethrowExpression() { - RethrowExpression expression = ParserTestCase.parse5("parseRethrowExpression", "rethrow;", []); + RethrowExpression expression = ParserTestCase.parse4("parseRethrowExpression", "rethrow;", []); JUnitTestCase.assertNotNull(expression.keyword); } void test_parseReturnStatement_noValue() { - ReturnStatement statement = ParserTestCase.parse5("parseReturnStatement", "return;", []); + ReturnStatement statement = ParserTestCase.parse4("parseReturnStatement", "return;", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNull(statement.expression); JUnitTestCase.assertNotNull(statement.semicolon); } void test_parseReturnStatement_value() { - ReturnStatement statement = ParserTestCase.parse5("parseReturnStatement", "return x;", []); + ReturnStatement statement = ParserTestCase.parse4("parseReturnStatement", "return x;", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.expression); JUnitTestCase.assertNotNull(statement.semicolon); } void test_parseReturnType_nonVoid() { - TypeName typeName = ParserTestCase.parse5("parseReturnType", "A", []); + TypeName typeName = ParserTestCase.parse4("parseReturnType", "A", []); JUnitTestCase.assertNotNull(typeName.name); JUnitTestCase.assertNotNull(typeName.typeArguments); } void test_parseReturnType_void() { - TypeName typeName = ParserTestCase.parse5("parseReturnType", "void", []); + TypeName typeName = ParserTestCase.parse4("parseReturnType", "void", []); JUnitTestCase.assertNotNull(typeName.name); JUnitTestCase.assertNull(typeName.typeArguments); } @@ -3648,7 +3680,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseShiftExpression_normal() { - BinaryExpression expression = ParserTestCase.parse5("parseShiftExpression", "x << y", []); + BinaryExpression expression = ParserTestCase.parse4("parseShiftExpression", "x << y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.LT_LT, expression.operator.type); @@ -3656,7 +3688,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseShiftExpression_super() { - BinaryExpression expression = ParserTestCase.parse5("parseShiftExpression", "super << y", []); + BinaryExpression expression = ParserTestCase.parse4("parseShiftExpression", "super << y", []); JUnitTestCase.assertNotNull(expression.leftOperand); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.LT_LT, expression.operator.type); @@ -3665,14 +3697,14 @@ class SimpleParserTest extends ParserTestCase { void test_parseSimpleIdentifier_builtInIdentifier() { String lexeme = "as"; - SimpleIdentifier identifier = ParserTestCase.parse5("parseSimpleIdentifier", lexeme, []); + SimpleIdentifier identifier = ParserTestCase.parse4("parseSimpleIdentifier", lexeme, []); JUnitTestCase.assertNotNull(identifier.token); JUnitTestCase.assertEquals(lexeme, identifier.name); } void test_parseSimpleIdentifier_normalIdentifier() { String lexeme = "foo"; - SimpleIdentifier identifier = ParserTestCase.parse5("parseSimpleIdentifier", lexeme, []); + SimpleIdentifier identifier = ParserTestCase.parse4("parseSimpleIdentifier", lexeme, []); JUnitTestCase.assertNotNull(identifier.token); JUnitTestCase.assertEquals(lexeme, identifier.name); } @@ -3682,22 +3714,22 @@ class SimpleParserTest extends ParserTestCase { void test_parseStatement_functionDeclaration() { // TODO(brianwilkerson) Implement more tests for this method. - FunctionDeclarationStatement statement = ParserTestCase.parse5("parseStatement", "int f(a, b) {};", []); + FunctionDeclarationStatement statement = ParserTestCase.parse4("parseStatement", "int f(a, b) {};", []); JUnitTestCase.assertNotNull(statement.functionDeclaration); } void test_parseStatement_mulipleLabels() { - LabeledStatement statement = ParserTestCase.parse5("parseStatement", "l: m: return x;", []); + LabeledStatement statement = ParserTestCase.parse4("parseStatement", "l: m: return x;", []); EngineTestCase.assertSize(2, statement.labels); JUnitTestCase.assertNotNull(statement.statement); } void test_parseStatement_noLabels() { - ParserTestCase.parse5("parseStatement", "return x;", []); + ParserTestCase.parse4("parseStatement", "return x;", []); } void test_parseStatement_singleLabel() { - LabeledStatement statement = ParserTestCase.parse5("parseStatement", "l: return x;", []); + LabeledStatement statement = ParserTestCase.parse4("parseStatement", "l: return x;", []); EngineTestCase.assertSize(1, statement.labels); JUnitTestCase.assertNotNull(statement.statement); } @@ -3713,7 +3745,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseStringLiteral_adjacent() { - AdjacentStrings literal = ParserTestCase.parse5("parseStringLiteral", "'a' 'b'", []); + AdjacentStrings literal = ParserTestCase.parse4("parseStringLiteral", "'a' 'b'", []); NodeList strings = literal.strings; EngineTestCase.assertSize(2, strings); StringLiteral firstString = strings[0]; @@ -3723,7 +3755,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseStringLiteral_interpolated() { - StringInterpolation literal = ParserTestCase.parse5("parseStringLiteral", "'a \${b} c \$this d'", []); + StringInterpolation literal = ParserTestCase.parse4("parseStringLiteral", "'a \${b} c \$this d'", []); NodeList elements = literal.elements; EngineTestCase.assertSize(5, elements); JUnitTestCase.assertTrue(elements[0] is InterpolationString); @@ -3734,13 +3766,13 @@ class SimpleParserTest extends ParserTestCase { } void test_parseStringLiteral_single() { - SimpleStringLiteral literal = ParserTestCase.parse5("parseStringLiteral", "'a'", []); + SimpleStringLiteral literal = ParserTestCase.parse4("parseStringLiteral", "'a'", []); JUnitTestCase.assertNotNull(literal.literal); JUnitTestCase.assertEquals("a", literal.value); } void test_parseSuperConstructorInvocation_named() { - SuperConstructorInvocation invocation = ParserTestCase.parse5("parseSuperConstructorInvocation", "super.a()", []); + SuperConstructorInvocation invocation = ParserTestCase.parse4("parseSuperConstructorInvocation", "super.a()", []); JUnitTestCase.assertNotNull(invocation.argumentList); JUnitTestCase.assertNotNull(invocation.constructorName); JUnitTestCase.assertNotNull(invocation.keyword); @@ -3748,7 +3780,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSuperConstructorInvocation_unnamed() { - SuperConstructorInvocation invocation = ParserTestCase.parse5("parseSuperConstructorInvocation", "super()", []); + SuperConstructorInvocation invocation = ParserTestCase.parse4("parseSuperConstructorInvocation", "super()", []); JUnitTestCase.assertNotNull(invocation.argumentList); JUnitTestCase.assertNull(invocation.constructorName); JUnitTestCase.assertNotNull(invocation.keyword); @@ -3756,7 +3788,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSwitchStatement_case() { - SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {case 1: return 'I';}", []); + SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {case 1: return 'I';}", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.expression); @@ -3767,7 +3799,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSwitchStatement_empty() { - SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {}", []); + SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {}", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.expression); @@ -3778,7 +3810,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSwitchStatement_labeledCase() { - SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}", []); + SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.expression); @@ -3790,7 +3822,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSwitchStatement_labeledStatementInCase() { - SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {case 0: f(); l1: g(); break;}", []); + SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {case 0: f(); l1: g(); break;}", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.expression); @@ -3802,7 +3834,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSymbolLiteral_builtInIdentifier() { - SymbolLiteral literal = ParserTestCase.parse5("parseSymbolLiteral", "#dynamic.static.abstract", []); + SymbolLiteral literal = ParserTestCase.parse4("parseSymbolLiteral", "#dynamic.static.abstract", []); JUnitTestCase.assertNotNull(literal.poundSign); List components = literal.components; EngineTestCase.assertLength(3, components); @@ -3812,7 +3844,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSymbolLiteral_multiple() { - SymbolLiteral literal = ParserTestCase.parse5("parseSymbolLiteral", "#a.b.c", []); + SymbolLiteral literal = ParserTestCase.parse4("parseSymbolLiteral", "#a.b.c", []); JUnitTestCase.assertNotNull(literal.poundSign); List components = literal.components; EngineTestCase.assertLength(3, components); @@ -3822,7 +3854,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSymbolLiteral_operator() { - SymbolLiteral literal = ParserTestCase.parse5("parseSymbolLiteral", "#==", []); + SymbolLiteral literal = ParserTestCase.parse4("parseSymbolLiteral", "#==", []); JUnitTestCase.assertNotNull(literal.poundSign); List components = literal.components; EngineTestCase.assertLength(1, components); @@ -3830,7 +3862,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseSymbolLiteral_single() { - SymbolLiteral literal = ParserTestCase.parse5("parseSymbolLiteral", "#a", []); + SymbolLiteral literal = ParserTestCase.parse4("parseSymbolLiteral", "#a", []); JUnitTestCase.assertNotNull(literal.poundSign); List components = literal.components; EngineTestCase.assertLength(1, components); @@ -3838,19 +3870,19 @@ class SimpleParserTest extends ParserTestCase { } void test_parseThrowExpression() { - ThrowExpression expression = ParserTestCase.parse5("parseThrowExpression", "throw x;", []); + ThrowExpression expression = ParserTestCase.parse4("parseThrowExpression", "throw x;", []); JUnitTestCase.assertNotNull(expression.keyword); JUnitTestCase.assertNotNull(expression.expression); } void test_parseThrowExpressionWithoutCascade() { - ThrowExpression expression = ParserTestCase.parse5("parseThrowExpressionWithoutCascade", "throw x;", []); + ThrowExpression expression = ParserTestCase.parse4("parseThrowExpressionWithoutCascade", "throw x;", []); JUnitTestCase.assertNotNull(expression.keyword); JUnitTestCase.assertNotNull(expression.expression); } void test_parseTryStatement_catch() { - TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} catch (e) {}", []); + TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} catch (e) {}", []); JUnitTestCase.assertNotNull(statement.tryKeyword); JUnitTestCase.assertNotNull(statement.body); NodeList catchClauses = statement.catchClauses; @@ -3868,7 +3900,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseTryStatement_catch_finally() { - TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} catch (e, s) {} finally {}", []); + TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} catch (e, s) {} finally {}", []); JUnitTestCase.assertNotNull(statement.tryKeyword); JUnitTestCase.assertNotNull(statement.body); NodeList catchClauses = statement.catchClauses; @@ -3886,7 +3918,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseTryStatement_finally() { - TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} finally {}", []); + TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} finally {}", []); JUnitTestCase.assertNotNull(statement.tryKeyword); JUnitTestCase.assertNotNull(statement.body); EngineTestCase.assertSize(0, statement.catchClauses); @@ -3895,7 +3927,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseTryStatement_multiple() { - TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on NPE catch (e) {} on Error {} catch (e) {}", []); + TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on NPE catch (e) {} on Error {} catch (e) {}", []); JUnitTestCase.assertNotNull(statement.tryKeyword); JUnitTestCase.assertNotNull(statement.body); EngineTestCase.assertSize(3, statement.catchClauses); @@ -3904,7 +3936,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseTryStatement_on() { - TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error {}", []); + TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error {}", []); JUnitTestCase.assertNotNull(statement.tryKeyword); JUnitTestCase.assertNotNull(statement.body); NodeList catchClauses = statement.catchClauses; @@ -3922,7 +3954,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseTryStatement_on_catch() { - TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error catch (e, s) {}", []); + TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error catch (e, s) {}", []); JUnitTestCase.assertNotNull(statement.tryKeyword); JUnitTestCase.assertNotNull(statement.body); NodeList catchClauses = statement.catchClauses; @@ -3940,7 +3972,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseTryStatement_on_catch_finally() { - TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error catch (e, s) {} finally {}", []); + TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error catch (e, s) {} finally {}", []); JUnitTestCase.assertNotNull(statement.tryKeyword); JUnitTestCase.assertNotNull(statement.body); NodeList catchClauses = statement.catchClauses; @@ -4018,14 +4050,14 @@ class SimpleParserTest extends ParserTestCase { } void test_parseTypeArgumentList_multiple() { - TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", "", []); + TypeArgumentList argumentList = ParserTestCase.parse4("parseTypeArgumentList", "", []); JUnitTestCase.assertNotNull(argumentList.leftBracket); EngineTestCase.assertSize(3, argumentList.arguments); JUnitTestCase.assertNotNull(argumentList.rightBracket); } void test_parseTypeArgumentList_nested() { - TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", ">", []); + TypeArgumentList argumentList = ParserTestCase.parse4("parseTypeArgumentList", ">", []); JUnitTestCase.assertNotNull(argumentList.leftBracket); EngineTestCase.assertSize(1, argumentList.arguments); TypeName argument = argumentList.arguments[0]; @@ -4037,75 +4069,75 @@ class SimpleParserTest extends ParserTestCase { } void test_parseTypeArgumentList_single() { - TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", "", []); + TypeArgumentList argumentList = ParserTestCase.parse4("parseTypeArgumentList", "", []); JUnitTestCase.assertNotNull(argumentList.leftBracket); EngineTestCase.assertSize(1, argumentList.arguments); JUnitTestCase.assertNotNull(argumentList.rightBracket); } void test_parseTypeName_parameterized() { - TypeName typeName = ParserTestCase.parse5("parseTypeName", "List", []); + TypeName typeName = ParserTestCase.parse4("parseTypeName", "List", []); JUnitTestCase.assertNotNull(typeName.name); JUnitTestCase.assertNotNull(typeName.typeArguments); } void test_parseTypeName_simple() { - TypeName typeName = ParserTestCase.parse5("parseTypeName", "int", []); + TypeName typeName = ParserTestCase.parse4("parseTypeName", "int", []); JUnitTestCase.assertNotNull(typeName.name); JUnitTestCase.assertNull(typeName.typeArguments); } void test_parseTypeParameter_bounded() { - TypeParameter parameter = ParserTestCase.parse5("parseTypeParameter", "A extends B", []); + TypeParameter parameter = ParserTestCase.parse4("parseTypeParameter", "A extends B", []); JUnitTestCase.assertNotNull(parameter.bound); JUnitTestCase.assertNotNull(parameter.keyword); JUnitTestCase.assertNotNull(parameter.name); } void test_parseTypeParameter_simple() { - TypeParameter parameter = ParserTestCase.parse5("parseTypeParameter", "A", []); + TypeParameter parameter = ParserTestCase.parse4("parseTypeParameter", "A", []); JUnitTestCase.assertNull(parameter.bound); JUnitTestCase.assertNull(parameter.keyword); JUnitTestCase.assertNotNull(parameter.name); } void test_parseTypeParameterList_multiple() { - TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "", []); + TypeParameterList parameterList = ParserTestCase.parse4("parseTypeParameterList", "", []); JUnitTestCase.assertNotNull(parameterList.leftBracket); JUnitTestCase.assertNotNull(parameterList.rightBracket); EngineTestCase.assertSize(3, parameterList.typeParameters); } void test_parseTypeParameterList_parameterizedWithTrailingEquals() { - TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", ">=", []); + TypeParameterList parameterList = ParserTestCase.parse4("parseTypeParameterList", ">=", []); JUnitTestCase.assertNotNull(parameterList.leftBracket); JUnitTestCase.assertNotNull(parameterList.rightBracket); EngineTestCase.assertSize(1, parameterList.typeParameters); } void test_parseTypeParameterList_single() { - TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "", []); + TypeParameterList parameterList = ParserTestCase.parse4("parseTypeParameterList", "", []); JUnitTestCase.assertNotNull(parameterList.leftBracket); JUnitTestCase.assertNotNull(parameterList.rightBracket); EngineTestCase.assertSize(1, parameterList.typeParameters); } void test_parseTypeParameterList_withTrailingEquals() { - TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "=", []); + TypeParameterList parameterList = ParserTestCase.parse4("parseTypeParameterList", "=", []); JUnitTestCase.assertNotNull(parameterList.leftBracket); JUnitTestCase.assertNotNull(parameterList.rightBracket); EngineTestCase.assertSize(1, parameterList.typeParameters); } void test_parseUnaryExpression_decrement_normal() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "--x", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "--x", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.MINUS_MINUS, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); } void test_parseUnaryExpression_decrement_super() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "--super", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "--super", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type); Expression innerExpression = expression.operand; @@ -4118,7 +4150,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseUnaryExpression_decrement_super_propertyAccess() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "--super.x", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "--super.x", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.MINUS_MINUS, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); @@ -4128,14 +4160,14 @@ class SimpleParserTest extends ParserTestCase { } void test_parseUnaryExpression_increment_normal() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "++x", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "++x", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.PLUS_PLUS, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); } void test_parseUnaryExpression_increment_super_index() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "++super[0]", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "++super[0]", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.PLUS_PLUS, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); @@ -4145,7 +4177,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseUnaryExpression_increment_super_propertyAccess() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "++super.x", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "++super.x", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.PLUS_PLUS, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); @@ -4155,56 +4187,56 @@ class SimpleParserTest extends ParserTestCase { } void test_parseUnaryExpression_minus_normal() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "-x", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "-x", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); } void test_parseUnaryExpression_minus_super() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "-super", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "-super", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); } void test_parseUnaryExpression_not_normal() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "!x", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "!x", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.BANG, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); } void test_parseUnaryExpression_not_super() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "!super", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "!super", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.BANG, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); } void test_parseUnaryExpression_tilda_normal() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "~x", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "~x", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.TILDE, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); } void test_parseUnaryExpression_tilda_super() { - PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "~super", []); + PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "~super", []); JUnitTestCase.assertNotNull(expression.operator); JUnitTestCase.assertEquals(TokenType.TILDE, expression.operator.type); JUnitTestCase.assertNotNull(expression.operand); } void test_parseVariableDeclaration_equals() { - VariableDeclaration declaration = ParserTestCase.parse5("parseVariableDeclaration", "a = b", []); + VariableDeclaration declaration = ParserTestCase.parse4("parseVariableDeclaration", "a = b", []); JUnitTestCase.assertNotNull(declaration.name); JUnitTestCase.assertNotNull(declaration.equals); JUnitTestCase.assertNotNull(declaration.initializer); } void test_parseVariableDeclaration_noEquals() { - VariableDeclaration declaration = ParserTestCase.parse5("parseVariableDeclaration", "a", []); + VariableDeclaration declaration = ParserTestCase.parse4("parseVariableDeclaration", "a", []); JUnitTestCase.assertNotNull(declaration.name); JUnitTestCase.assertNull(declaration.equals); JUnitTestCase.assertNull(declaration.initializer); @@ -4299,7 +4331,7 @@ class SimpleParserTest extends ParserTestCase { } void test_parseWhileStatement() { - WhileStatement statement = ParserTestCase.parse5("parseWhileStatement", "while (x) {}", []); + WhileStatement statement = ParserTestCase.parse4("parseWhileStatement", "while (x) {}", []); JUnitTestCase.assertNotNull(statement.keyword); JUnitTestCase.assertNotNull(statement.leftParenthesis); JUnitTestCase.assertNotNull(statement.condition); @@ -4308,13 +4340,13 @@ class SimpleParserTest extends ParserTestCase { } void test_parseWithClause_multiple() { - WithClause clause = ParserTestCase.parse5("parseWithClause", "with A, B, C", []); + WithClause clause = ParserTestCase.parse4("parseWithClause", "with A, B, C", []); JUnitTestCase.assertNotNull(clause.withKeyword); EngineTestCase.assertSize(3, clause.mixinTypes); } void test_parseWithClause_single() { - WithClause clause = ParserTestCase.parse5("parseWithClause", "with M", []); + WithClause clause = ParserTestCase.parse4("parseWithClause", "with M", []); JUnitTestCase.assertNotNull(clause.withKeyword); EngineTestCase.assertSize(1, clause.mixinTypes); } @@ -5235,10 +5267,22 @@ class SimpleParserTest extends ParserTestCase { final __test = new SimpleParserTest(); runJUnitTest(__test, __test.test_parseCommentReference_simple); }); + _ut.test('test_parseCommentReference_synthetic', () { + final __test = new SimpleParserTest(); + runJUnitTest(__test, __test.test_parseCommentReference_synthetic); + }); _ut.test('test_parseCommentReferences_multiLine', () { final __test = new SimpleParserTest(); runJUnitTest(__test, __test.test_parseCommentReferences_multiLine); }); + _ut.test('test_parseCommentReferences_notClosed_noIdentifier', () { + final __test = new SimpleParserTest(); + runJUnitTest(__test, __test.test_parseCommentReferences_notClosed_noIdentifier); + }); + _ut.test('test_parseCommentReferences_notClosed_withIdentifier', () { + final __test = new SimpleParserTest(); + runJUnitTest(__test, __test.test_parseCommentReferences_notClosed_withIdentifier); + }); _ut.test('test_parseCommentReferences_singleLine', () { final __test = new SimpleParserTest(); runJUnitTest(__test, __test.test_parseCommentReferences_singleLine); @@ -7328,7 +7372,7 @@ class ParserTestCase extends EngineTestCase { * @throws Exception if the method could not be invoked or throws an exception * @throws AssertionFailedError if the result is `null` or if any errors are produced */ - static Object parse(String methodName, List objects, String source) => parse3(methodName, objects, source, new List(0)); + static Object parse(String methodName, List objects, String source) => parse2(methodName, objects, source, new List(0)); /** * Invoke a parse method in [Parser]. The method is assumed to have the given number and @@ -7346,7 +7390,7 @@ class ParserTestCase extends EngineTestCase { * @throws AssertionFailedError if the result is `null` or the errors produced while * scanning and parsing the source do not match the expected errors */ - static Object parse3(String methodName, List objects, String source, List errors) { + static Object parse2(String methodName, List objects, String source, List errors) { GatheringErrorListener listener = new GatheringErrorListener(); Object result = invokeParserMethod(methodName, objects, source, listener); listener.assertErrors(errors); @@ -7369,7 +7413,7 @@ class ParserTestCase extends EngineTestCase { * @throws AssertionFailedError if the result is `null` or the errors produced while * scanning and parsing the source do not match the expected errors */ - static Object parse4(String methodName, List objects, String source, List errorCodes) { + static Object parse3(String methodName, List objects, String source, List errorCodes) { GatheringErrorListener listener = new GatheringErrorListener(); Object result = invokeParserMethod(methodName, objects, source, listener); listener.assertErrors2(errorCodes); @@ -7390,7 +7434,7 @@ class ParserTestCase extends EngineTestCase { * @throws AssertionFailedError if the result is `null` or the errors produced while * scanning and parsing the source do not match the expected errors */ - static Object parse5(String methodName, String source, List errorCodes) => parse4(methodName, _EMPTY_ARGUMENTS, source, errorCodes); + static Object parse4(String methodName, String source, List errorCodes) => parse3(methodName, _EMPTY_ARGUMENTS, source, errorCodes); /** * Parse the given source as a compilation unit. @@ -8561,13 +8605,13 @@ class RecoveryParserTest extends ParserTestCase { } void test_conditionalExpression_missingElse() { - ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? y :", [ParserErrorCode.MISSING_IDENTIFIER]); + ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? y :", [ParserErrorCode.MISSING_IDENTIFIER]); EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.elseExpression); JUnitTestCase.assertTrue(expression.elseExpression.isSynthetic); } void test_conditionalExpression_missingThen() { - ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? : z", [ParserErrorCode.MISSING_IDENTIFIER]); + ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? : z", [ParserErrorCode.MISSING_IDENTIFIER]); EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.thenExpression); JUnitTestCase.assertTrue(expression.thenExpression.isSynthetic); } @@ -8625,7 +8669,7 @@ class RecoveryParserTest extends ParserTestCase { } void test_expressionList_multiple_end() { - List result = ParserTestCase.parse5("parseExpressionList", ", 2, 3, 4", [ParserErrorCode.MISSING_IDENTIFIER]); + List result = ParserTestCase.parse4("parseExpressionList", ", 2, 3, 4", [ParserErrorCode.MISSING_IDENTIFIER]); EngineTestCase.assertSize(4, result); Expression syntheticExpression = result[0]; EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression); @@ -8633,7 +8677,7 @@ class RecoveryParserTest extends ParserTestCase { } void test_expressionList_multiple_middle() { - List result = ParserTestCase.parse5("parseExpressionList", "1, 2, , 4", [ParserErrorCode.MISSING_IDENTIFIER]); + List result = ParserTestCase.parse4("parseExpressionList", "1, 2, , 4", [ParserErrorCode.MISSING_IDENTIFIER]); EngineTestCase.assertSize(4, result); Expression syntheticExpression = result[2]; EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression); @@ -8641,7 +8685,7 @@ class RecoveryParserTest extends ParserTestCase { } void test_expressionList_multiple_start() { - List result = ParserTestCase.parse5("parseExpressionList", "1, 2, 3,", [ParserErrorCode.MISSING_IDENTIFIER]); + List result = ParserTestCase.parse4("parseExpressionList", "1, 2, 3,", [ParserErrorCode.MISSING_IDENTIFIER]); EngineTestCase.assertSize(4, result); Expression syntheticExpression = result[3]; EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression); @@ -8755,6 +8799,14 @@ class RecoveryParserTest extends ParserTestCase { EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand); } + void test_missingIdentifier_afterAnnotation() { + MethodDeclaration method = ParserTestCase.parse3("parseClassMember", ["C"], "@override }", [ParserErrorCode.EXPECTED_CLASS_MEMBER]); + JUnitTestCase.assertNull(method.documentationComment); + NodeList metadata = method.metadata; + EngineTestCase.assertSize(1, metadata); + JUnitTestCase.assertEquals("override", metadata[0].name.name); + } + void test_multiplicativeExpression_missing_LHS() { BinaryExpression expression = ParserTestCase.parseExpression("* y", [ParserErrorCode.MISSING_IDENTIFIER]); EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand); @@ -9133,6 +9185,10 @@ class RecoveryParserTest extends ParserTestCase { final __test = new RecoveryParserTest(); runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_right); }); + _ut.test('test_missingIdentifier_afterAnnotation', () { + final __test = new RecoveryParserTest(); + runJUnitTest(__test, __test.test_missingIdentifier_afterAnnotation); + }); _ut.test('test_multiplicativeExpression_missing_LHS', () { final __test = new RecoveryParserTest(); runJUnitTest(__test, __test.test_multiplicativeExpression_missing_LHS); @@ -9284,6 +9340,12 @@ class IncrementalParserTest extends EngineTestCase { assertParse("class A {}", "", " class B {}", ""); } + void test_insert_insideClassBody() { + // "class C {C(); }" + // "class C { C(); }" + assertParse("class C {", "", " ", "C(); }"); + } + void test_insert_insideIdentifier() { // "f() => cob;" // "f() => cow.b;" @@ -9510,6 +9572,10 @@ class IncrementalParserTest extends EngineTestCase { final __test = new IncrementalParserTest(); runJUnitTest(__test, __test.test_insert_end); }); + _ut.test('test_insert_insideClassBody', () { + final __test = new IncrementalParserTest(); + runJUnitTest(__test, __test.test_insert_insideClassBody); + }); _ut.test('test_insert_insideIdentifier', () { final __test = new IncrementalParserTest(); runJUnitTest(__test, __test.test_insert_insideIdentifier); @@ -9608,7 +9674,7 @@ class ErrorParserTest extends ParserTestCase { // literal in this case, but isSynthetic() isn't overridden for ListLiteral. The problem is that // the synthetic list literals that are being created are not always zero length (because they // could have type parameters), which violates the contract of isSynthetic(). - TypedLiteral literal = ParserTestCase.parse4("parseListOrMapLiteral", [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]); + TypedLiteral literal = ParserTestCase.parse3("parseListOrMapLiteral", [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]); JUnitTestCase.assertTrue(literal.isSynthetic); } @@ -9620,26 +9686,26 @@ class ErrorParserTest extends ParserTestCase { void fail_invalidCommentReference__new_nonIdentifier() { // This test fails because the method parseCommentReference returns null. - ParserTestCase.parse4("parseCommentReference", ["new 42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]); + ParserTestCase.parse3("parseCommentReference", ["new 42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]); } void fail_invalidCommentReference__new_tooMuch() { - ParserTestCase.parse4("parseCommentReference", ["new a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]); + ParserTestCase.parse3("parseCommentReference", ["new a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]); } void fail_invalidCommentReference__nonNew_nonIdentifier() { // This test fails because the method parseCommentReference returns null. - ParserTestCase.parse4("parseCommentReference", ["42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]); + ParserTestCase.parse3("parseCommentReference", ["42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]); } void fail_invalidCommentReference__nonNew_tooMuch() { - ParserTestCase.parse4("parseCommentReference", ["a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]); + ParserTestCase.parse3("parseCommentReference", ["a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]); } void fail_missingClosingParenthesis() { // It is possible that it is not possible to generate this error (that it's being reported in // code that cannot actually be reached), but that hasn't been proven yet. - ParserTestCase.parse5("parseFormalParameterList", "(int a, int b ;", [ParserErrorCode.MISSING_CLOSING_PARENTHESIS]); + ParserTestCase.parse4("parseFormalParameterList", "(int a, int b ;", [ParserErrorCode.MISSING_CLOSING_PARENTHESIS]); } void fail_missingFunctionParameters_local_nonVoid_block() { @@ -9655,7 +9721,7 @@ class ErrorParserTest extends ParserTestCase { } void fail_namedFunctionExpression() { - Expression expression = ParserTestCase.parse5("parsePrimaryExpression", "f() {}", [ParserErrorCode.NAMED_FUNCTION_EXPRESSION]); + Expression expression = ParserTestCase.parse4("parsePrimaryExpression", "f() {}", [ParserErrorCode.NAMED_FUNCTION_EXPRESSION]); EngineTestCase.assertInstanceOf(FunctionExpression, expression); } @@ -9673,27 +9739,27 @@ class ErrorParserTest extends ParserTestCase { void fail_varAndType_parameter() { // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but this would be a // better error message. - ParserTestCase.parse5("parseFormalParameterList", "(var int x)", [ParserErrorCode.VAR_AND_TYPE]); + ParserTestCase.parse4("parseFormalParameterList", "(var int x)", [ParserErrorCode.VAR_AND_TYPE]); } void test_abstractClassMember_constructor() { - ParserTestCase.parse4("parseClassMember", ["C"], "abstract C.c();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); + ParserTestCase.parse3("parseClassMember", ["C"], "abstract C.c();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); } void test_abstractClassMember_field() { - ParserTestCase.parse4("parseClassMember", ["C"], "abstract C f;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); + ParserTestCase.parse3("parseClassMember", ["C"], "abstract C f;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); } void test_abstractClassMember_getter() { - ParserTestCase.parse4("parseClassMember", ["C"], "abstract get m;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); + ParserTestCase.parse3("parseClassMember", ["C"], "abstract get m;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); } void test_abstractClassMember_method() { - ParserTestCase.parse4("parseClassMember", ["C"], "abstract m();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); + ParserTestCase.parse3("parseClassMember", ["C"], "abstract m();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); } void test_abstractClassMember_setter() { - ParserTestCase.parse4("parseClassMember", ["C"], "abstract set m(v);", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); + ParserTestCase.parse3("parseClassMember", ["C"], "abstract set m(v);", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]); } void test_abstractTopLevelFunction_function() { @@ -9717,39 +9783,39 @@ class ErrorParserTest extends ParserTestCase { } void test_assertDoesNotTakeAssignment() { - ParserTestCase.parse5("parseAssertStatement", "assert(b = true);", [ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT]); + ParserTestCase.parse4("parseAssertStatement", "assert(b = true);", [ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT]); } void test_assertDoesNotTakeCascades() { - ParserTestCase.parse5("parseAssertStatement", "assert(new A()..m());", [ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE]); + ParserTestCase.parse4("parseAssertStatement", "assert(new A()..m());", [ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE]); } void test_assertDoesNotTakeRethrow() { - ParserTestCase.parse5("parseAssertStatement", "assert(rethrow);", [ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW]); + ParserTestCase.parse4("parseAssertStatement", "assert(rethrow);", [ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW]); } void test_assertDoesNotTakeThrow() { - ParserTestCase.parse5("parseAssertStatement", "assert(throw x);", [ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW]); + ParserTestCase.parse4("parseAssertStatement", "assert(throw x);", [ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW]); } void test_breakOutsideOfLoop_breakInDoStatement() { - ParserTestCase.parse5("parseDoStatement", "do {break;} while (x);", []); + ParserTestCase.parse4("parseDoStatement", "do {break;} while (x);", []); } void test_breakOutsideOfLoop_breakInForStatement() { - ParserTestCase.parse5("parseForStatement", "for (; x;) {break;}", []); + ParserTestCase.parse4("parseForStatement", "for (; x;) {break;}", []); } void test_breakOutsideOfLoop_breakInIfStatement() { - ParserTestCase.parse5("parseIfStatement", "if (x) {break;}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]); + ParserTestCase.parse4("parseIfStatement", "if (x) {break;}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]); } void test_breakOutsideOfLoop_breakInSwitchStatement() { - ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: break;}", []); + ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: break;}", []); } void test_breakOutsideOfLoop_breakInWhileStatement() { - ParserTestCase.parse5("parseWhileStatement", "while (x) {break;}", []); + ParserTestCase.parse4("parseWhileStatement", "while (x) {break;}", []); } void test_breakOutsideOfLoop_functionExpression_inALoop() { @@ -9761,11 +9827,11 @@ class ErrorParserTest extends ParserTestCase { } void test_constAndFinal() { - ParserTestCase.parse4("parseClassMember", ["C"], "const final int x;", [ParserErrorCode.CONST_AND_FINAL]); + ParserTestCase.parse3("parseClassMember", ["C"], "const final int x;", [ParserErrorCode.CONST_AND_FINAL]); } void test_constAndVar() { - ParserTestCase.parse4("parseClassMember", ["C"], "const var x;", [ParserErrorCode.CONST_AND_VAR]); + ParserTestCase.parse3("parseClassMember", ["C"], "const var x;", [ParserErrorCode.CONST_AND_VAR]); } void test_constClass() { @@ -9773,23 +9839,23 @@ class ErrorParserTest extends ParserTestCase { } void test_constConstructorWithBody() { - ParserTestCase.parse4("parseClassMember", ["C"], "const C() {}", [ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "const C() {}", [ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY]); } void test_constFactory() { - ParserTestCase.parse4("parseClassMember", ["C"], "const factory C() {}", [ParserErrorCode.CONST_FACTORY]); + ParserTestCase.parse3("parseClassMember", ["C"], "const factory C() {}", [ParserErrorCode.CONST_FACTORY]); } void test_constMethod() { - ParserTestCase.parse4("parseClassMember", ["C"], "const int m() {}", [ParserErrorCode.CONST_METHOD]); + ParserTestCase.parse3("parseClassMember", ["C"], "const int m() {}", [ParserErrorCode.CONST_METHOD]); } void test_constructorWithReturnType() { - ParserTestCase.parse4("parseClassMember", ["C"], "C C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]); + ParserTestCase.parse3("parseClassMember", ["C"], "C C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]); } void test_constructorWithReturnType_var() { - ParserTestCase.parse4("parseClassMember", ["C"], "var C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]); + ParserTestCase.parse3("parseClassMember", ["C"], "var C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]); } void test_constTypedef() { @@ -9797,23 +9863,23 @@ class ErrorParserTest extends ParserTestCase { } void test_continueOutsideOfLoop_continueInDoStatement() { - ParserTestCase.parse5("parseDoStatement", "do {continue;} while (x);", []); + ParserTestCase.parse4("parseDoStatement", "do {continue;} while (x);", []); } void test_continueOutsideOfLoop_continueInForStatement() { - ParserTestCase.parse5("parseForStatement", "for (; x;) {continue;}", []); + ParserTestCase.parse4("parseForStatement", "for (; x;) {continue;}", []); } void test_continueOutsideOfLoop_continueInIfStatement() { - ParserTestCase.parse5("parseIfStatement", "if (x) {continue;}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]); + ParserTestCase.parse4("parseIfStatement", "if (x) {continue;}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]); } void test_continueOutsideOfLoop_continueInSwitchStatement() { - ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue a;}", []); + ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: continue a;}", []); } void test_continueOutsideOfLoop_continueInWhileStatement() { - ParserTestCase.parse5("parseWhileStatement", "while (x) {continue;}", []); + ParserTestCase.parse4("parseWhileStatement", "while (x) {continue;}", []); } void test_continueOutsideOfLoop_functionExpression_inALoop() { @@ -9825,15 +9891,15 @@ class ErrorParserTest extends ParserTestCase { } void test_continueWithoutLabelInCase_error() { - ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue;}", [ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE]); + ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: continue;}", [ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE]); } void test_continueWithoutLabelInCase_noError() { - ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue a;}", []); + ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: continue a;}", []); } void test_continueWithoutLabelInCase_noError_switchInLoop() { - ParserTestCase.parse5("parseWhileStatement", "while (a) { switch (b) {default: continue;}}", []); + ParserTestCase.parse4("parseWhileStatement", "while (a) { switch (b) {default: continue;}}", []); } void test_deprecatedClassTypeAlias() { @@ -9855,31 +9921,31 @@ class ErrorParserTest extends ParserTestCase { } void test_duplicatedModifier_const() { - ParserTestCase.parse4("parseClassMember", ["C"], "const const m;", [ParserErrorCode.DUPLICATED_MODIFIER]); + ParserTestCase.parse3("parseClassMember", ["C"], "const const m;", [ParserErrorCode.DUPLICATED_MODIFIER]); } void test_duplicatedModifier_external() { - ParserTestCase.parse4("parseClassMember", ["C"], "external external f();", [ParserErrorCode.DUPLICATED_MODIFIER]); + ParserTestCase.parse3("parseClassMember", ["C"], "external external f();", [ParserErrorCode.DUPLICATED_MODIFIER]); } void test_duplicatedModifier_factory() { - ParserTestCase.parse4("parseClassMember", ["C"], "factory factory C() {}", [ParserErrorCode.DUPLICATED_MODIFIER]); + ParserTestCase.parse3("parseClassMember", ["C"], "factory factory C() {}", [ParserErrorCode.DUPLICATED_MODIFIER]); } void test_duplicatedModifier_final() { - ParserTestCase.parse4("parseClassMember", ["C"], "final final m;", [ParserErrorCode.DUPLICATED_MODIFIER]); + ParserTestCase.parse3("parseClassMember", ["C"], "final final m;", [ParserErrorCode.DUPLICATED_MODIFIER]); } void test_duplicatedModifier_static() { - ParserTestCase.parse4("parseClassMember", ["C"], "static static var m;", [ParserErrorCode.DUPLICATED_MODIFIER]); + ParserTestCase.parse3("parseClassMember", ["C"], "static static var m;", [ParserErrorCode.DUPLICATED_MODIFIER]); } void test_duplicatedModifier_var() { - ParserTestCase.parse4("parseClassMember", ["C"], "var var m;", [ParserErrorCode.DUPLICATED_MODIFIER]); + ParserTestCase.parse3("parseClassMember", ["C"], "var var m;", [ParserErrorCode.DUPLICATED_MODIFIER]); } void test_duplicateLabelInSwitchStatement() { - ParserTestCase.parse5("parseSwitchStatement", "switch (e) {l1: case 0: break; l1: case 1: break;}", [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]); + ParserTestCase.parse4("parseSwitchStatement", "switch (e) {l1: case 0: break; l1: case 1: break;}", [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]); } void test_equalityCannotBeEqualityOperand_eq_eq() { @@ -9895,44 +9961,44 @@ class ErrorParserTest extends ParserTestCase { } void test_expectedCaseOrDefault() { - ParserTestCase.parse5("parseSwitchStatement", "switch (e) {break;}", [ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]); + ParserTestCase.parse4("parseSwitchStatement", "switch (e) {break;}", [ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]); } void test_expectedClassMember_inClass_afterType() { - ParserTestCase.parse4("parseClassMember", ["C"], "heart 2 heart", [ParserErrorCode.EXPECTED_CLASS_MEMBER]); + ParserTestCase.parse3("parseClassMember", ["C"], "heart 2 heart", [ParserErrorCode.EXPECTED_CLASS_MEMBER]); } void test_expectedClassMember_inClass_beforeType() { - ParserTestCase.parse4("parseClassMember", ["C"], "4 score", [ParserErrorCode.EXPECTED_CLASS_MEMBER]); + ParserTestCase.parse3("parseClassMember", ["C"], "4 score", [ParserErrorCode.EXPECTED_CLASS_MEMBER]); } void test_expectedExecutable_inClass_afterVoid() { - ParserTestCase.parse4("parseClassMember", ["C"], "void 2 void", [ParserErrorCode.EXPECTED_EXECUTABLE]); + ParserTestCase.parse3("parseClassMember", ["C"], "void 2 void", [ParserErrorCode.EXPECTED_EXECUTABLE]); } void test_expectedExecutable_topLevel_afterType() { - ParserTestCase.parse4("parseCompilationUnitMember", [emptyCommentAndMetadata()], "heart 2 heart", [ParserErrorCode.EXPECTED_EXECUTABLE]); + ParserTestCase.parse3("parseCompilationUnitMember", [emptyCommentAndMetadata()], "heart 2 heart", [ParserErrorCode.EXPECTED_EXECUTABLE]); } void test_expectedExecutable_topLevel_afterVoid() { - ParserTestCase.parse4("parseCompilationUnitMember", [emptyCommentAndMetadata()], "void 2 void", [ParserErrorCode.EXPECTED_EXECUTABLE]); + ParserTestCase.parse3("parseCompilationUnitMember", [emptyCommentAndMetadata()], "void 2 void", [ParserErrorCode.EXPECTED_EXECUTABLE]); } void test_expectedExecutable_topLevel_beforeType() { - ParserTestCase.parse4("parseCompilationUnitMember", [emptyCommentAndMetadata()], "4 score", [ParserErrorCode.EXPECTED_EXECUTABLE]); + ParserTestCase.parse3("parseCompilationUnitMember", [emptyCommentAndMetadata()], "4 score", [ParserErrorCode.EXPECTED_EXECUTABLE]); } void test_expectedInterpolationIdentifier() { - ParserTestCase.parse5("parseStringLiteral", "'\$x\$'", [ParserErrorCode.MISSING_IDENTIFIER]); + ParserTestCase.parse4("parseStringLiteral", "'\$x\$'", [ParserErrorCode.MISSING_IDENTIFIER]); } void test_expectedStringLiteral() { - StringLiteral expression = ParserTestCase.parse5("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]); + StringLiteral expression = ParserTestCase.parse4("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]); JUnitTestCase.assertTrue(expression.isSynthetic); } void test_expectedToken_commaMissingInArgumentList() { - ParserTestCase.parse5("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]); + ParserTestCase.parse4("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]); } void test_expectedToken_parseStatement_afterVoid() { @@ -9943,13 +10009,29 @@ class ErrorParserTest extends ParserTestCase { void test_expectedToken_semicolonAfterClass() { Token token = TokenFactory.token(Keyword.CLASS); - ParserTestCase.parse4("parseClassTypeAlias", [emptyCommentAndMetadata(), null, token], "A = B", [ParserErrorCode.EXPECTED_TOKEN]); + ParserTestCase.parse3("parseClassTypeAlias", [emptyCommentAndMetadata(), null, token], "A = B", [ParserErrorCode.EXPECTED_TOKEN]); + } + + void test_expectedToken_semicolonMissingAfterExport() { + CompilationUnit unit = ParserTestCase.parseCompilationUnit("export '' class A {}", [ParserErrorCode.EXPECTED_TOKEN]); + ExportDirective directive = unit.directives[0] as ExportDirective; + Token semicolon = directive.semicolon; + JUnitTestCase.assertNotNull(semicolon); + JUnitTestCase.assertTrue(semicolon.isSynthetic); } void test_expectedToken_semicolonMissingAfterExpression() { ParserTestCase.parseStatement("x", [ParserErrorCode.EXPECTED_TOKEN]); } + void test_expectedToken_semicolonMissingAfterImport() { + CompilationUnit unit = ParserTestCase.parseCompilationUnit("import '' class A {}", [ParserErrorCode.EXPECTED_TOKEN]); + ImportDirective directive = unit.directives[0] as ImportDirective; + Token semicolon = directive.semicolon; + JUnitTestCase.assertNotNull(semicolon); + JUnitTestCase.assertTrue(semicolon.isSynthetic); + } + void test_expectedToken_whileMissingInDoStatement() { ParserTestCase.parseStatement("do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]); } @@ -9963,15 +10045,15 @@ class ErrorParserTest extends ParserTestCase { } void test_externalAfterConst() { - ParserTestCase.parse4("parseClassMember", ["C"], "const external C();", [ParserErrorCode.EXTERNAL_AFTER_CONST]); + ParserTestCase.parse3("parseClassMember", ["C"], "const external C();", [ParserErrorCode.EXTERNAL_AFTER_CONST]); } void test_externalAfterFactory() { - ParserTestCase.parse4("parseClassMember", ["C"], "factory external C();", [ParserErrorCode.EXTERNAL_AFTER_FACTORY]); + ParserTestCase.parse3("parseClassMember", ["C"], "factory external C();", [ParserErrorCode.EXTERNAL_AFTER_FACTORY]); } void test_externalAfterStatic() { - ParserTestCase.parse4("parseClassMember", ["C"], "static external int m();", [ParserErrorCode.EXTERNAL_AFTER_STATIC]); + ParserTestCase.parse3("parseClassMember", ["C"], "static external int m();", [ParserErrorCode.EXTERNAL_AFTER_STATIC]); } void test_externalClass() { @@ -9979,47 +10061,47 @@ class ErrorParserTest extends ParserTestCase { } void test_externalConstructorWithBody_factory() { - ParserTestCase.parse4("parseClassMember", ["C"], "external factory C() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "external factory C() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]); } void test_externalConstructorWithBody_named() { - ParserTestCase.parse4("parseClassMember", ["C"], "external C.c() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "external C.c() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]); } void test_externalField_const() { - ParserTestCase.parse4("parseClassMember", ["C"], "external const A f;", [ParserErrorCode.EXTERNAL_FIELD]); + ParserTestCase.parse3("parseClassMember", ["C"], "external const A f;", [ParserErrorCode.EXTERNAL_FIELD]); } void test_externalField_final() { - ParserTestCase.parse4("parseClassMember", ["C"], "external final A f;", [ParserErrorCode.EXTERNAL_FIELD]); + ParserTestCase.parse3("parseClassMember", ["C"], "external final A f;", [ParserErrorCode.EXTERNAL_FIELD]); } void test_externalField_static() { - ParserTestCase.parse4("parseClassMember", ["C"], "external static A f;", [ParserErrorCode.EXTERNAL_FIELD]); + ParserTestCase.parse3("parseClassMember", ["C"], "external static A f;", [ParserErrorCode.EXTERNAL_FIELD]); } void test_externalField_typed() { - ParserTestCase.parse4("parseClassMember", ["C"], "external A f;", [ParserErrorCode.EXTERNAL_FIELD]); + ParserTestCase.parse3("parseClassMember", ["C"], "external A f;", [ParserErrorCode.EXTERNAL_FIELD]); } void test_externalField_untyped() { - ParserTestCase.parse4("parseClassMember", ["C"], "external var f;", [ParserErrorCode.EXTERNAL_FIELD]); + ParserTestCase.parse3("parseClassMember", ["C"], "external var f;", [ParserErrorCode.EXTERNAL_FIELD]); } void test_externalGetterWithBody() { - ParserTestCase.parse4("parseClassMember", ["C"], "external int get x {}", [ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "external int get x {}", [ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]); } void test_externalMethodWithBody() { - ParserTestCase.parse4("parseClassMember", ["C"], "external m() {}", [ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "external m() {}", [ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]); } void test_externalOperatorWithBody() { - ParserTestCase.parse4("parseClassMember", ["C"], "external operator +(int value) {}", [ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "external operator +(int value) {}", [ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY]); } void test_externalSetterWithBody() { - ParserTestCase.parse4("parseClassMember", ["C"], "external set x(int value) {}", [ParserErrorCode.EXTERNAL_SETTER_WITH_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "external set x(int value) {}", [ParserErrorCode.EXTERNAL_SETTER_WITH_BODY]); } void test_externalTypedef() { @@ -10035,15 +10117,15 @@ class ErrorParserTest extends ParserTestCase { } void test_factoryWithoutBody() { - ParserTestCase.parse4("parseClassMember", ["C"], "factory C();", [ParserErrorCode.FACTORY_WITHOUT_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "factory C();", [ParserErrorCode.FACTORY_WITHOUT_BODY]); } void test_fieldInitializerOutsideConstructor() { - ParserTestCase.parse4("parseClassMember", ["C"], "void m(this.x);", [ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "void m(this.x);", [ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]); } void test_finalAndVar() { - ParserTestCase.parse4("parseClassMember", ["C"], "final var x;", [ParserErrorCode.FINAL_AND_VAR]); + ParserTestCase.parse3("parseClassMember", ["C"], "final var x;", [ParserErrorCode.FINAL_AND_VAR]); } void test_finalClass() { @@ -10051,11 +10133,11 @@ class ErrorParserTest extends ParserTestCase { } void test_finalConstructor() { - ParserTestCase.parse4("parseClassMember", ["C"], "final C() {}", [ParserErrorCode.FINAL_CONSTRUCTOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "final C() {}", [ParserErrorCode.FINAL_CONSTRUCTOR]); } void test_finalMethod() { - ParserTestCase.parse4("parseClassMember", ["C"], "final int m() {}", [ParserErrorCode.FINAL_METHOD]); + ParserTestCase.parse3("parseClassMember", ["C"], "final int m() {}", [ParserErrorCode.FINAL_METHOD]); } void test_finalTypedef() { @@ -10083,7 +10165,23 @@ class ErrorParserTest extends ParserTestCase { } void test_getterWithParameters() { - ParserTestCase.parse4("parseClassMember", ["C"], "int get x() {}", [ParserErrorCode.GETTER_WITH_PARAMETERS]); + ParserTestCase.parse3("parseClassMember", ["C"], "int get x() {}", [ParserErrorCode.GETTER_WITH_PARAMETERS]); + } + + void test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal() { + ParserTestCase.parseExpression("0--", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]); + } + + void test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal() { + ParserTestCase.parseExpression("0++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]); + } + + void test_illegalAssignmentToNonAssignable_postfix_plusPlus_parethesized() { + ParserTestCase.parseExpression("(x)++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]); + } + + void test_illegalAssignmentToNonAssignable_primarySelectorPostfix() { + ParserTestCase.parseExpression("x(y)(z)++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]); } void test_illegalAssignmentToNonAssignable_superAssigned() { @@ -10108,55 +10206,55 @@ class ErrorParserTest extends ParserTestCase { } void test_initializedVariableInForEach() { - ParserTestCase.parse5("parseForStatement", "for (int a = 0 in foo) {}", [ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH]); + ParserTestCase.parse4("parseForStatement", "for (int a = 0 in foo) {}", [ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH]); } void test_invalidCodePoint() { - ParserTestCase.parse5("parseStringLiteral", "'\\uD900'", [ParserErrorCode.INVALID_CODE_POINT]); + ParserTestCase.parse4("parseStringLiteral", "'\\uD900'", [ParserErrorCode.INVALID_CODE_POINT]); } void test_invalidHexEscape_invalidDigit() { - ParserTestCase.parse5("parseStringLiteral", "'\\x0 a'", [ParserErrorCode.INVALID_HEX_ESCAPE]); + ParserTestCase.parse4("parseStringLiteral", "'\\x0 a'", [ParserErrorCode.INVALID_HEX_ESCAPE]); } void test_invalidHexEscape_tooFewDigits() { - ParserTestCase.parse5("parseStringLiteral", "'\\x0'", [ParserErrorCode.INVALID_HEX_ESCAPE]); + ParserTestCase.parse4("parseStringLiteral", "'\\x0'", [ParserErrorCode.INVALID_HEX_ESCAPE]); } void test_invalidInterpolationIdentifier_startWithDigit() { - ParserTestCase.parse5("parseStringLiteral", "'\$1'", [ParserErrorCode.MISSING_IDENTIFIER]); + ParserTestCase.parse4("parseStringLiteral", "'\$1'", [ParserErrorCode.MISSING_IDENTIFIER]); } void test_invalidOperator() { - ParserTestCase.parse4("parseClassMember", ["C"], "void operator ===(x) {}", [ParserErrorCode.INVALID_OPERATOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "void operator ===(x) {}", [ParserErrorCode.INVALID_OPERATOR]); } void test_invalidOperatorForSuper() { - ParserTestCase.parse5("parseUnaryExpression", "++super", [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]); + ParserTestCase.parse4("parseUnaryExpression", "++super", [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]); } void test_invalidUnicodeEscape_incomplete_noDigits() { - ParserTestCase.parse5("parseStringLiteral", "'\\u{'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); + ParserTestCase.parse4("parseStringLiteral", "'\\u{'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); } void test_invalidUnicodeEscape_incomplete_someDigits() { - ParserTestCase.parse5("parseStringLiteral", "'\\u{0A'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); + ParserTestCase.parse4("parseStringLiteral", "'\\u{0A'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); } void test_invalidUnicodeEscape_invalidDigit() { - ParserTestCase.parse5("parseStringLiteral", "'\\u0 a'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); + ParserTestCase.parse4("parseStringLiteral", "'\\u0 a'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); } void test_invalidUnicodeEscape_tooFewDigits_fixed() { - ParserTestCase.parse5("parseStringLiteral", "'\\u04'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); + ParserTestCase.parse4("parseStringLiteral", "'\\u04'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); } void test_invalidUnicodeEscape_tooFewDigits_variable() { - ParserTestCase.parse5("parseStringLiteral", "'\\u{}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); + ParserTestCase.parse4("parseStringLiteral", "'\\u{}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]); } void test_invalidUnicodeEscape_tooManyDigits_variable() { - ParserTestCase.parse5("parseStringLiteral", "'\\u{12345678}'", [ + ParserTestCase.parse4("parseStringLiteral", "'\\u{12345678}'", [ ParserErrorCode.INVALID_UNICODE_ESCAPE, ParserErrorCode.INVALID_CODE_POINT]); } @@ -10190,14 +10288,6 @@ class ErrorParserTest extends ParserTestCase { ParserTestCase.parseExpression("x.y = y;", []); } - void test_missingAssignableSelector_postfix_minusMinus_literal() { - ParserTestCase.parseExpression("0--", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]); - } - - void test_missingAssignableSelector_postfix_plusPlus_literal() { - ParserTestCase.parseExpression("0++", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]); - } - void test_missingAssignableSelector_prefix_minusMinus_literal() { ParserTestCase.parseExpression("--0", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]); } @@ -10206,16 +10296,12 @@ class ErrorParserTest extends ParserTestCase { ParserTestCase.parseExpression("++0", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]); } - void test_missingAssignableSelector_primarySelectorPostfix() { - ParserTestCase.parseExpression("x(y)(z)++", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]); - } - void test_missingAssignableSelector_selector() { ParserTestCase.parseExpression("x(y)(z).a++", []); } void test_missingAssignableSelector_superPrimaryExpression() { - SuperExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "super", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]); + SuperExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "super", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]); JUnitTestCase.assertNotNull(expression.keyword); } @@ -10224,7 +10310,7 @@ class ErrorParserTest extends ParserTestCase { } void test_missingCatchOrFinally() { - TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {}", [ParserErrorCode.MISSING_CATCH_OR_FINALLY]); + TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {}", [ParserErrorCode.MISSING_CATCH_OR_FINALLY]); JUnitTestCase.assertNotNull(statement); } @@ -10237,23 +10323,23 @@ class ErrorParserTest extends ParserTestCase { } void test_missingConstFinalVarOrType_topLevel() { - ParserTestCase.parse4("parseFinalConstVarOrType", [false], "a;", [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]); + ParserTestCase.parse3("parseFinalConstVarOrType", [false], "a;", [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]); } void test_missingExpressionInThrow_withCascade() { - ParserTestCase.parse5("parseThrowExpression", "throw;", [ParserErrorCode.MISSING_EXPRESSION_IN_THROW]); + ParserTestCase.parse4("parseThrowExpression", "throw;", [ParserErrorCode.MISSING_EXPRESSION_IN_THROW]); } void test_missingExpressionInThrow_withoutCascade() { - ParserTestCase.parse5("parseThrowExpressionWithoutCascade", "throw;", [ParserErrorCode.MISSING_EXPRESSION_IN_THROW]); + ParserTestCase.parse4("parseThrowExpressionWithoutCascade", "throw;", [ParserErrorCode.MISSING_EXPRESSION_IN_THROW]); } void test_missingFunctionBody_emptyNotAllowed() { - ParserTestCase.parse4("parseFunctionBody", [false, ParserErrorCode.MISSING_FUNCTION_BODY, false], ";", [ParserErrorCode.MISSING_FUNCTION_BODY]); + ParserTestCase.parse3("parseFunctionBody", [false, ParserErrorCode.MISSING_FUNCTION_BODY, false], ";", [ParserErrorCode.MISSING_FUNCTION_BODY]); } void test_missingFunctionBody_invalid() { - ParserTestCase.parse4("parseFunctionBody", [false, ParserErrorCode.MISSING_FUNCTION_BODY, false], "return 0;", [ParserErrorCode.MISSING_FUNCTION_BODY]); + ParserTestCase.parse3("parseFunctionBody", [false, ParserErrorCode.MISSING_FUNCTION_BODY, false], "return 0;", [ParserErrorCode.MISSING_FUNCTION_BODY]); } void test_missingFunctionParameters_local_void_block() { @@ -10281,46 +10367,46 @@ class ErrorParserTest extends ParserTestCase { } void test_missingIdentifier_afterOperator() { - ParserTestCase.parse5("parseMultiplicativeExpression", "1 *", [ParserErrorCode.MISSING_IDENTIFIER]); + ParserTestCase.parse4("parseMultiplicativeExpression", "1 *", [ParserErrorCode.MISSING_IDENTIFIER]); } void test_missingIdentifier_beforeClosingCurly() { - ParserTestCase.parse4("parseClassMember", ["C"], "int}", [ + ParserTestCase.parse3("parseClassMember", ["C"], "int}", [ ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]); } void test_missingIdentifier_functionDeclaration_returnTypeWithoutName() { - ParserTestCase.parse5("parseFunctionDeclarationStatement", "A () {}", [ParserErrorCode.MISSING_IDENTIFIER]); + ParserTestCase.parse4("parseFunctionDeclarationStatement", "A () {}", [ParserErrorCode.MISSING_IDENTIFIER]); } void test_missingIdentifier_inSymbol_afterPeriod() { - ParserTestCase.parse5("parseSymbolLiteral", "#a.", [ParserErrorCode.MISSING_IDENTIFIER]); + ParserTestCase.parse4("parseSymbolLiteral", "#a.", [ParserErrorCode.MISSING_IDENTIFIER]); } void test_missingIdentifier_inSymbol_first() { - ParserTestCase.parse5("parseSymbolLiteral", "#", [ParserErrorCode.MISSING_IDENTIFIER]); + ParserTestCase.parse4("parseSymbolLiteral", "#", [ParserErrorCode.MISSING_IDENTIFIER]); } void test_missingIdentifier_number() { - SimpleIdentifier expression = ParserTestCase.parse5("parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]); + SimpleIdentifier expression = ParserTestCase.parse4("parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]); JUnitTestCase.assertTrue(expression.isSynthetic); } void test_missingKeywordOperator() { - ParserTestCase.parse4("parseOperator", [emptyCommentAndMetadata(), null, null], "+(x) {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]); + ParserTestCase.parse3("parseOperator", [emptyCommentAndMetadata(), null, null], "+(x) {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]); } void test_missingKeywordOperator_parseClassMember() { - ParserTestCase.parse4("parseClassMember", ["C"], "+() {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "+() {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]); } void test_missingKeywordOperator_parseClassMember_afterTypeName() { - ParserTestCase.parse4("parseClassMember", ["C"], "int +() {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "int +() {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]); } void test_missingKeywordOperator_parseClassMember_afterVoid() { - ParserTestCase.parse4("parseClassMember", ["C"], "void +() {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "void +() {}", [ParserErrorCode.MISSING_KEYWORD_OPERATOR]); } void test_missingNameInLibraryDirective() { @@ -10342,11 +10428,11 @@ class ErrorParserTest extends ParserTestCase { } void test_missingTerminatorForParameterGroup_named() { - ParserTestCase.parse5("parseFormalParameterList", "(a, {b: 0)", [ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP]); + ParserTestCase.parse4("parseFormalParameterList", "(a, {b: 0)", [ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP]); } void test_missingTerminatorForParameterGroup_optional() { - ParserTestCase.parse5("parseFormalParameterList", "(a, [b = 0)", [ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP]); + ParserTestCase.parse4("parseFormalParameterList", "(a, [b = 0)", [ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP]); } void test_missingTypedefParameters_nonVoid() { @@ -10362,15 +10448,15 @@ class ErrorParserTest extends ParserTestCase { } void test_missingVariableInForEach() { - ParserTestCase.parse5("parseForStatement", "for (a < b in foo) {}", [ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH]); + ParserTestCase.parse4("parseForStatement", "for (a < b in foo) {}", [ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH]); } void test_mixedParameterGroups_namedPositional() { - ParserTestCase.parse5("parseFormalParameterList", "(a, {b}, [c])", [ParserErrorCode.MIXED_PARAMETER_GROUPS]); + ParserTestCase.parse4("parseFormalParameterList", "(a, {b}, [c])", [ParserErrorCode.MIXED_PARAMETER_GROUPS]); } void test_mixedParameterGroups_positionalNamed() { - ParserTestCase.parse5("parseFormalParameterList", "(a, [b], {c})", [ParserErrorCode.MIXED_PARAMETER_GROUPS]); + ParserTestCase.parse4("parseFormalParameterList", "(a, [b], {c})", [ParserErrorCode.MIXED_PARAMETER_GROUPS]); } void test_multipleExtendsClauses() { @@ -10386,7 +10472,7 @@ class ErrorParserTest extends ParserTestCase { } void test_multipleNamedParameterGroups() { - ParserTestCase.parse5("parseFormalParameterList", "(a, {b}, {c})", [ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS]); + ParserTestCase.parse4("parseFormalParameterList", "(a, {b}, {c})", [ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS]); } void test_multiplePartOfDirectives() { @@ -10394,11 +10480,11 @@ class ErrorParserTest extends ParserTestCase { } void test_multiplePositionalParameterGroups() { - ParserTestCase.parse5("parseFormalParameterList", "(a, [b], [c])", [ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS]); + ParserTestCase.parse4("parseFormalParameterList", "(a, [b], [c])", [ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS]); } void test_multipleVariablesInForEach() { - ParserTestCase.parse5("parseForStatement", "for (int a, b in foo) {}", [ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH]); + ParserTestCase.parse4("parseForStatement", "for (int a, b in foo) {}", [ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH]); } void test_multipleWithClauses() { @@ -10406,15 +10492,15 @@ class ErrorParserTest extends ParserTestCase { } void test_namedParameterOutsideGroup() { - ParserTestCase.parse5("parseFormalParameterList", "(a, b : 0)", [ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP]); + ParserTestCase.parse4("parseFormalParameterList", "(a, b : 0)", [ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP]); } void test_nonConstructorFactory_field() { - ParserTestCase.parse4("parseClassMember", ["C"], "factory int x;", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]); + ParserTestCase.parse3("parseClassMember", ["C"], "factory int x;", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]); } void test_nonConstructorFactory_method() { - ParserTestCase.parse4("parseClassMember", ["C"], "factory int m() {}", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]); + ParserTestCase.parse3("parseClassMember", ["C"], "factory int m() {}", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]); } void test_nonIdentifierLibraryName_library() { @@ -10436,7 +10522,7 @@ class ErrorParserTest extends ParserTestCase { } void test_nonUserDefinableOperator() { - ParserTestCase.parse4("parseClassMember", ["C"], "operator +=(int x) => x + 1;", [ParserErrorCode.NON_USER_DEFINABLE_OPERATOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "operator +=(int x) => x + 1;", [ParserErrorCode.NON_USER_DEFINABLE_OPERATOR]); } void test_optionalAfterNormalParameters_named() { @@ -10448,22 +10534,22 @@ class ErrorParserTest extends ParserTestCase { } void test_parseCascadeSection_missingIdentifier() { - MethodInvocation methodInvocation = ParserTestCase.parse5("parseCascadeSection", "..()", [ParserErrorCode.MISSING_IDENTIFIER]); + MethodInvocation methodInvocation = ParserTestCase.parse4("parseCascadeSection", "..()", [ParserErrorCode.MISSING_IDENTIFIER]); JUnitTestCase.assertNull(methodInvocation.target); JUnitTestCase.assertEquals("", methodInvocation.methodName.name); EngineTestCase.assertSize(0, methodInvocation.argumentList.arguments); } void test_positionalAfterNamedArgument() { - ParserTestCase.parse5("parseArgumentList", "(x: 1, 2)", [ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT]); + ParserTestCase.parse4("parseArgumentList", "(x: 1, 2)", [ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT]); } void test_positionalParameterOutsideGroup() { - ParserTestCase.parse5("parseFormalParameterList", "(a, b = 0)", [ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP]); + ParserTestCase.parse4("parseFormalParameterList", "(a, b = 0)", [ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP]); } void test_redirectionInNonFactoryConstructor() { - ParserTestCase.parse4("parseClassMember", ["C"], "C() = D;", [ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "C() = D;", [ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR]); } void test_setterInFunction_block() { @@ -10475,35 +10561,35 @@ class ErrorParserTest extends ParserTestCase { } void test_staticAfterConst() { - ParserTestCase.parse4("parseClassMember", ["C"], "final static int f;", [ParserErrorCode.STATIC_AFTER_FINAL]); + ParserTestCase.parse3("parseClassMember", ["C"], "final static int f;", [ParserErrorCode.STATIC_AFTER_FINAL]); } void test_staticAfterFinal() { - ParserTestCase.parse4("parseClassMember", ["C"], "const static int f;", [ParserErrorCode.STATIC_AFTER_CONST]); + ParserTestCase.parse3("parseClassMember", ["C"], "const static int f;", [ParserErrorCode.STATIC_AFTER_CONST]); } void test_staticAfterVar() { - ParserTestCase.parse4("parseClassMember", ["C"], "var static f;", [ParserErrorCode.STATIC_AFTER_VAR]); + ParserTestCase.parse3("parseClassMember", ["C"], "var static f;", [ParserErrorCode.STATIC_AFTER_VAR]); } void test_staticConstructor() { - ParserTestCase.parse4("parseClassMember", ["C"], "static C.m() {}", [ParserErrorCode.STATIC_CONSTRUCTOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "static C.m() {}", [ParserErrorCode.STATIC_CONSTRUCTOR]); } void test_staticGetterWithoutBody() { - ParserTestCase.parse4("parseClassMember", ["C"], "static get m;", [ParserErrorCode.STATIC_GETTER_WITHOUT_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "static get m;", [ParserErrorCode.STATIC_GETTER_WITHOUT_BODY]); } void test_staticOperator_noReturnType() { - ParserTestCase.parse4("parseClassMember", ["C"], "static operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "static operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]); } void test_staticOperator_returnType() { - ParserTestCase.parse4("parseClassMember", ["C"], "static int operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]); + ParserTestCase.parse3("parseClassMember", ["C"], "static int operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]); } void test_staticSetterWithoutBody() { - ParserTestCase.parse4("parseClassMember", ["C"], "static set m(x);", [ParserErrorCode.STATIC_SETTER_WITHOUT_BODY]); + ParserTestCase.parse3("parseClassMember", ["C"], "static set m(x);", [ParserErrorCode.STATIC_SETTER_WITHOUT_BODY]); } void test_staticTopLevelDeclaration_class() { @@ -10523,47 +10609,47 @@ class ErrorParserTest extends ParserTestCase { } void test_switchHasCaseAfterDefaultCase() { - ParserTestCase.parse5("parseSwitchStatement", "switch (a) {default: return 0; case 1: return 1;}", [ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE]); + ParserTestCase.parse4("parseSwitchStatement", "switch (a) {default: return 0; case 1: return 1;}", [ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE]); } void test_switchHasCaseAfterDefaultCase_repeated() { - ParserTestCase.parse5("parseSwitchStatement", "switch (a) {default: return 0; case 1: return 1; case 2: return 2;}", [ + ParserTestCase.parse4("parseSwitchStatement", "switch (a) {default: return 0; case 1: return 1; case 2: return 2;}", [ ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE, ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE]); } void test_switchHasMultipleDefaultCases() { - ParserTestCase.parse5("parseSwitchStatement", "switch (a) {default: return 0; default: return 1;}", [ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES]); + ParserTestCase.parse4("parseSwitchStatement", "switch (a) {default: return 0; default: return 1;}", [ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES]); } void test_switchHasMultipleDefaultCases_repeated() { - ParserTestCase.parse5("parseSwitchStatement", "switch (a) {default: return 0; default: return 1; default: return 2;}", [ + ParserTestCase.parse4("parseSwitchStatement", "switch (a) {default: return 0; default: return 1; default: return 2;}", [ ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES]); } void test_topLevelOperator_withoutType() { - ParserTestCase.parse4("parseCompilationUnitMember", [emptyCommentAndMetadata()], "operator +(bool x, bool y) => x | y;", [ParserErrorCode.TOP_LEVEL_OPERATOR]); + ParserTestCase.parse3("parseCompilationUnitMember", [emptyCommentAndMetadata()], "operator +(bool x, bool y) => x | y;", [ParserErrorCode.TOP_LEVEL_OPERATOR]); } void test_topLevelOperator_withType() { - ParserTestCase.parse4("parseCompilationUnitMember", [emptyCommentAndMetadata()], "bool operator +(bool x, bool y) => x | y;", [ParserErrorCode.TOP_LEVEL_OPERATOR]); + ParserTestCase.parse3("parseCompilationUnitMember", [emptyCommentAndMetadata()], "bool operator +(bool x, bool y) => x | y;", [ParserErrorCode.TOP_LEVEL_OPERATOR]); } void test_topLevelOperator_withVoid() { - ParserTestCase.parse4("parseCompilationUnitMember", [emptyCommentAndMetadata()], "void operator +(bool x, bool y) => x | y;", [ParserErrorCode.TOP_LEVEL_OPERATOR]); + ParserTestCase.parse3("parseCompilationUnitMember", [emptyCommentAndMetadata()], "void operator +(bool x, bool y) => x | y;", [ParserErrorCode.TOP_LEVEL_OPERATOR]); } void test_unexpectedTerminatorForParameterGroup_named() { - ParserTestCase.parse5("parseFormalParameterList", "(a, b})", [ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP]); + ParserTestCase.parse4("parseFormalParameterList", "(a, b})", [ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP]); } void test_unexpectedTerminatorForParameterGroup_optional() { - ParserTestCase.parse5("parseFormalParameterList", "(a, b])", [ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP]); + ParserTestCase.parse4("parseFormalParameterList", "(a, b])", [ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP]); } void test_unexpectedToken_semicolonBetweenClassMembers() { - ParserTestCase.parse4("parseClassDeclaration", [emptyCommentAndMetadata(), null], "class C { int x; ; int y;}", [ParserErrorCode.UNEXPECTED_TOKEN]); + ParserTestCase.parse3("parseClassDeclaration", [emptyCommentAndMetadata(), null], "class C { int x; ; int y;}", [ParserErrorCode.UNEXPECTED_TOKEN]); } void test_unexpectedToken_semicolonBetweenCompilationUnitMembers() { @@ -10571,7 +10657,7 @@ class ErrorParserTest extends ParserTestCase { } void test_useOfUnaryPlusOperator() { - SimpleIdentifier expression = ParserTestCase.parse5("parseUnaryExpression", "+x", [ParserErrorCode.MISSING_IDENTIFIER]); + SimpleIdentifier expression = ParserTestCase.parse4("parseUnaryExpression", "+x", [ParserErrorCode.MISSING_IDENTIFIER]); EngineTestCase.assertInstanceOf(SimpleIdentifier, expression); JUnitTestCase.assertTrue(expression.isSynthetic); } @@ -10593,7 +10679,7 @@ class ErrorParserTest extends ParserTestCase { } void test_varReturnType() { - ParserTestCase.parse4("parseClassMember", ["C"], "var m() {}", [ParserErrorCode.VAR_RETURN_TYPE]); + ParserTestCase.parse3("parseClassMember", ["C"], "var m() {}", [ParserErrorCode.VAR_RETURN_TYPE]); } void test_varTypedef() { @@ -10601,15 +10687,15 @@ class ErrorParserTest extends ParserTestCase { } void test_voidParameter() { - ParserTestCase.parse5("parseNormalFormalParameter", "void a)", [ParserErrorCode.VOID_PARAMETER]); + ParserTestCase.parse4("parseNormalFormalParameter", "void a)", [ParserErrorCode.VOID_PARAMETER]); } void test_voidVariable_parseClassMember_initializer() { - ParserTestCase.parse4("parseClassMember", ["C"], "void x = 0;", [ParserErrorCode.VOID_VARIABLE]); + ParserTestCase.parse3("parseClassMember", ["C"], "void x = 0;", [ParserErrorCode.VOID_VARIABLE]); } void test_voidVariable_parseClassMember_noInitializer() { - ParserTestCase.parse4("parseClassMember", ["C"], "void x;", [ParserErrorCode.VOID_VARIABLE]); + ParserTestCase.parse3("parseClassMember", ["C"], "void x;", [ParserErrorCode.VOID_VARIABLE]); } void test_voidVariable_parseCompilationUnit_initializer() { @@ -10621,11 +10707,11 @@ class ErrorParserTest extends ParserTestCase { } void test_voidVariable_parseCompilationUnitMember_initializer() { - ParserTestCase.parse4("parseCompilationUnitMember", [emptyCommentAndMetadata()], "void a = 0;", [ParserErrorCode.VOID_VARIABLE]); + ParserTestCase.parse3("parseCompilationUnitMember", [emptyCommentAndMetadata()], "void a = 0;", [ParserErrorCode.VOID_VARIABLE]); } void test_voidVariable_parseCompilationUnitMember_noInitializer() { - ParserTestCase.parse4("parseCompilationUnitMember", [emptyCommentAndMetadata()], "void a;", [ParserErrorCode.VOID_VARIABLE]); + ParserTestCase.parse3("parseCompilationUnitMember", [emptyCommentAndMetadata()], "void a;", [ParserErrorCode.VOID_VARIABLE]); } void test_voidVariable_statement_initializer() { @@ -10645,23 +10731,23 @@ class ErrorParserTest extends ParserTestCase { } void test_withWithoutExtends() { - ParserTestCase.parse4("parseClassDeclaration", [emptyCommentAndMetadata(), null], "class A with B, C {}", [ParserErrorCode.WITH_WITHOUT_EXTENDS]); + ParserTestCase.parse3("parseClassDeclaration", [emptyCommentAndMetadata(), null], "class A with B, C {}", [ParserErrorCode.WITH_WITHOUT_EXTENDS]); } void test_wrongSeparatorForNamedParameter() { - ParserTestCase.parse5("parseFormalParameterList", "(a, {b = 0})", [ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER]); + ParserTestCase.parse4("parseFormalParameterList", "(a, {b = 0})", [ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER]); } void test_wrongSeparatorForPositionalParameter() { - ParserTestCase.parse5("parseFormalParameterList", "(a, [b : 0])", [ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER]); + ParserTestCase.parse4("parseFormalParameterList", "(a, [b : 0])", [ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER]); } void test_wrongTerminatorForParameterGroup_named() { - ParserTestCase.parse5("parseFormalParameterList", "(a, {b, c])", [ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP]); + ParserTestCase.parse4("parseFormalParameterList", "(a, {b, c])", [ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP]); } void test_wrongTerminatorForParameterGroup_optional() { - ParserTestCase.parse5("parseFormalParameterList", "(a, [b, c})", [ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP]); + ParserTestCase.parse4("parseFormalParameterList", "(a, [b, c})", [ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP]); } static dartSuite() { @@ -10930,10 +11016,18 @@ class ErrorParserTest extends ParserTestCase { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_expectedToken_semicolonAfterClass); }); + _ut.test('test_expectedToken_semicolonMissingAfterExport', () { + final __test = new ErrorParserTest(); + runJUnitTest(__test, __test.test_expectedToken_semicolonMissingAfterExport); + }); _ut.test('test_expectedToken_semicolonMissingAfterExpression', () { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_expectedToken_semicolonMissingAfterExpression); }); + _ut.test('test_expectedToken_semicolonMissingAfterImport', () { + final __test = new ErrorParserTest(); + runJUnitTest(__test, __test.test_expectedToken_semicolonMissingAfterImport); + }); _ut.test('test_expectedToken_whileMissingInDoStatement', () { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_expectedToken_whileMissingInDoStatement); @@ -11070,6 +11164,22 @@ class ErrorParserTest extends ParserTestCase { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_getterWithParameters); }); + _ut.test('test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal', () { + final __test = new ErrorParserTest(); + runJUnitTest(__test, __test.test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal); + }); + _ut.test('test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal', () { + final __test = new ErrorParserTest(); + runJUnitTest(__test, __test.test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal); + }); + _ut.test('test_illegalAssignmentToNonAssignable_postfix_plusPlus_parethesized', () { + final __test = new ErrorParserTest(); + runJUnitTest(__test, __test.test_illegalAssignmentToNonAssignable_postfix_plusPlus_parethesized); + }); + _ut.test('test_illegalAssignmentToNonAssignable_primarySelectorPostfix', () { + final __test = new ErrorParserTest(); + runJUnitTest(__test, __test.test_illegalAssignmentToNonAssignable_primarySelectorPostfix); + }); _ut.test('test_illegalAssignmentToNonAssignable_superAssigned', () { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_illegalAssignmentToNonAssignable_superAssigned); @@ -11166,14 +11276,6 @@ class ErrorParserTest extends ParserTestCase { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_missingAssignableSelector_identifiersAssigned); }); - _ut.test('test_missingAssignableSelector_postfix_minusMinus_literal', () { - final __test = new ErrorParserTest(); - runJUnitTest(__test, __test.test_missingAssignableSelector_postfix_minusMinus_literal); - }); - _ut.test('test_missingAssignableSelector_postfix_plusPlus_literal', () { - final __test = new ErrorParserTest(); - runJUnitTest(__test, __test.test_missingAssignableSelector_postfix_plusPlus_literal); - }); _ut.test('test_missingAssignableSelector_prefix_minusMinus_literal', () { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_missingAssignableSelector_prefix_minusMinus_literal); @@ -11182,10 +11284,6 @@ class ErrorParserTest extends ParserTestCase { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_missingAssignableSelector_prefix_plusPlus_literal); }); - _ut.test('test_missingAssignableSelector_primarySelectorPostfix', () { - final __test = new ErrorParserTest(); - runJUnitTest(__test, __test.test_missingAssignableSelector_primarySelectorPostfix); - }); _ut.test('test_missingAssignableSelector_selector', () { final __test = new ErrorParserTest(); runJUnitTest(__test, __test.test_missingAssignableSelector_selector); @@ -11676,6 +11774,7 @@ Map _methodTable_Parser = { 'createSyntheticToken_1': new MethodTrampoline(1, (Parser target, arg0) => target.createSyntheticToken(arg0)), 'ensureAssignable_1': new MethodTrampoline(1, (Parser target, arg0) => target.ensureAssignable(arg0)), 'expect_1': new MethodTrampoline(1, (Parser target, arg0) => target.expect(arg0)), + 'expectSemicolon_0': new MethodTrampoline(0, (Parser target) => target.expectSemicolon()), 'findRange_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.findRange(arg0, arg1)), 'getCodeBlockRanges_1': new MethodTrampoline(1, (Parser target, arg0) => target.getCodeBlockRanges(arg0)), 'getEndToken_1': new MethodTrampoline(1, (Parser target, arg0) => target.getEndToken(arg0)), diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart index 878187ab5c3..c388ffa5413 100644 --- a/pkg/analyzer/test/generated/resolver_test.dart +++ b/pkg/analyzer/test/generated/resolver_test.dart @@ -17,6 +17,7 @@ import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; import 'package:analyzer/src/generated/element.dart'; import 'package:analyzer/src/generated/resolver.dart'; import 'package:analyzer/src/generated/engine.dart'; +import 'package:analyzer/src/generated/utilities_dart.dart'; import 'package:analyzer/src/generated/java_engine_io.dart'; import 'package:analyzer/src/generated/sdk.dart' show DartSdk; import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk; @@ -1695,6 +1696,20 @@ class NonErrorResolverTest extends ResolverTestCase { verify([source]); } + void test_extraPositionalArguments_implicitConstructor() { + Source source = addSource(EngineTestCase.createSource([ + "class A {", + " A(E x, E y);", + "}", + "class B = A;", + "void main() {", + " B x = new B(0,0);", + "}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + void test_extraPositionalArguments_typedef_local() { Source source = addSource(EngineTestCase.createSource([ "typedef A(p1, p2);", @@ -2941,6 +2956,52 @@ class NonErrorResolverTest extends ResolverTestCase { verify([source]); } + void test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter() { + // 17034 + Source source = addSource(EngineTestCase.createSource([ + "class A {", + " var a;", + "}", + "abstract class M {", + " get a;", + "}", + "class B extends A with M {}", + "class C extends B {}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + + void test_nonAbstractClassInheritsAbstractMemberOne_mixin_method() { + Source source = addSource(EngineTestCase.createSource([ + "class A {", + " m() {}", + "}", + "abstract class M {", + " m();", + "}", + "class B extends A with M {}", + "class C extends B {}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + + void test_nonAbstractClassInheritsAbstractMemberOne_mixin_setter() { + Source source = addSource(EngineTestCase.createSource([ + "class A {", + " var a;", + "}", + "abstract class M {", + " set a(dynamic v);", + "}", + "class B extends A with M {}", + "class C extends B {}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + void test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor() { Source source = addSource(EngineTestCase.createSource([ "abstract class A {", @@ -3469,6 +3530,73 @@ class NonErrorResolverTest extends ResolverTestCase { assertNoErrors(source); } + void test_proxy_annotation_superclass() { + Source source = addSource(EngineTestCase.createSource([ + "library L;", + "class B extends A {", + " m() {", + " n();", + " var x = g;", + " s = 1;", + " var y = this + this;", + " }", + "}", + "@proxy", + "class A {}"])); + resolve(source); + assertNoErrors(source); + } + + void test_proxy_annotation_superclass_mixin() { + Source source = addSource(EngineTestCase.createSource([ + "library L;", + "class B extends Object with A {", + " m() {", + " n();", + " var x = g;", + " s = 1;", + " var y = this + this;", + " }", + "}", + "@proxy", + "class A {}"])); + resolve(source); + assertNoErrors(source); + } + + void test_proxy_annotation_superinterface() { + Source source = addSource(EngineTestCase.createSource([ + "library L;", + "class B implements A {", + " m() {", + " n();", + " var x = g;", + " s = 1;", + " var y = this + this;", + " }", + "}", + "@proxy", + "class A {}"])); + resolve(source); + assertNoErrors(source); + } + + void test_proxy_annotation_superinterface_infiniteLoop() { + Source source = addSource(EngineTestCase.createSource([ + "library L;", + "class C implements A {", + " m() {", + " n();", + " var x = g;", + " s = 1;", + " var y = this + this;", + " }", + "}", + "class B implements A{}", + "class A implements B{}"])); + resolve(source); + } + void test_recursiveConstructorRedirect() { Source source = addSource(EngineTestCase.createSource([ "class A {", @@ -4672,6 +4800,10 @@ class NonErrorResolverTest extends ResolverTestCase { final __test = new NonErrorResolverTest(); runJUnitTest(__test, __test.test_extraPositionalArguments_function); }); + _ut.test('test_extraPositionalArguments_implicitConstructor', () { + final __test = new NonErrorResolverTest(); + runJUnitTest(__test, __test.test_extraPositionalArguments_implicitConstructor); + }); _ut.test('test_extraPositionalArguments_typedef_local', () { final __test = new NonErrorResolverTest(); runJUnitTest(__test, __test.test_extraPositionalArguments_typedef_local); @@ -5132,6 +5264,18 @@ class NonErrorResolverTest extends ResolverTestCase { final __test = new NonErrorResolverTest(); runJUnitTest(__test, __test.test_newWithUndefinedConstructorDefault); }); + _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter', () { + final __test = new NonErrorResolverTest(); + runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter); + }); + _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_mixin_method', () { + final __test = new NonErrorResolverTest(); + runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_mixin_method); + }); + _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_mixin_setter', () { + final __test = new NonErrorResolverTest(); + runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_mixin_setter); + }); _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor', () { final __test = new NonErrorResolverTest(); runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor); @@ -5312,6 +5456,22 @@ class NonErrorResolverTest extends ResolverTestCase { final __test = new NonErrorResolverTest(); runJUnitTest(__test, __test.test_proxy_annotation_simple); }); + _ut.test('test_proxy_annotation_superclass', () { + final __test = new NonErrorResolverTest(); + runJUnitTest(__test, __test.test_proxy_annotation_superclass); + }); + _ut.test('test_proxy_annotation_superclass_mixin', () { + final __test = new NonErrorResolverTest(); + runJUnitTest(__test, __test.test_proxy_annotation_superclass_mixin); + }); + _ut.test('test_proxy_annotation_superinterface', () { + final __test = new NonErrorResolverTest(); + runJUnitTest(__test, __test.test_proxy_annotation_superinterface); + }); + _ut.test('test_proxy_annotation_superinterface_infiniteLoop', () { + final __test = new NonErrorResolverTest(); + runJUnitTest(__test, __test.test_proxy_annotation_superinterface_infiniteLoop); + }); _ut.test('test_recursiveConstructorRedirect', () { final __test = new NonErrorResolverTest(); runJUnitTest(__test, __test.test_recursiveConstructorRedirect); @@ -5654,7 +5814,7 @@ class LibraryTest extends EngineTestCase { Library _library5; void setUp() { - _sourceFactory = new SourceFactory.con2([new FileUriResolver()]); + _sourceFactory = new SourceFactory([new FileUriResolver()]); _analysisContext = new AnalysisContextImpl(); _analysisContext.sourceFactory = _sourceFactory; _errorListener = new GatheringErrorListener(); @@ -5725,7 +5885,7 @@ class LibraryTest extends EngineTestCase { JUnitTestCase.assertSame(element, _library5.libraryElement); } - Library library(String definingCompilationUnitPath) => new Library(_analysisContext, _errorListener, new FileBasedSource.con1(_sourceFactory.contentCache, FileUtilities2.createFile(definingCompilationUnitPath))); + Library library(String definingCompilationUnitPath) => new Library(_analysisContext, _errorListener, new FileBasedSource.con1(FileUtilities2.createFile(definingCompilationUnitPath))); static dartSuite() { _ut.group('LibraryTest', () { @@ -6969,6 +7129,13 @@ class StaticTypeWarningCodeTest extends ResolverTestCase { verify([source]); } + void test_wrongNumberOfTypeArguments_classAlias() { + Source source = addSource(EngineTestCase.createSource(["class A {}", "class B = A;"])); + resolve(source); + assertErrors(source, [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]); + verify([source]); + } + void test_wrongNumberOfTypeArguments_tooFew() { Source source = addSource(EngineTestCase.createSource(["class A {}", "A a = null;"])); resolve(source); @@ -7409,6 +7576,10 @@ class StaticTypeWarningCodeTest extends ResolverTestCase { final __test = new StaticTypeWarningCodeTest(); runJUnitTest(__test, __test.test_unqualifiedReferenceToNonLocalStaticMember_setter); }); + _ut.test('test_wrongNumberOfTypeArguments_classAlias', () { + final __test = new StaticTypeWarningCodeTest(); + runJUnitTest(__test, __test.test_wrongNumberOfTypeArguments_classAlias); + }); _ut.test('test_wrongNumberOfTypeArguments_tooFew', () { final __test = new StaticTypeWarningCodeTest(); runJUnitTest(__test, __test.test_wrongNumberOfTypeArguments_tooFew); @@ -8017,6 +8188,51 @@ class HintCodeTest extends ResolverTestCase { verify([source]); } + void test_overrideOnNonOverridingGetter_invalid() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + "}", + "class B extends A {", + " @override", + " int get m => 1;", + "}"])); + resolve(source); + assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]); + verify([source]); + } + + void test_overrideOnNonOverridingMethod_invalid() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + "}", + "class B extends A {", + " @override", + " int m() => 1;", + "}"])); + resolve(source); + assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]); + verify([source]); + } + + void test_overrideOnNonOverridingSetter_invalid() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + "}", + "class B extends A {", + " @override", + " set m(int x) {}", + "}"])); + resolve(source); + assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]); + verify([source]); + } + void test_typeCheck_type_is_Null() { Source source = addSource(EngineTestCase.createSource(["m(i) {", " bool b = i is Null;", "}"])); resolve(source); @@ -8541,6 +8757,18 @@ class HintCodeTest extends ResolverTestCase { final __test = new HintCodeTest(); runJUnitTest(__test, __test.test_missingReturn_method); }); + _ut.test('test_overrideOnNonOverridingGetter_invalid', () { + final __test = new HintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingGetter_invalid); + }); + _ut.test('test_overrideOnNonOverridingMethod_invalid', () { + final __test = new HintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingMethod_invalid); + }); + _ut.test('test_overrideOnNonOverridingSetter_invalid', () { + final __test = new HintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingSetter_invalid); + }); _ut.test('test_typeCheck_type_is_Null', () { final __test = new HintCodeTest(); runJUnitTest(__test, __test.test_typeCheck_type_is_Null); @@ -8732,10 +8960,10 @@ class TypeResolverVisitorTest extends EngineTestCase { void setUp() { _listener = new GatheringErrorListener(); - SourceFactory factory = new SourceFactory.con2([new FileUriResolver()]); + SourceFactory factory = new SourceFactory([new FileUriResolver()]); AnalysisContextImpl context = new AnalysisContextImpl(); context.sourceFactory = factory; - Source librarySource = new FileBasedSource.con1(factory.contentCache, FileUtilities2.createFile("/lib.dart")); + Source librarySource = new FileBasedSource.con1(FileUtilities2.createFile("/lib.dart")); _library = new Library(context, _listener, librarySource); LibraryElementImpl element = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2(["lib"])); element.definingCompilationUnit = new CompilationUnitElementImpl("lib.dart"); @@ -9051,11 +9279,6 @@ class TypeResolverVisitorTest extends EngineTestCase { } class ResolverTestCase extends EngineTestCase { - /** - * The source factory used to create [Source]. - */ - SourceFactory _sourceFactory; - /** * The analysis context used to parse the compilation units being resolved. */ @@ -9127,8 +9350,8 @@ class ResolverTestCase extends EngineTestCase { * @return the source object representing the cached file */ Source cacheSource(String filePath, String contents) { - Source source = new FileBasedSource.con1(_sourceFactory.contentCache, FileUtilities2.createFile(filePath)); - _sourceFactory.setContents(source, contents); + Source source = new FileBasedSource.con1(FileUtilities2.createFile(filePath)); + _analysisContext.setContents(source, contents); return source; } @@ -9170,8 +9393,6 @@ class ResolverTestCase extends EngineTestCase { AnalysisContext get analysisContext => _analysisContext; - SourceFactory get sourceFactory => _sourceFactory; - /** * Return a type provider that can be used to test the results of resolution. * @@ -9186,7 +9407,6 @@ class ResolverTestCase extends EngineTestCase { */ void reset() { _analysisContext = AnalysisContextFactory.contextWithCore(); - _sourceFactory = _analysisContext.sourceFactory; } /** @@ -9234,8 +9454,8 @@ class ResolverTestCase extends EngineTestCase { * @return the source that was created */ FileBasedSource createSource2(String fileName) { - FileBasedSource source = new FileBasedSource.con1(_sourceFactory.contentCache, FileUtilities2.createFile(fileName)); - _sourceFactory.setContents(source, ""); + FileBasedSource source = new FileBasedSource.con1(FileUtilities2.createFile(fileName)); + _analysisContext.setContents(source, ""); return source; } @@ -9358,6 +9578,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromClasses_accessor_extends() { + // class A { int get g; } + // class B extends A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String getterName = "g"; PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, _typeProvider.intType); @@ -9373,6 +9595,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromClasses_accessor_implements() { + // class A { int get g; } + // class B implements A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String getterName = "g"; PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, _typeProvider.intType); @@ -9389,6 +9613,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromClasses_accessor_with() { + // class A { int get g; } + // class B extends Object with A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String getterName = "g"; PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, _typeProvider.intType); @@ -9404,7 +9630,17 @@ class InheritanceManagerTest extends EngineTestCase { assertNoErrors(classB); } + void test_getMapOfMembersInheritedFromClasses_implicitExtends() { + // class A {} + ClassElementImpl classA = ElementFactory.classElement2("A", []); + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromClasses(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject, mapA.size); + assertNoErrors(classA); + } + void test_getMapOfMembersInheritedFromClasses_method_extends() { + // class A { int g(); } + // class B extends A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String methodName = "m"; MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); @@ -9421,6 +9657,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromClasses_method_implements() { + // class A { int g(); } + // class B implements A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String methodName = "m"; MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); @@ -9437,6 +9675,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromClasses_method_with() { + // class A { int g(); } + // class B extends Object with A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String methodName = "m"; MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); @@ -9453,6 +9693,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromInterfaces_accessor_extends() { + // class A { int get g; } + // class B extends A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String getterName = "g"; PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, _typeProvider.intType); @@ -9468,6 +9710,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromInterfaces_accessor_implements() { + // class A { int get g; } + // class B implements A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String getterName = "g"; PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, _typeProvider.intType); @@ -9484,6 +9728,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromInterfaces_accessor_with() { + // class A { int get g; } + // class B extends Object with A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String getterName = "g"; PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, _typeProvider.intType); @@ -9499,7 +9745,129 @@ class InheritanceManagerTest extends EngineTestCase { assertNoErrors(classB); } + void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() { + // class A {} + ClassElementImpl classA = ElementFactory.classElement2("A", []); + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject, mapA.size); + assertNoErrors(classA); + } + + void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() { + // class I1 { int m(); } + // class I2 { int get m; } + // class A implements I2, I1 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + classI1.methods = [methodM]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + PropertyAccessorElement getter = ElementFactory.getterElement(methodName, false, _typeProvider.intType); + classI2.accessors = [getter]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI2.type, classI1.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject, mapA.size); + JUnitTestCase.assertNull(mapA.get(methodName)); + assertErrors(classA, [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]); + } + + void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() { + // class I1 { int m(); } + // class I2 { String m(); } + // class A implements I1, I2 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElement methodM1 = ElementFactory.methodElement(methodName, null, [_typeProvider.intType]); + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + MethodElement methodM2 = ElementFactory.methodElement(methodName, null, [_typeProvider.stringType]); + classI2.methods = [methodM2]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject, mapA.size); + JUnitTestCase.assertNull(mapA.get(methodName)); + assertErrors(classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); + } + + void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() { + // class I1 { int m(); } + // class I2 { int get m; } + // class A implements I1, I2 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + classI1.methods = [methodM]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + PropertyAccessorElement getter = ElementFactory.getterElement(methodName, false, _typeProvider.intType); + classI2.accessors = [getter]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject, mapA.size); + JUnitTestCase.assertNull(mapA.get(methodName)); + assertErrors(classA, [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]); + } + + void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() { + // class I1 { dynamic m(int, [int]); } + // class I2 { dynamic m(int, int, int); } + // class A implements I1, I2 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElementImpl methodM1 = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, []); + ParameterElementImpl parameter1 = new ParameterElementImpl.con1(ASTFactory.identifier3("a1")); + parameter1.type = _typeProvider.intType; + parameter1.parameterKind = ParameterKind.REQUIRED; + ParameterElementImpl parameter2 = new ParameterElementImpl.con1(ASTFactory.identifier3("a2")); + parameter2.type = _typeProvider.intType; + parameter2.parameterKind = ParameterKind.POSITIONAL; + methodM1.parameters = [parameter1, parameter2]; + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + MethodElementImpl methodM2 = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, []); + ParameterElementImpl parameter3 = new ParameterElementImpl.con1(ASTFactory.identifier3("a3")); + parameter3.type = _typeProvider.intType; + parameter3.parameterKind = ParameterKind.REQUIRED; + ParameterElementImpl parameter4 = new ParameterElementImpl.con1(ASTFactory.identifier3("a4")); + parameter4.type = _typeProvider.intType; + parameter4.parameterKind = ParameterKind.REQUIRED; + ParameterElementImpl parameter5 = new ParameterElementImpl.con1(ASTFactory.identifier3("a5")); + parameter5.type = _typeProvider.intType; + parameter5.parameterKind = ParameterKind.REQUIRED; + methodM2.parameters = [parameter3, parameter4, parameter5]; + classI2.methods = [methodM2]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject, mapA.size); + JUnitTestCase.assertNull(mapA.get(methodName)); + assertErrors(classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); + } + + void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() { + // class I1 { int m(); } + // class I2 { String m(); } + // class A implements I2, I1 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElement methodM1 = ElementFactory.methodElement(methodName, null, [_typeProvider.stringType]); + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + MethodElement methodM2 = ElementFactory.methodElement(methodName, null, [_typeProvider.intType]); + classI2.methods = [methodM2]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI2.type, classI1.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject, mapA.size); + JUnitTestCase.assertNull(mapA.get(methodName)); + assertErrors(classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); + } + void test_getMapOfMembersInheritedFromInterfaces_method_extends() { + // class A { int g(); } + // class B extends A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String methodName = "m"; MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); @@ -9515,6 +9883,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromInterfaces_method_implements() { + // class A { int g(); } + // class B implements A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String methodName = "m"; MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); @@ -9531,6 +9901,8 @@ class InheritanceManagerTest extends EngineTestCase { } void test_getMapOfMembersInheritedFromInterfaces_method_with() { + // class A { int g(); } + // class B extends Object with A {} ClassElementImpl classA = ElementFactory.classElement2("A", []); String methodName = "m"; MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); @@ -9546,6 +9918,294 @@ class InheritanceManagerTest extends EngineTestCase { assertNoErrors(classB); } + void test_getMapOfMembersInheritedFromInterfaces_union_differentNames() { + // class I1 { int m1(); } + // class I2 { int m2(); } + // class A implements I1, I2 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName1 = "m1"; + MethodElement methodM1 = ElementFactory.methodElement(methodName1, _typeProvider.intType, []); + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + String methodName2 = "m2"; + MethodElement methodM2 = ElementFactory.methodElement(methodName2, _typeProvider.intType, []); + classI2.methods = [methodM2]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject + 2, mapA.size); + JUnitTestCase.assertSame(methodM1, mapA.get(methodName1)); + JUnitTestCase.assertSame(methodM2, mapA.get(methodName2)); + assertNoErrors(classA); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() { + // class I1 { int get g; } + // class I2 { num get g; } + // class A implements I1, I2 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String accessorName = "g"; + PropertyAccessorElement getter1 = ElementFactory.getterElement(accessorName, false, _typeProvider.intType); + classI1.accessors = [getter1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + PropertyAccessorElement getter2 = ElementFactory.getterElement(accessorName, false, _typeProvider.numType); + classI2.accessors = [getter2]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapA.size); + PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(accessorName, false, _typeProvider.dynamicType); + JUnitTestCase.assertEquals(syntheticAccessor.type, mapA.get(accessorName).type); + assertNoErrors(classA); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() { + // class I1 { dynamic m(int); } + // class I2 { dynamic m(num); } + // class A implements I1, I2 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElementImpl methodM1 = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, []); + ParameterElementImpl parameter1 = new ParameterElementImpl.con1(ASTFactory.identifier3("a0")); + parameter1.type = _typeProvider.intType; + parameter1.parameterKind = ParameterKind.REQUIRED; + methodM1.parameters = [parameter1]; + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + MethodElementImpl methodM2 = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, []); + ParameterElementImpl parameter2 = new ParameterElementImpl.con1(ASTFactory.identifier3("a0")); + parameter2.type = _typeProvider.numType; + parameter2.parameterKind = ParameterKind.REQUIRED; + methodM2.parameters = [parameter2]; + classI2.methods = [methodM2]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapA.size); + MethodElement syntheticMethod = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]); + JUnitTestCase.assertEquals(syntheticMethod.type, mapA.get(methodName).type); + assertNoErrors(classA); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() { + // class I1 { set s(int); } + // class I2 { set s(num); } + // class A implements I1, I2 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String accessorName = "s"; + PropertyAccessorElement setter1 = ElementFactory.setterElement(accessorName, false, _typeProvider.intType); + classI1.accessors = [setter1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + PropertyAccessorElement setter2 = ElementFactory.setterElement(accessorName, false, _typeProvider.numType); + classI2.accessors = [setter2]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapA.size); + PropertyAccessorElementImpl syntheticAccessor = ElementFactory.setterElement(accessorName, false, _typeProvider.dynamicType); + syntheticAccessor.returnType = _typeProvider.dynamicType; + JUnitTestCase.assertEquals(syntheticAccessor.type, mapA.get("${accessorName}=").type); + assertNoErrors(classA); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() { + // class A {} + // class B extends A {} + // class C extends B {} + // class I1 { A get g; } + // class I2 { B get g; } + // class I3 { C get g; } + // class D implements I1, I2, I3 {} + ClassElementImpl classA = ElementFactory.classElement2("A", []); + ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []); + ClassElementImpl classC = ElementFactory.classElement("C", classB.type, []); + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String accessorName = "g"; + PropertyAccessorElement getter1 = ElementFactory.getterElement(accessorName, false, classA.type); + classI1.accessors = [getter1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + PropertyAccessorElement getter2 = ElementFactory.getterElement(accessorName, false, classB.type); + classI2.accessors = [getter2]; + ClassElementImpl classI3 = ElementFactory.classElement2("I3", []); + PropertyAccessorElement getter3 = ElementFactory.getterElement(accessorName, false, classC.type); + classI3.accessors = [getter3]; + ClassElementImpl classD = ElementFactory.classElement2("D", []); + classD.interfaces = [classI1.type, classI2.type, classI3.type]; + MemberMap mapD = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapD.size); + PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(accessorName, false, _typeProvider.dynamicType); + JUnitTestCase.assertEquals(syntheticAccessor.type, mapD.get(accessorName).type); + assertNoErrors(classD); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() { + // class A {} + // class B extends A {} + // class C extends B {} + // class I1 { dynamic m(A a); } + // class I2 { dynamic m(B b); } + // class I3 { dynamic m(C c); } + // class D implements I1, I2, I3 {} + ClassElementImpl classA = ElementFactory.classElement2("A", []); + ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []); + ClassElementImpl classC = ElementFactory.classElement("C", classB.type, []); + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElementImpl methodM1 = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, []); + ParameterElementImpl parameter1 = new ParameterElementImpl.con1(ASTFactory.identifier3("a0")); + parameter1.type = classA.type; + parameter1.parameterKind = ParameterKind.REQUIRED; + methodM1.parameters = [parameter1]; + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + MethodElementImpl methodM2 = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, []); + ParameterElementImpl parameter2 = new ParameterElementImpl.con1(ASTFactory.identifier3("a0")); + parameter2.type = classB.type; + parameter2.parameterKind = ParameterKind.REQUIRED; + methodM2.parameters = [parameter2]; + classI2.methods = [methodM2]; + ClassElementImpl classI3 = ElementFactory.classElement2("I3", []); + MethodElementImpl methodM3 = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, []); + ParameterElementImpl parameter3 = new ParameterElementImpl.con1(ASTFactory.identifier3("a0")); + parameter3.type = classC.type; + parameter3.parameterKind = ParameterKind.REQUIRED; + methodM3.parameters = [parameter3]; + classI3.methods = [methodM3]; + ClassElementImpl classD = ElementFactory.classElement2("D", []); + classD.interfaces = [classI1.type, classI2.type, classI3.type]; + MemberMap mapD = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapD.size); + MethodElement syntheticMethod = ElementFactory.methodElement(methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]); + JUnitTestCase.assertEquals(syntheticMethod.type, mapD.get(methodName).type); + assertNoErrors(classD); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() { + // class A {} + // class B extends A {} + // class C extends B {} + // class I1 { set s(A); } + // class I2 { set s(B); } + // class I3 { set s(C); } + // class D implements I1, I2, I3 {} + ClassElementImpl classA = ElementFactory.classElement2("A", []); + ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []); + ClassElementImpl classC = ElementFactory.classElement("C", classB.type, []); + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String accessorName = "s"; + PropertyAccessorElement setter1 = ElementFactory.setterElement(accessorName, false, classA.type); + classI1.accessors = [setter1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + PropertyAccessorElement setter2 = ElementFactory.setterElement(accessorName, false, classB.type); + classI2.accessors = [setter2]; + ClassElementImpl classI3 = ElementFactory.classElement2("I3", []); + PropertyAccessorElement setter3 = ElementFactory.setterElement(accessorName, false, classC.type); + classI3.accessors = [setter3]; + ClassElementImpl classD = ElementFactory.classElement2("D", []); + classD.interfaces = [classI1.type, classI2.type, classI3.type]; + MemberMap mapD = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapD.size); + PropertyAccessorElementImpl syntheticAccessor = ElementFactory.setterElement(accessorName, false, _typeProvider.dynamicType); + syntheticAccessor.returnType = _typeProvider.dynamicType; + JUnitTestCase.assertEquals(syntheticAccessor.type, mapD.get("${accessorName}=").type); + assertNoErrors(classD); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() { + // class I1 { int m(); } + // class I2 { int m([int]); } + // class A implements I1, I2 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElement methodM1 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + MethodElementImpl methodM2 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + ParameterElementImpl parameter1 = new ParameterElementImpl.con1(ASTFactory.identifier3("a1")); + parameter1.type = _typeProvider.intType; + parameter1.parameterKind = ParameterKind.POSITIONAL; + methodM2.parameters = [parameter1]; + classI2.methods = [methodM2]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapA.size); + JUnitTestCase.assertSame(methodM2, mapA.get(methodName)); + assertNoErrors(classA); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() { + // class I1 { int m(); } + // class I2 { int m([int]); } + // class I3 { int m([int, int]); } + // class A implements I1, I2, I3 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElementImpl methodM1 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + MethodElementImpl methodM2 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + ParameterElementImpl parameter1 = new ParameterElementImpl.con1(ASTFactory.identifier3("a1")); + parameter1.type = _typeProvider.intType; + parameter1.parameterKind = ParameterKind.POSITIONAL; + methodM1.parameters = [parameter1]; + classI2.methods = [methodM2]; + ClassElementImpl classI3 = ElementFactory.classElement2("I3", []); + MethodElementImpl methodM3 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + ParameterElementImpl parameter2 = new ParameterElementImpl.con1(ASTFactory.identifier3("a2")); + parameter2.type = _typeProvider.intType; + parameter2.parameterKind = ParameterKind.POSITIONAL; + ParameterElementImpl parameter3 = new ParameterElementImpl.con1(ASTFactory.identifier3("a3")); + parameter3.type = _typeProvider.intType; + parameter3.parameterKind = ParameterKind.POSITIONAL; + methodM3.parameters = [parameter2, parameter3]; + classI3.methods = [methodM3]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type, classI3.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapA.size); + JUnitTestCase.assertSame(methodM3, mapA.get(methodName)); + assertNoErrors(classA); + } + + void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() { + // class I1 { int m(); } + // class I2 { int m(); } + // class I3 { int m([int]); } + // class I4 { int m([int, int]); } + // class A implements I1, I2, I3, I4 {} + ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); + String methodName = "m"; + MethodElement methodM1 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + classI1.methods = [methodM1]; + ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); + MethodElement methodM2 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + classI2.methods = [methodM2]; + ClassElementImpl classI3 = ElementFactory.classElement2("I3", []); + MethodElementImpl methodM3 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + ParameterElementImpl parameter1 = new ParameterElementImpl.con1(ASTFactory.identifier3("a1")); + parameter1.type = _typeProvider.intType; + parameter1.parameterKind = ParameterKind.POSITIONAL; + methodM3.parameters = [parameter1]; + classI3.methods = [methodM3]; + ClassElementImpl classI4 = ElementFactory.classElement2("I4", []); + MethodElementImpl methodM4 = ElementFactory.methodElement(methodName, _typeProvider.intType, []); + ParameterElementImpl parameter2 = new ParameterElementImpl.con1(ASTFactory.identifier3("a2")); + parameter2.type = _typeProvider.intType; + parameter2.parameterKind = ParameterKind.POSITIONAL; + ParameterElementImpl parameter3 = new ParameterElementImpl.con1(ASTFactory.identifier3("a3")); + parameter3.type = _typeProvider.intType; + parameter3.parameterKind = ParameterKind.POSITIONAL; + methodM4.parameters = [parameter2, parameter3]; + classI4.methods = [methodM4]; + ClassElementImpl classA = ElementFactory.classElement2("A", []); + classA.interfaces = [classI1.type, classI2.type, classI3.type, classI4.type]; + MemberMap mapA = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA); + JUnitTestCase.assertEquals(_numOfMembersInObject + 1, mapA.size); + JUnitTestCase.assertSame(methodM4, mapA.get(methodName)); + assertNoErrors(classA); + } + void test_lookupInheritance_interface_getter() { ClassElementImpl classA = ElementFactory.classElement2("A", []); String getterName = "g"; @@ -9612,56 +10272,6 @@ class InheritanceManagerTest extends EngineTestCase { assertNoErrors(classB); } - void test_lookupInheritance_interfaces_STWC_inconsistentMethodInheritance() { - ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); - String methodName = "m"; - MethodElement methodM1 = ElementFactory.methodElement(methodName, null, [_typeProvider.intType]); - classI1.methods = [methodM1]; - ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); - MethodElement methodM2 = ElementFactory.methodElement(methodName, null, [_typeProvider.stringType]); - classI2.methods = [methodM2]; - ClassElementImpl classA = ElementFactory.classElement2("A", []); - classA.interfaces = [classI1.type, classI2.type]; - JUnitTestCase.assertNull(_inheritanceManager.lookupInheritance(classA, methodName)); - assertNoErrors(classI1); - assertNoErrors(classI2); - assertErrors(classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]); - } - - void test_lookupInheritance_interfaces_SWC_inconsistentMethodInheritance() { - ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); - String methodName = "m"; - MethodElement methodM = ElementFactory.methodElement(methodName, _typeProvider.intType, []); - classI1.methods = [methodM]; - ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); - PropertyAccessorElement getter = ElementFactory.getterElement(methodName, false, _typeProvider.intType); - classI2.accessors = [getter]; - ClassElementImpl classA = ElementFactory.classElement2("A", []); - classA.interfaces = [classI1.type, classI2.type]; - JUnitTestCase.assertNull(_inheritanceManager.lookupInheritance(classA, methodName)); - assertNoErrors(classI1); - assertNoErrors(classI2); - assertErrors(classA, [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]); - } - - void test_lookupInheritance_interfaces_union1() { - ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); - String methodName1 = "m1"; - MethodElement methodM1 = ElementFactory.methodElement(methodName1, _typeProvider.intType, []); - classI1.methods = [methodM1]; - ClassElementImpl classI2 = ElementFactory.classElement2("I2", []); - String methodName2 = "m2"; - MethodElement methodM2 = ElementFactory.methodElement(methodName2, _typeProvider.intType, []); - classI2.methods = [methodM2]; - ClassElementImpl classA = ElementFactory.classElement2("A", []); - classA.interfaces = [classI1.type, classI2.type]; - JUnitTestCase.assertSame(methodM1, _inheritanceManager.lookupInheritance(classA, methodName1)); - JUnitTestCase.assertSame(methodM2, _inheritanceManager.lookupInheritance(classA, methodName2)); - assertNoErrors(classI1); - assertNoErrors(classI2); - assertNoErrors(classA); - } - void test_lookupInheritance_interfaces_union2() { ClassElementImpl classI1 = ElementFactory.classElement2("I1", []); String methodName1 = "m1"; @@ -9881,7 +10491,7 @@ class InheritanceManagerTest extends EngineTestCase { */ InheritanceManager createInheritanceManager() { AnalysisContextImpl context = AnalysisContextFactory.contextWithCore(); - FileBasedSource source = new FileBasedSource.con1(new ContentCache(), FileUtilities2.createFile("/test.dart")); + FileBasedSource source = new FileBasedSource.con1(FileUtilities2.createFile("/test.dart")); CompilationUnitElementImpl definingCompilationUnit = new CompilationUnitElementImpl("test.dart"); definingCompilationUnit.source = source; _definingLibrary = ElementFactory.library(context, "test"); @@ -9903,6 +10513,10 @@ class InheritanceManagerTest extends EngineTestCase { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromClasses_accessor_with); }); + _ut.test('test_getMapOfMembersInheritedFromClasses_implicitExtends', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromClasses_implicitExtends); + }); _ut.test('test_getMapOfMembersInheritedFromClasses_method_extends', () { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromClasses_method_extends); @@ -9927,6 +10541,30 @@ class InheritanceManagerTest extends EngineTestCase { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_accessor_with); }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_implicitExtends', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_implicitExtends); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int); + }); _ut.test('test_getMapOfMembersInheritedFromInterfaces_method_extends', () { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_method_extends); @@ -9939,6 +10577,46 @@ class InheritanceManagerTest extends EngineTestCase { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_method_with); }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_differentNames', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_differentNames); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods); + }); + _ut.test('test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods', () { + final __test = new InheritanceManagerTest(); + runJUnitTest(__test, __test.test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods); + }); _ut.test('test_lookupInheritance_interface_getter', () { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_lookupInheritance_interface_getter); @@ -9955,14 +10633,6 @@ class InheritanceManagerTest extends EngineTestCase { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_lookupInheritance_interface_staticMember); }); - _ut.test('test_lookupInheritance_interfaces_STWC_inconsistentMethodInheritance', () { - final __test = new InheritanceManagerTest(); - runJUnitTest(__test, __test.test_lookupInheritance_interfaces_STWC_inconsistentMethodInheritance); - }); - _ut.test('test_lookupInheritance_interfaces_SWC_inconsistentMethodInheritance', () { - final __test = new InheritanceManagerTest(); - runJUnitTest(__test, __test.test_lookupInheritance_interfaces_SWC_inconsistentMethodInheritance); - }); _ut.test('test_lookupInheritance_interfaces_infiniteLoop', () { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_lookupInheritance_interfaces_infiniteLoop); @@ -9971,10 +10641,6 @@ class InheritanceManagerTest extends EngineTestCase { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_lookupInheritance_interfaces_infiniteLoop2); }); - _ut.test('test_lookupInheritance_interfaces_union1', () { - final __test = new InheritanceManagerTest(); - runJUnitTest(__test, __test.test_lookupInheritance_interfaces_union1); - }); _ut.test('test_lookupInheritance_interfaces_union2', () { final __test = new InheritanceManagerTest(); runJUnitTest(__test, __test.test_lookupInheritance_interfaces_union2); @@ -15441,10 +16107,9 @@ class ElementResolverTest extends EngineTestCase { */ ElementResolver createResolver() { AnalysisContextImpl context = new AnalysisContextImpl(); - ContentCache contentCache = new ContentCache(); - SourceFactory sourceFactory = new SourceFactory.con1(contentCache, [new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]); + SourceFactory sourceFactory = new SourceFactory([new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]); context.sourceFactory = sourceFactory; - FileBasedSource source = new FileBasedSource.con1(contentCache, FileUtilities2.createFile("/test.dart")); + FileBasedSource source = new FileBasedSource.con1(FileUtilities2.createFile("/test.dart")); CompilationUnitElementImpl definingCompilationUnit = new CompilationUnitElementImpl("test.dart"); definingCompilationUnit.source = source; _definingLibrary = ElementFactory.library(context, "test"); @@ -17078,6 +17743,24 @@ class StaticWarningCodeTest extends ResolverTestCase { verify([source]); } + void test_invalidGetterOverrideReturnType_twoInterfaces() { + // test from language/override_inheritance_field_test_11.dart + Source source = addSource(EngineTestCase.createSource([ + "abstract class I {", + " int get getter => null;", + "}", + "abstract class J {", + " num get getter => null;", + "}", + "abstract class A implements I, J {}", + "class B extends A {", + " String get getter => null;", + "}"])); + resolve(source); + assertErrors(source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]); + verify([source]); + } + void test_invalidMethodOverrideNamedParamType() { Source source = addSource(EngineTestCase.createSource([ "class A {", @@ -17104,6 +17787,23 @@ class StaticWarningCodeTest extends ResolverTestCase { verify([source]); } + void test_invalidMethodOverrideNormalParamType_twoInterfaces() { + Source source = addSource(EngineTestCase.createSource([ + "abstract class I {", + " m(int n);", + "}", + "abstract class J {", + " m(num n);", + "}", + "abstract class A implements I, J {}", + "class B extends A {", + " m(String n) {}", + "}"])); + resolve(source); + assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); + verify([source]); + } + void test_invalidMethodOverrideOptionalParamType() { Source source = addSource(EngineTestCase.createSource([ "class A {", @@ -17117,6 +17817,23 @@ class StaticWarningCodeTest extends ResolverTestCase { verify([source]); } + void test_invalidMethodOverrideOptionalParamType_twoInterfaces() { + Source source = addSource(EngineTestCase.createSource([ + "abstract class I {", + " m([int n]);", + "}", + "abstract class J {", + " m([num n]);", + "}", + "abstract class A implements I, J {}", + "class B extends A {", + " m([String n]) {}", + "}"])); + resolve(source); + assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]); + verify([source]); + } + void test_invalidMethodOverrideReturnType_interface() { Source source = addSource(EngineTestCase.createSource([ "class A {", @@ -17130,7 +17847,7 @@ class StaticWarningCodeTest extends ResolverTestCase { verify([source]); } - void test_invalidMethodOverrideReturnType_interface2() { + void test_invalidMethodOverrideReturnType_interface_grandparent() { Source source = addSource(EngineTestCase.createSource([ "abstract class A {", " int m();", @@ -17171,7 +17888,7 @@ class StaticWarningCodeTest extends ResolverTestCase { verify([source]); } - void test_invalidMethodOverrideReturnType_superclass2() { + void test_invalidMethodOverrideReturnType_superclass_grandparent() { Source source = addSource(EngineTestCase.createSource([ "class A {", " int m() { return 0; }", @@ -17186,6 +17903,23 @@ class StaticWarningCodeTest extends ResolverTestCase { verify([source]); } + void test_invalidMethodOverrideReturnType_twoInterfaces() { + Source source = addSource(EngineTestCase.createSource([ + "abstract class I {", + " int m();", + "}", + "abstract class J {", + " num m();", + "}", + "abstract class A implements I, J {}", + "class B extends A {", + " String m() => '';", + "}"])); + resolve(source); + assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); + verify([source]); + } + void test_invalidMethodOverrideReturnType_void() { Source source = addSource(EngineTestCase.createSource([ "class A {", @@ -17316,6 +18050,24 @@ class StaticWarningCodeTest extends ResolverTestCase { verify([source]); } + void test_invalidSetterOverrideNormalParamType_twoInterfaces() { + // test from language/override_inheritance_field_test_34.dart + Source source = addSource(EngineTestCase.createSource([ + "abstract class I {", + " set setter14(int _) => null;", + "}", + "abstract class J {", + " set setter14(num _) => null;", + "}", + "abstract class A implements I, J {}", + "class B extends A {", + " set setter14(String _) => null;", + "}"])); + resolve(source); + assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]); + verify([source]); + } + void test_listElementTypeNotAssignable() { Source source = addSource(EngineTestCase.createSource(["var v = [42];"])); resolve(source); @@ -17394,7 +18146,9 @@ class StaticWarningCodeTest extends ResolverTestCase { " }", "}"])); resolve(source); - assertErrors(source, [StaticWarningCode.MIXED_RETURN_TYPES]); + assertErrors(source, [ + StaticWarningCode.MIXED_RETURN_TYPES, + StaticWarningCode.MIXED_RETURN_TYPES]); verify([source]); } @@ -17409,7 +18163,9 @@ class StaticWarningCodeTest extends ResolverTestCase { " }", "}"])); resolve(source); - assertErrors(source, [StaticWarningCode.MIXED_RETURN_TYPES]); + assertErrors(source, [ + StaticWarningCode.MIXED_RETURN_TYPES, + StaticWarningCode.MIXED_RETURN_TYPES]); verify([source]); } @@ -17422,7 +18178,9 @@ class StaticWarningCodeTest extends ResolverTestCase { " return 0;", "}"])); resolve(source); - assertErrors(source, [StaticWarningCode.MIXED_RETURN_TYPES]); + assertErrors(source, [ + StaticWarningCode.MIXED_RETURN_TYPES, + StaticWarningCode.MIXED_RETURN_TYPES]); verify([source]); } @@ -17652,6 +18410,23 @@ class StaticWarningCodeTest extends ResolverTestCase { verify([source]); } + void test_nonAbstractClassInheritsAbstractMemberOne_setter_and_implicitSetter() { + // test from language/override_inheritance_abstract_test_14.dart + Source source = addSource(EngineTestCase.createSource([ + "abstract class A {", + " set field(_);", + "}", + "abstract class I {", + " var field;", + "}", + "class B extends A implements I {", + " get field => 0;", + "}"])); + resolve(source); + assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]); + verify([source]); + } + void test_nonAbstractClassInheritsAbstractMemberOne_setter_fromInterface() { Source source = addSource(EngineTestCase.createSource([ "class I {", @@ -18542,6 +19317,10 @@ class StaticWarningCodeTest extends ResolverTestCase { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_invalidGetterOverrideReturnType_implicit); }); + _ut.test('test_invalidGetterOverrideReturnType_twoInterfaces', () { + final __test = new StaticWarningCodeTest(); + runJUnitTest(__test, __test.test_invalidGetterOverrideReturnType_twoInterfaces); + }); _ut.test('test_invalidMethodOverrideNamedParamType', () { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_invalidMethodOverrideNamedParamType); @@ -18550,17 +19329,25 @@ class StaticWarningCodeTest extends ResolverTestCase { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType); }); + _ut.test('test_invalidMethodOverrideNormalParamType_twoInterfaces', () { + final __test = new StaticWarningCodeTest(); + runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType_twoInterfaces); + }); _ut.test('test_invalidMethodOverrideOptionalParamType', () { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_invalidMethodOverrideOptionalParamType); }); + _ut.test('test_invalidMethodOverrideOptionalParamType_twoInterfaces', () { + final __test = new StaticWarningCodeTest(); + runJUnitTest(__test, __test.test_invalidMethodOverrideOptionalParamType_twoInterfaces); + }); _ut.test('test_invalidMethodOverrideReturnType_interface', () { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_invalidMethodOverrideReturnType_interface); }); - _ut.test('test_invalidMethodOverrideReturnType_interface2', () { + _ut.test('test_invalidMethodOverrideReturnType_interface_grandparent', () { final __test = new StaticWarningCodeTest(); - runJUnitTest(__test, __test.test_invalidMethodOverrideReturnType_interface2); + runJUnitTest(__test, __test.test_invalidMethodOverrideReturnType_interface_grandparent); }); _ut.test('test_invalidMethodOverrideReturnType_mixin', () { final __test = new StaticWarningCodeTest(); @@ -18570,9 +19357,13 @@ class StaticWarningCodeTest extends ResolverTestCase { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_invalidMethodOverrideReturnType_superclass); }); - _ut.test('test_invalidMethodOverrideReturnType_superclass2', () { + _ut.test('test_invalidMethodOverrideReturnType_superclass_grandparent', () { final __test = new StaticWarningCodeTest(); - runJUnitTest(__test, __test.test_invalidMethodOverrideReturnType_superclass2); + runJUnitTest(__test, __test.test_invalidMethodOverrideReturnType_superclass_grandparent); + }); + _ut.test('test_invalidMethodOverrideReturnType_twoInterfaces', () { + final __test = new StaticWarningCodeTest(); + runJUnitTest(__test, __test.test_invalidMethodOverrideReturnType_twoInterfaces); }); _ut.test('test_invalidMethodOverrideReturnType_void', () { final __test = new StaticWarningCodeTest(); @@ -18614,6 +19405,10 @@ class StaticWarningCodeTest extends ResolverTestCase { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType); }); + _ut.test('test_invalidSetterOverrideNormalParamType_twoInterfaces', () { + final __test = new StaticWarningCodeTest(); + runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType_twoInterfaces); + }); _ut.test('test_listElementTypeNotAssignable', () { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_listElementTypeNotAssignable); @@ -18726,6 +19521,10 @@ class StaticWarningCodeTest extends ResolverTestCase { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_method_optionalParamCount); }); + _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_setter_and_implicitSetter', () { + final __test = new StaticWarningCodeTest(); + runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_setter_and_implicitSetter); + }); _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_setter_fromInterface', () { final __test = new StaticWarningCodeTest(); runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_setter_fromInterface); @@ -18952,29 +19751,18 @@ class StaticWarningCodeTest extends ResolverTestCase { class AnalysisContextHelper { AnalysisContext context; - SourceFactory _sourceFactory; - - ContentCache _cache; - /** * Creates new [AnalysisContext] using [AnalysisContextFactory#contextWithCore]. */ AnalysisContextHelper() { context = AnalysisContextFactory.contextWithCore(); - _sourceFactory = context.sourceFactory; - _cache = _sourceFactory.contentCache; } Source addSource(String path, String code) { - Source source = new FileBasedSource.con1(_cache, FileUtilities2.createFile(path)); - // add source - { - _sourceFactory.setContents(source, ""); - ChangeSet changeSet = new ChangeSet(); - changeSet.added(source); - context.applyChanges(changeSet); - } - // update source + Source source = new FileBasedSource.con1(FileUtilities2.createFile(path)); + ChangeSet changeSet = new ChangeSet(); + changeSet.added(source); + context.applyChanges(changeSet); context.setContents(source, code); return source; } @@ -19229,7 +20017,12 @@ class TestTypeProvider implements TypeProvider { if (_mapType == null) { ClassElementImpl mapElement = ElementFactory.classElement2("Map", ["K", "V"]); _mapType = mapElement.type; + Type2 kType = mapElement.typeParameters[0].type; + Type2 vType = mapElement.typeParameters[1].type; mapElement.accessors = [ElementFactory.getterElement("length", false, intType)]; + mapElement.methods = [ + ElementFactory.methodElement("[]", vType, [objectType]), + ElementFactory.methodElement("[]=", VoidTypeImpl.instance, [kType, vType])]; propagateTypeArguments(mapElement); } return _mapType; @@ -19505,7 +20298,7 @@ class AnalysisContextFactory { elementMap[coreSource] = coreLibrary; elementMap[htmlSource] = htmlLibrary; (sdkContext as AnalysisContextImpl).recordLibraryElements(elementMap); - sourceFactory = new SourceFactory.con2([ + sourceFactory = new SourceFactory([ new DartUriResolver(sdkContext.sourceFactory.dartSdk), new FileUriResolver()]); context.sourceFactory = sourceFactory; @@ -19516,6 +20309,7 @@ class AnalysisContextFactory { class LibraryImportScopeTest extends ResolverTestCase { void test_conflictingImports() { AnalysisContext context = new AnalysisContextImpl(); + context.sourceFactory = new SourceFactory([]); String typeNameA = "A"; String typeNameB = "B"; String typeNameC = "C"; @@ -19570,6 +20364,7 @@ class LibraryImportScopeTest extends ResolverTestCase { void test_creation_nonEmpty() { AnalysisContext context = new AnalysisContextImpl(); + context.sourceFactory = new SourceFactory([]); String importedTypeName = "A"; ClassElement importedType = new ClassElementImpl(ASTFactory.identifier3(importedTypeName)); LibraryElement importedLibrary = createTestLibrary2(context, "imported", []); @@ -19608,6 +20403,7 @@ class LibraryImportScopeTest extends ResolverTestCase { void test_nonConflictingImports_sameElement() { AnalysisContext context = new AnalysisContextImpl(); + context.sourceFactory = new SourceFactory([]); String typeNameA = "A"; String typeNameB = "B"; ClassElement typeA = ElementFactory.classElement2(typeNameA, []); @@ -19628,6 +20424,7 @@ class LibraryImportScopeTest extends ResolverTestCase { void test_prefixedAndNonPrefixed() { AnalysisContext context = new AnalysisContextImpl(); + context.sourceFactory = new SourceFactory([]); String typeName = "C"; String prefixName = "p"; ClassElement prefixedType = ElementFactory.classElement2(typeName, []); @@ -20031,6 +20828,7 @@ class LibraryScopeTest extends ResolverTestCase { void test_creation_nonEmpty() { AnalysisContext context = new AnalysisContextImpl(); + context.sourceFactory = new SourceFactory([]); String importedTypeName = "A"; ClassElement importedType = new ClassElementImpl(ASTFactory.identifier3(importedTypeName)); LibraryElement importedLibrary = createTestLibrary2(context, "imported", []); @@ -20132,7 +20930,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { InterfaceType superclassType = superclass.type; ClassElement subclass = ElementFactory.classElement("B", superclassType, []); Expression node = ASTFactory.asExpression(ASTFactory.thisExpression(), ASTFactory.typeName(subclass, [])); - JUnitTestCase.assertSame(subclass.type, analyze2(node, superclassType)); + JUnitTestCase.assertSame(subclass.type, analyze3(node, superclassType)); _listener.assertNoErrors(); } @@ -20280,8 +21078,8 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p2 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0)); setType(p2, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([])); - analyze3(p1); - analyze3(p2); + analyze5(p1); + analyze5(p2); Type2 resultType = analyze(node); Map expectedNamedTypes = new Map(); expectedNamedTypes["p1"] = dynamicType; @@ -20296,7 +21094,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p"), resolvedInteger(0)); setType(p, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p]), ASTFactory.expressionFunctionBody(resolvedInteger(0))); - analyze3(p); + analyze5(p); Type2 resultType = analyze(node); Map expectedNamedTypes = new Map(); expectedNamedTypes["p"] = dynamicType; @@ -20312,8 +21110,8 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p2 = ASTFactory.simpleFormalParameter3("p2"); setType(p2, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([])); - analyze3(p1); - analyze3(p2); + analyze5(p1); + analyze5(p2); Type2 resultType = analyze(node); assertFunctionType(dynamicType, [dynamicType, dynamicType], null, null, resultType); _listener.assertNoErrors(); @@ -20325,7 +21123,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p = ASTFactory.simpleFormalParameter3("p"); setType(p, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p]), ASTFactory.expressionFunctionBody(resolvedInteger(0))); - analyze3(p); + analyze5(p); Type2 resultType = analyze(node); assertFunctionType(_typeProvider.intType, [dynamicType], null, null, resultType); _listener.assertNoErrors(); @@ -20339,7 +21137,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p2 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0)); setType(p2, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([])); - analyze3(p2); + analyze5(p2); Type2 resultType = analyze(node); Map expectedNamedTypes = new Map(); expectedNamedTypes["p2"] = dynamicType; @@ -20355,7 +21153,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p2 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0)); setType(p2, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.expressionFunctionBody(resolvedInteger(0))); - analyze3(p2); + analyze5(p2); Type2 resultType = analyze(node); Map expectedNamedTypes = new Map(); expectedNamedTypes["p2"] = dynamicType; @@ -20371,8 +21169,8 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p2 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0)); setType(p2, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([])); - analyze3(p1); - analyze3(p2); + analyze5(p1); + analyze5(p2); Type2 resultType = analyze(node); assertFunctionType(dynamicType, [dynamicType], [dynamicType], null, resultType); _listener.assertNoErrors(); @@ -20386,8 +21184,8 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p2 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0)); setType(p2, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.expressionFunctionBody(resolvedInteger(0))); - analyze3(p1); - analyze3(p2); + analyze5(p1); + analyze5(p2); Type2 resultType = analyze(node); assertFunctionType(_typeProvider.intType, [dynamicType], [dynamicType], null, resultType); _listener.assertNoErrors(); @@ -20401,8 +21199,8 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p2 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0)); setType(p2, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([])); - analyze3(p1); - analyze3(p2); + analyze5(p1); + analyze5(p2); Type2 resultType = analyze(node); assertFunctionType(dynamicType, null, [dynamicType, dynamicType], null, resultType); _listener.assertNoErrors(); @@ -20414,7 +21212,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { FormalParameter p = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p"), resolvedInteger(0)); setType(p, dynamicType); FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p]), ASTFactory.expressionFunctionBody(resolvedInteger(0))); - analyze3(p); + analyze5(p); Type2 resultType = analyze(node); assertFunctionType(_typeProvider.intType, null, [dynamicType], null, resultType); _listener.assertNoErrors(); @@ -20709,7 +21507,26 @@ class StaticTypeAnalyzerTest extends EngineTestCase { _listener.assertNoErrors(); } - void test_visitPropertyAccess_getter() { + void test_visitPropertyAccess_propagated_getter() { + Type2 boolType = _typeProvider.boolType; + PropertyAccessorElementImpl getter = ElementFactory.getterElement("b", false, boolType); + PropertyAccess node = ASTFactory.propertyAccess2(ASTFactory.identifier3("a"), "b"); + node.propertyName.propagatedElement = getter; + JUnitTestCase.assertSame(boolType, analyze2(node, false)); + _listener.assertNoErrors(); + } + + void test_visitPropertyAccess_propagated_setter() { + Type2 boolType = _typeProvider.boolType; + FieldElementImpl field = ElementFactory.fieldElement("b", false, false, false, boolType); + PropertyAccessorElement setter = field.setter; + PropertyAccess node = ASTFactory.propertyAccess2(ASTFactory.identifier3("a"), "b"); + node.propertyName.propagatedElement = setter; + JUnitTestCase.assertSame(boolType, analyze2(node, false)); + _listener.assertNoErrors(); + } + + void test_visitPropertyAccess_static_getter() { Type2 boolType = _typeProvider.boolType; PropertyAccessorElementImpl getter = ElementFactory.getterElement("b", false, boolType); PropertyAccess node = ASTFactory.propertyAccess2(ASTFactory.identifier3("a"), "b"); @@ -20718,7 +21535,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { _listener.assertNoErrors(); } - void test_visitPropertyAccess_setter() { + void test_visitPropertyAccess_static_setter() { Type2 boolType = _typeProvider.boolType; FieldElementImpl field = ElementFactory.fieldElement("b", false, false, false, boolType); PropertyAccessorElement setter = field.setter; @@ -20750,7 +21567,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { InterfaceType superType = ElementFactory.classElement2("A", []).type; InterfaceType thisType = ElementFactory.classElement("B", superType, []).type; Expression node = ASTFactory.superExpression(); - JUnitTestCase.assertSame(thisType, analyze2(node, thisType)); + JUnitTestCase.assertSame(thisType, analyze3(node, thisType)); _listener.assertNoErrors(); } @@ -20762,7 +21579,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { // this InterfaceType thisType = ElementFactory.classElement("B", ElementFactory.classElement2("A", []).type, []).type; Expression node = ASTFactory.thisExpression(); - JUnitTestCase.assertSame(thisType, analyze2(node, thisType)); + JUnitTestCase.assertSame(thisType, analyze3(node, thisType)); _listener.assertNoErrors(); } @@ -20787,7 +21604,18 @@ class StaticTypeAnalyzerTest extends EngineTestCase { * @param node the expression with which the type is associated * @return the type associated with the expression */ - Type2 analyze(Expression node) => analyze2(node, null); + Type2 analyze(Expression node) => analyze4(node, null, true); + + /** + * Return the type associated with the given expression after the static or propagated type + * analyzer has computed a type for it. + * + * @param node the expression with which the type is associated + * @param useStaticType `true` if the static type is being requested, and `false` if + * the propagated type is being requested + * @return the type associated with the expression + */ + Type2 analyze2(Expression node, bool useStaticType) => analyze4(node, null, useStaticType); /** * Return the type associated with the given expression after the static type analyzer has @@ -20797,14 +21625,30 @@ class StaticTypeAnalyzerTest extends EngineTestCase { * @param thisType the type of 'this' * @return the type associated with the expression */ - Type2 analyze2(Expression node, InterfaceType thisType) { + Type2 analyze3(Expression node, InterfaceType thisType) => analyze4(node, thisType, true); + + /** + * Return the type associated with the given expression after the static type analyzer has + * computed a type for it. + * + * @param node the expression with which the type is associated + * @param thisType the type of 'this' + * @param useStaticType `true` if the static type is being requested, and `false` if + * the propagated type is being requested + * @return the type associated with the expression + */ + Type2 analyze4(Expression node, InterfaceType thisType, bool useStaticType) { try { _analyzer.thisType_J2DAccessor = thisType; } on JavaException catch (exception) { throw new IllegalArgumentException("Could not set type of 'this'", exception); } node.accept(_analyzer); - return node.staticType; + if (useStaticType) { + return node.staticType; + } else { + return node.propagatedType; + } } /** @@ -20814,7 +21658,7 @@ class StaticTypeAnalyzerTest extends EngineTestCase { * @param node the parameter with which the type is associated * @return the type associated with the parameter */ - Type2 analyze3(FormalParameter node) { + Type2 analyze5(FormalParameter node) { node.accept(_analyzer); return (node.identifier.staticElement as ParameterElement).type; } @@ -20889,9 +21733,9 @@ class StaticTypeAnalyzerTest extends EngineTestCase { */ StaticTypeAnalyzer createAnalyzer() { AnalysisContextImpl context = new AnalysisContextImpl(); - SourceFactory sourceFactory = new SourceFactory.con2([new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]); + SourceFactory sourceFactory = new SourceFactory([new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]); context.sourceFactory = sourceFactory; - FileBasedSource source = new FileBasedSource.con1(sourceFactory.contentCache, FileUtilities2.createFile("/lib.dart")); + FileBasedSource source = new FileBasedSource.con1(FileUtilities2.createFile("/lib.dart")); CompilationUnitElementImpl definingCompilationUnit = new CompilationUnitElementImpl("lib.dart"); definingCompilationUnit.source = source; LibraryElementImpl definingLibrary = new LibraryElementImpl(context, null); @@ -21240,13 +22084,21 @@ class StaticTypeAnalyzerTest extends EngineTestCase { final __test = new StaticTypeAnalyzerTest(); runJUnitTest(__test, __test.test_visitPrefixedIdentifier_variable); }); - _ut.test('test_visitPropertyAccess_getter', () { + _ut.test('test_visitPropertyAccess_propagated_getter', () { final __test = new StaticTypeAnalyzerTest(); - runJUnitTest(__test, __test.test_visitPropertyAccess_getter); + runJUnitTest(__test, __test.test_visitPropertyAccess_propagated_getter); }); - _ut.test('test_visitPropertyAccess_setter', () { + _ut.test('test_visitPropertyAccess_propagated_setter', () { final __test = new StaticTypeAnalyzerTest(); - runJUnitTest(__test, __test.test_visitPropertyAccess_setter); + runJUnitTest(__test, __test.test_visitPropertyAccess_propagated_setter); + }); + _ut.test('test_visitPropertyAccess_static_getter', () { + final __test = new StaticTypeAnalyzerTest(); + runJUnitTest(__test, __test.test_visitPropertyAccess_static_getter); + }); + _ut.test('test_visitPropertyAccess_static_setter', () { + final __test = new StaticTypeAnalyzerTest(); + runJUnitTest(__test, __test.test_visitPropertyAccess_static_setter); }); _ut.test('test_visitSimpleStringLiteral', () { final __test = new StaticTypeAnalyzerTest(); @@ -21535,6 +22387,102 @@ class NonHintCodeTest extends ResolverTestCase { verify([source]); } + void test_overrideOnNonOverridingGetter_inInterface() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + " int get m => 0;", + "}", + "class B implements A {", + " @override", + " int get m => 1;", + "}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + + void test_overrideOnNonOverridingGetter_inSuperclass() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + " int get m => 0;", + "}", + "class B extends A {", + " @override", + " int get m => 1;", + "}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + + void test_overrideOnNonOverridingMethod_inInterface() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + " int m() => 0;", + "}", + "class B implements A {", + " @override", + " int m() => 1;", + "}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + + void test_overrideOnNonOverridingMethod_inSuperclass() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + " int m() => 0;", + "}", + "class B extends A {", + " @override", + " int m() => 1;", + "}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + + void test_overrideOnNonOverridingSetter_inInterface() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + " set m(int x) {}", + "}", + "class B implements A {", + " @override", + " set m(int x) {}", + "}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + + void test_overrideOnNonOverridingSetter_inSuperclass() { + Source source = addSource(EngineTestCase.createSource([ + "library dart.core;", + "const override = null;", + "class A {", + " set m(int x) {}", + "}", + "class B extends A {", + " @override", + " set m(int x) {}", + "}"])); + resolve(source); + assertNoErrors(source); + verify([source]); + } + void test_proxy_annotation_prefixed() { Source source = addSource(EngineTestCase.createSource([ "library L;", @@ -21948,6 +22896,30 @@ class NonHintCodeTest extends ResolverTestCase { final __test = new NonHintCodeTest(); runJUnitTest(__test, __test.test_overrideEqualsButNotHashCode); }); + _ut.test('test_overrideOnNonOverridingGetter_inInterface', () { + final __test = new NonHintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingGetter_inInterface); + }); + _ut.test('test_overrideOnNonOverridingGetter_inSuperclass', () { + final __test = new NonHintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingGetter_inSuperclass); + }); + _ut.test('test_overrideOnNonOverridingMethod_inInterface', () { + final __test = new NonHintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingMethod_inInterface); + }); + _ut.test('test_overrideOnNonOverridingMethod_inSuperclass', () { + final __test = new NonHintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingMethod_inSuperclass); + }); + _ut.test('test_overrideOnNonOverridingSetter_inInterface', () { + final __test = new NonHintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingSetter_inInterface); + }); + _ut.test('test_overrideOnNonOverridingSetter_inSuperclass', () { + final __test = new NonHintCodeTest(); + runJUnitTest(__test, __test.test_overrideOnNonOverridingSetter_inSuperclass); + }); _ut.test('test_proxy_annotation_prefixed', () { final __test = new NonHintCodeTest(); runJUnitTest(__test, __test.test_proxy_annotation_prefixed); @@ -22108,12 +23080,16 @@ class Scope_EnclosedScopeTest_test_define_normal extends Scope { class LibraryElementBuilderTest extends EngineTestCase { /** - * The source factory used to create [Source]. + * The analysis context used to analyze sources. */ - SourceFactory _sourceFactory; + AnalysisContextImpl _context; void setUp() { - _sourceFactory = new SourceFactory.con2([new FileUriResolver()]); + SourceFactory sourceFactory = new SourceFactory([ + new DartUriResolver(DirectoryBasedDartSdk.defaultSdk), + new FileUriResolver()]); + _context = new AnalysisContextImpl(); + _context.sourceFactory = sourceFactory; } void test_accessorsAcrossFiles() { @@ -22214,8 +23190,8 @@ class LibraryElementBuilderTest extends EngineTestCase { * @return the source object representing the added file */ Source addSource(String filePath, String contents) { - Source source = new FileBasedSource.con1(_sourceFactory.contentCache, FileUtilities2.createFile(filePath)); - _sourceFactory.setContents(source, contents); + Source source = new FileBasedSource.con1(FileUtilities2.createFile(filePath)); + _context.setContents(source, contents); return source; } @@ -22254,11 +23230,7 @@ class LibraryElementBuilderTest extends EngineTestCase { * @throws Exception if the element model could not be built */ LibraryElement buildLibrary(Source librarySource, List expectedErrorCodes) { - AnalysisContextImpl context = new AnalysisContextImpl(); - context.sourceFactory = new SourceFactory.con2([ - new DartUriResolver(DirectoryBasedDartSdk.defaultSdk), - new FileUriResolver()]); - LibraryResolver resolver = new LibraryResolver(context); + LibraryResolver resolver = new LibraryResolver(_context); LibraryElementBuilder builder = new LibraryElementBuilder(resolver); Library library = resolver.createLibrary(librarySource); LibraryElement element = builder.buildLibrary(library); @@ -22556,6 +23528,38 @@ class SimpleResolverTest extends ResolverTestCase { verify([source]); } + void test_entryPoint_exported() { + addSource2("/two.dart", EngineTestCase.createSource(["library two;", "main() {}"])); + Source source = addSource2("/one.dart", EngineTestCase.createSource(["library one;", "export 'two.dart';"])); + LibraryElement library = resolve(source); + JUnitTestCase.assertNotNull(library); + FunctionElement main = library.entryPoint; + JUnitTestCase.assertNotNull(main); + JUnitTestCase.assertNotSame(library, main.library); + assertNoErrors(source); + verify([source]); + } + + void test_entryPoint_local() { + Source source = addSource2("/one.dart", EngineTestCase.createSource(["library one;", "main() {}"])); + LibraryElement library = resolve(source); + JUnitTestCase.assertNotNull(library); + FunctionElement main = library.entryPoint; + JUnitTestCase.assertNotNull(main); + JUnitTestCase.assertSame(library, main.library); + assertNoErrors(source); + verify([source]); + } + + void test_entryPoint_none() { + Source source = addSource2("/one.dart", EngineTestCase.createSource(["library one;"])); + LibraryElement library = resolve(source); + JUnitTestCase.assertNotNull(library); + JUnitTestCase.assertNull(library.entryPoint); + assertNoErrors(source); + verify([source]); + } + void test_extractedMethodAsConstant() { Source source = addSource(EngineTestCase.createSource([ "abstract class Comparable {", @@ -23203,6 +24207,18 @@ class SimpleResolverTest extends ResolverTestCase { final __test = new SimpleResolverTest(); runJUnitTest(__test, __test.test_empty); }); + _ut.test('test_entryPoint_exported', () { + final __test = new SimpleResolverTest(); + runJUnitTest(__test, __test.test_entryPoint_exported); + }); + _ut.test('test_entryPoint_local', () { + final __test = new SimpleResolverTest(); + runJUnitTest(__test, __test.test_entryPoint_local); + }); + _ut.test('test_entryPoint_none', () { + final __test = new SimpleResolverTest(); + runJUnitTest(__test, __test.test_entryPoint_none); + }); _ut.test('test_extractedMethodAsConstant', () { final __test = new SimpleResolverTest(); runJUnitTest(__test, __test.test_extractedMethodAsConstant); @@ -23459,7 +24475,7 @@ class SubtypeManagerTest extends EngineTestCase { void setUp() { super.setUp(); AnalysisContextImpl context = AnalysisContextFactory.contextWithCore(); - FileBasedSource source = new FileBasedSource.con1(new ContentCache(), FileUtilities2.createFile("/test.dart")); + FileBasedSource source = new FileBasedSource.con1(FileUtilities2.createFile("/test.dart")); _definingCompilationUnit = new CompilationUnitElementImpl("test.dart"); _definingCompilationUnit.source = source; LibraryElementImpl definingLibrary = ElementFactory.library(context, "test"); diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart index 2e1b72b37cc..adde198e19a 100644 --- a/pkg/analyzer/test/generated/test_support.dart +++ b/pkg/analyzer/test/generated/test_support.dart @@ -14,7 +14,7 @@ import 'package:analyzer/src/generated/error.dart'; import 'package:analyzer/src/generated/scanner.dart'; import 'package:analyzer/src/generated/ast.dart' show ASTNode, NodeLocator; import 'package:analyzer/src/generated/element.dart' show InterfaceType, MethodElement, PropertyAccessorElement; -import 'package:analyzer/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl, RecordingErrorListener; +import 'package:analyzer/src/generated/engine.dart'; import 'package:unittest/unittest.dart' as _ut; /** @@ -781,7 +781,7 @@ class EngineTestCase extends JUnitTestCase { AnalysisContextImpl createAnalysisContext() { AnalysisContextImpl context = new AnalysisContextImpl(); - context.sourceFactory = new SourceFactory.con2([]); + context.sourceFactory = new SourceFactory([]); return context; } @@ -836,7 +836,7 @@ class TestSource implements Source { AnalysisContext get context { throw new UnsupportedOperationException(); } - void getContents(Source_ContentReceiver receiver) { + void getContentsToReceiver(Source_ContentReceiver receiver) { throw new UnsupportedOperationException(); } String get fullName { @@ -864,6 +864,9 @@ class TestSource implements Source { UriKind get uriKind { throw new UnsupportedOperationException(); } + TimestampedData get contents { + throw new UnsupportedOperationException(); + } } /** diff --git a/pkg/analyzer/test/services/test_utils.dart b/pkg/analyzer/test/services/test_utils.dart index 2a95fb33c7e..b67ad1ff016 100644 --- a/pkg/analyzer/test/services/test_utils.dart +++ b/pkg/analyzer/test/services/test_utils.dart @@ -6,7 +6,7 @@ library test_utils; import 'package:unittest/unittest.dart'; -import 'package:analyzer/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl; +import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/source.dart'; import 'package:analyzer/src/generated/error.dart'; import 'package:analyzer/src/generated/scanner.dart'; @@ -162,7 +162,7 @@ class _TestSource implements Source { AnalysisContext get context => _unsupported(); - void getContents(Source_ContentReceiver receiver) => _unsupported(); + void getContentsToReceiver(Source_ContentReceiver receiver) => _unsupported(); String get fullName => _unsupported(); @@ -182,6 +182,7 @@ class _TestSource implements Source { Source resolveRelative(Uri uri) => _unsupported(); + TimestampedData get contents => _unsupported(); } diff --git a/pkg/code_transformers/lib/src/resolver_impl.dart b/pkg/code_transformers/lib/src/resolver_impl.dart index ae0a5b08fd0..afe3079007f 100644 --- a/pkg/code_transformers/lib/src/resolver_impl.dart +++ b/pkg/code_transformers/lib/src/resolver_impl.dart @@ -69,7 +69,7 @@ class ResolverImpl implements Resolver { _dartSdk = new _DirectoryBasedDartSdkProxy(new JavaFile(sdkDir)); _dartSdk.context.analysisOptions = options; - _context.sourceFactory = new SourceFactory.con2([ + _context.sourceFactory = new SourceFactory([ new DartUriResolverProxy(_dartSdk), new _AssetUriResolver(this)]); } @@ -241,7 +241,7 @@ class ResolverImpl implements Resolver { var sourceFile = _getSourceFile(element); if (sourceFile == null) return null; - return new TextEditTransaction(source.contents, sourceFile); + return new TextEditTransaction(source.rawContents, sourceFile); } /// Gets the SourceFile for the source of the element. @@ -251,7 +251,7 @@ class ResolverImpl implements Resolver { var importUri = _getSourceUri(element, from: entryPoint); var spanPath = importUri != null ? importUri.toString() : assetId.path; - return new SourceFile.text(spanPath, sources[assetId].contents); + return new SourceFile.text(spanPath, sources[assetId].rawContents); } } @@ -303,7 +303,11 @@ class _AssetBasedSource extends Source { } /// Contents of the file. - String get contents => _contents; + TimestampedData get contents => + new TimestampedData(modificationStamp, _contents); + + /// Contents of the file. + String get rawContents => _contents; /// Logger for the current transform. /// @@ -320,8 +324,8 @@ class _AssetBasedSource extends Source { int get hashCode => assetId.hashCode; - void getContents(Source_ContentReceiver receiver) { - receiver.accept(contents, modificationStamp); + void getContentsToReceiver(Source_ContentReceiver receiver) { + receiver.accept(rawContents, modificationStamp); } String get encoding => @@ -359,7 +363,7 @@ class _AssetBasedSource extends Source { var uri = getSourceUri(_resolver.entryPoint); var path = uri != null ? uri.toString() : assetId.path; - return new SourceFile.text(path, contents); + return new SourceFile.text(path, rawContents); } /// Gets a URI which would be appropriate for importing this file. @@ -384,7 +388,7 @@ class _AssetUriResolver implements UriResolver { final ResolverImpl _resolver; _AssetUriResolver(this._resolver); - Source resolveAbsolute(ContentCache contentCache, Uri uri) { + Source resolveAbsolute(Uri uri) { var assetId = _resolve(null, uri.toString(), logger, null); var source = _resolver.sources[assetId]; /// All resolved assets should be available by this point. @@ -394,7 +398,7 @@ class _AssetUriResolver implements UriResolver { return source; } - Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) => + Source fromEncoding(UriKind kind, Uri uri) => throw new UnsupportedError('fromEncoding is not supported'); Uri restoreAbsolute(Source source) => @@ -423,12 +427,12 @@ class DartUriResolverProxy implements DartUriResolver { DartUriResolverProxy(DirectoryBasedDartSdk sdk) : _proxy = new DartUriResolver(sdk); - Source resolveAbsolute(ContentCache contentCache, Uri uri) => - _DartSourceProxy.wrap(_proxy.resolveAbsolute(contentCache, uri), uri); + Source resolveAbsolute(Uri uri) => + _DartSourceProxy.wrap(_proxy.resolveAbsolute(uri), uri); DartSdk get dartSdk => _proxy.dartSdk; - Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) => + Source fromEncoding(UriKind kind, Uri uri) => throw new UnsupportedError('fromEncoding is not supported'); Uri restoreAbsolute(Source source) => @@ -468,10 +472,12 @@ class _DartSourceProxy implements Source { int get hashCode => _proxy.hashCode; - void getContents(Source_ContentReceiver receiver) { - _proxy.getContents(receiver); + void getContentsToReceiver(Source_ContentReceiver receiver) { + _proxy.getContentsToReceiver(receiver); } + TimestampedData get contents => _proxy.contents; + String get encoding => _proxy.encoding; String get fullName => _proxy.fullName; diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status index cf3aeb9a05e..6660efccefb 100644 --- a/tests/language/language_analyzer2.status +++ b/tests/language/language_analyzer2.status @@ -20,14 +20,6 @@ call_type_literal_test/01: fail override_field_test/03: fail method_override7_test/03: Fail # Issue 11496 -assignable_expression_test/02: Fail # Issue 15471 -assignable_expression_test/12: Fail # Issue 15471 -assignable_expression_test/22: Fail # Issue 15471 -assignable_expression_test/32: Fail # Issue 15471 -assignable_expression_test/42: Fail # Issue 15471 - -unicode_bom_test: Fail # Issue 16314 - type_check_const_function_typedef2_test/00: MissingCompileTimeError, Ok # Compile-time error in checked mode, because of constants. # Please add new failing tests before this line. @@ -181,9 +173,6 @@ least_upper_bound_expansive_test/12: MissingStaticWarning # Issue 15060 proxy_test/05: StaticWarning # Issue 15467 proxy_test/06: StaticWarning # Issue 15467 -# test issue 15714 -typevariable_substitution2_test/01: StaticWarning # Issue 15714 - # analyzer does not handle @proxy and noSuchMethod correctly override_inheritance_no_such_method_test/03: StaticWarning # Issue 16132 override_inheritance_no_such_method_test/04: StaticWarning # Issue 16132 @@ -198,7 +187,6 @@ override_inheritance_abstract_test/27: StaticWarning # Issue 16134 override_inheritance_generic_test/03: StaticWarning # Issue 16134 # missing warning for override -override_inheritance_field_test/10: MissingStaticWarning # Issue 16135 override_inheritance_generic_test/04: MissingStaticWarning # Issue 16135 override_inheritance_generic_test/06: MissingStaticWarning # Issue 16135 override_inheritance_generic_test/07: MissingStaticWarning # Issue 16135 @@ -342,14 +330,11 @@ method_override6_test: StaticWarning method_override_test: StaticWarning mixin_illegal_static_access_test: StaticWarning mixin_illegal_syntax_test/13: CompileTimeError -mixin_typedef_constructor_test: StaticWarning -mixin_type_parameter2_test: StaticWarning mixin_type_parameters_mixin_extends_test: StaticWarning mixin_type_parameters_mixin_test: StaticWarning mixin_type_parameters_super_extends_test: StaticWarning mixin_type_parameters_super_test: StaticWarning mixin_with_two_implicit_constructors_test: StaticWarning -mixin_bound_test: StaticWarning mixin_invalid_bound_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated mixin_invalid_bound2_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated named_constructor_test/01: StaticWarning @@ -483,4 +468,3 @@ unresolved_top_level_method_negative_test: CompileTimeError vm/type_cast_vm_test: StaticWarning vm/type_vm_test: StaticWarning void_type_test: StaticWarning - diff --git a/tests/utils/utils.status b/tests/utils/utils.status index 9876a0cad43..9ef81704413 100644 --- a/tests/utils/utils.status +++ b/tests/utils/utils.status @@ -15,6 +15,3 @@ dart2js_test: Skip # Uses dart:io. [ $compiler == none && $runtime == dartium ] dart2js_test: Skip # Uses dart:io. - -[ $compiler == dart2analyzer ] -source_mirrors_test: StaticWarning # issue 16466