Version 1.4.0-dev.1.0
svn merge -r 34866:34916 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@34925 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index 52c4124..8a91113 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -6469,6 +6469,7 @@
* <pre>
* importDirective ::=
* [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'
+ * | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combinator]* ';'
* </pre>
*/
class ImportDirective extends NamespaceDirective {
@@ -6564,6 +6565,11 @@
};
/**
+ * The token representing the 'deferred' token, or `null` if the imported is not deferred.
+ */
+ Token deferredToken;
+
+ /**
* The token representing the 'as' token, or `null` if the imported names are not prefixed.
*/
Token asToken;
@@ -6581,12 +6587,13 @@
* @param metadata the annotations associated with the directive
* @param keyword the token representing the 'import' keyword
* @param libraryUri the URI of the library being imported
+ * @param deferredToken the token representing the 'deferred' token
* @param asToken the token representing the 'as' token
* @param prefix the prefix to be used with the imported names
* @param combinators the combinators used to control how names are imported
* @param semicolon the semicolon terminating the directive
*/
- ImportDirective(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, this.asToken, SimpleIdentifier prefix, List<Combinator> combinators, Token semicolon) : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
+ ImportDirective(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, this.deferredToken, this.asToken, SimpleIdentifier prefix, List<Combinator> combinators, Token semicolon) : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
this._prefix = becomeParentOf(prefix);
}
@@ -12637,6 +12644,13 @@
return element;
}
}
+ // try to get Polymer specific Element
+ {
+ Element element = null;
+ if (element != null) {
+ return element;
+ }
+ }
// no Element
return null;
}
@@ -15769,7 +15783,7 @@
@override
ImportDirective visitImportDirective(ImportDirective node) {
- ImportDirective directive = new ImportDirective(_cloneNode(node.documentationComment), _cloneNodeList(node.metadata), node.keyword, _cloneNode(node.uri), node.asToken, _cloneNode(node.prefix), _cloneNodeList(node.combinators), node.semicolon);
+ ImportDirective directive = new ImportDirective(_cloneNode(node.documentationComment), _cloneNodeList(node.metadata), node.keyword, _cloneNode(node.uri), node.deferredToken, node.asToken, _cloneNode(node.prefix), _cloneNodeList(node.combinators), node.semicolon);
directive.source = node.source;
directive.uriContent = node.uriContent;
return directive;
@@ -16964,7 +16978,7 @@
ImplementsClause visitImplementsClause(ImplementsClause node) => new ImplementsClause(_mapToken(node.keyword), _cloneNodeList(node.interfaces));
@override
- ImportDirective visitImportDirective(ImportDirective node) => new ImportDirective(_cloneNode(node.documentationComment), _cloneNodeList(node.metadata), _mapToken(node.keyword), _cloneNode(node.uri), _mapToken(node.asToken), _cloneNode(node.prefix), _cloneNodeList(node.combinators), _mapToken(node.semicolon));
+ ImportDirective visitImportDirective(ImportDirective node) => new ImportDirective(_cloneNode(node.documentationComment), _cloneNodeList(node.metadata), _mapToken(node.keyword), _cloneNode(node.uri), _mapToken(node.deferredToken), _mapToken(node.asToken), _cloneNode(node.prefix), _cloneNodeList(node.combinators), _mapToken(node.semicolon));
@override
IndexExpression visitIndexExpression(IndexExpression node) {
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index e7aeff2..91815ec 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -17,7 +17,7 @@
import 'resolver.dart' show TypeProvider;
import 'engine.dart' show AnalysisEngine;
import 'utilities_dart.dart' show ParameterKind;
-import 'utilities_collection.dart' show DirectedGraph;
+import 'utilities_collection.dart';
/**
* Instances of the class `ConstantEvaluator` evaluate constant expressions to produce their
@@ -312,11 +312,11 @@
*/
void computeValues() {
_declarationMap = _constantFinder.variableMap;
- for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(_declarationMap)) {
- VariableElement element = entry.getKey();
+ for (MapIterator<VariableElement, VariableDeclaration> iter = SingleMapIterator.forMap(_declarationMap); iter.moveNext();) {
+ VariableElement element = iter.key;
ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceGraph);
_referenceGraph.addNode(element);
- entry.getValue().initializer.accept(referenceFinder);
+ iter.value.initializer.accept(referenceFinder);
}
while (!_referenceGraph.isEmpty) {
VariableElement element = _referenceGraph.removeSink();
@@ -3938,9 +3938,9 @@
} else if (count == 0) {
return true;
}
- for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
- DartObjectImpl key = entry.getKey();
- DartObjectImpl value = entry.getValue();
+ for (MapIterator<DartObjectImpl, DartObjectImpl> iter = SingleMapIterator.forMap(_entries); iter.moveNext();) {
+ DartObjectImpl key = iter.key;
+ DartObjectImpl value = iter.value;
DartObjectImpl otherValue = otherElements[key];
if (value != otherValue) {
return false;
@@ -3955,9 +3955,9 @@
@override
Map<Object, Object> get value {
Map<Object, Object> result = new Map<Object, Object>();
- for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
- DartObjectImpl key = entry.getKey();
- DartObjectImpl value = entry.getValue();
+ for (MapIterator<DartObjectImpl, DartObjectImpl> iter = SingleMapIterator.forMap(_entries); iter.moveNext();) {
+ DartObjectImpl key = iter.key;
+ DartObjectImpl value = iter.value;
if (!key.hasExactValue || !value.hasExactValue) {
return null;
}
@@ -3968,8 +3968,8 @@
@override
bool get hasExactValue {
- for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
- if (!entry.getKey().hasExactValue || !entry.getValue().hasExactValue) {
+ for (MapIterator<DartObjectImpl, DartObjectImpl> iter = SingleMapIterator.forMap(_entries); iter.moveNext();) {
+ if (!iter.key.hasExactValue || !iter.value.hasExactValue) {
return false;
}
}
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 85c655f..a10931f 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -412,6 +412,15 @@
* @return the classes contained in this compilation unit
*/
List<ClassElement> get types;
+
+ /**
+ * Return `true` if this compilation unit defines a top-level function named
+ * `loadLibrary`.
+ *
+ * @return `true` if this compilation unit defines a top-level function named
+ * `loadLibrary`
+ */
+ bool get hasLoadLibraryFunction;
}
/**
@@ -785,17 +794,23 @@
static const ElementKind PARAMETER = const ElementKind('PARAMETER', 26, "parameter");
- static const ElementKind PREFIX = const ElementKind('PREFIX', 27, "import prefix");
+ static const ElementKind POLYMER_ATTRIBUTE = const ElementKind('POLYMER_ATTRIBUTE', 27, "Polymer attribute");
- static const ElementKind SETTER = const ElementKind('SETTER', 28, "setter");
+ static const ElementKind POLYMER_TAG_DART = const ElementKind('POLYMER_TAG_DART', 28, "Polymer Dart tag");
- static const ElementKind TOP_LEVEL_VARIABLE = const ElementKind('TOP_LEVEL_VARIABLE', 29, "top level variable");
+ static const ElementKind POLYMER_TAG_HTML = const ElementKind('POLYMER_TAG_HTML', 29, "Polymer HTML tag");
- static const ElementKind FUNCTION_TYPE_ALIAS = const ElementKind('FUNCTION_TYPE_ALIAS', 30, "function type alias");
+ static const ElementKind PREFIX = const ElementKind('PREFIX', 30, "import prefix");
- static const ElementKind TYPE_PARAMETER = const ElementKind('TYPE_PARAMETER', 31, "type parameter");
+ static const ElementKind SETTER = const ElementKind('SETTER', 31, "setter");
- static const ElementKind UNIVERSE = const ElementKind('UNIVERSE', 32, "<universe>");
+ static const ElementKind TOP_LEVEL_VARIABLE = const ElementKind('TOP_LEVEL_VARIABLE', 32, "top level variable");
+
+ static const ElementKind FUNCTION_TYPE_ALIAS = const ElementKind('FUNCTION_TYPE_ALIAS', 33, "function type alias");
+
+ static const ElementKind TYPE_PARAMETER = const ElementKind('TYPE_PARAMETER', 34, "type parameter");
+
+ static const ElementKind UNIVERSE = const ElementKind('UNIVERSE', 35, "<universe>");
static const List<ElementKind> values = const [
ANGULAR_FILTER,
@@ -825,6 +840,9 @@
METHOD,
NAME,
PARAMETER,
+ POLYMER_ATTRIBUTE,
+ POLYMER_TAG_DART,
+ POLYMER_TAG_HTML,
PREFIX,
SETTER,
TOP_LEVEL_VARIABLE,
@@ -930,6 +948,12 @@
R visitParameterElement(ParameterElement element);
+ R visitPolymerAttributeElement(PolymerAttributeElement element);
+
+ R visitPolymerTagDartElement(PolymerTagDartElement element);
+
+ R visitPolymerTagHtmlElement(PolymerTagHtmlElement element);
+
R visitPrefixElement(PrefixElement element);
R visitPropertyAccessorElement(PropertyAccessorElement element);
@@ -1084,6 +1108,11 @@
*/
abstract class FunctionElement implements ExecutableElement, LocalElement {
/**
+ * The name of the synthetic function defined for libraries that are deferred.
+ */
+ static final String LOAD_LIBRARY_NAME = "loadLibrary";
+
+ /**
* Return the resolved [FunctionDeclaration] node that declares this [FunctionElement]
* .
*
@@ -1175,6 +1204,14 @@
CompilationUnitElement get angularCompilationUnit;
/**
+ * Return an array containing all of the [PolymerTagHtmlElement]s defined in the HTML file.
+ *
+ * @return the [PolymerTagHtmlElement]s elements in the HTML file (not `null`,
+ * contains no `null`s)
+ */
+ List<PolymerTagHtmlElement> get polymerTags;
+
+ /**
* Return an array containing all of the script elements contained in the HTML file. This includes
* scripts with libraries that are defined by the content of a script tag as well as libraries
* that are referenced in the {@core source} attribute of a script tag.
@@ -1235,6 +1272,13 @@
* @return the offset of the prefix of this import
*/
int get prefixOffset;
+
+ /**
+ * Return `true` if this import is for a deferred library.
+ *
+ * @return `true` if this import is for a deferred library
+ */
+ bool get isDeferred;
}
/**
@@ -1349,6 +1393,13 @@
bool get hasExtUri;
/**
+ * Return `true` if this library defines a top-level function named `loadLibrary`.
+ *
+ * @return `true` if this library defines a top-level function named `loadLibrary`
+ */
+ bool get hasLoadLibraryFunction;
+
+ /**
* 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.
*
@@ -1876,7 +1927,7 @@
*/
abstract class AngularElement implements ToolkitObjectElement {
/**
- * An empty array of angular elements.
+ * An empty array of Angular elements.
*/
static final List<AngularElement> EMPTY_ARRAY = new List<AngularElement>(0);
@@ -2087,6 +2138,87 @@
}
/**
+ * The interface `PolymerAttributeElement` defines an attribute in
+ * [PolymerTagHtmlElement].
+ *
+ * <pre>
+ * <polymer-element name="my-example" attributes='attrA attrB'>
+ * </polymer-element>
+ * </pre>
+ */
+abstract class PolymerAttributeElement implements PolymerElement {
+ /**
+ * An empty array of Polymer custom tag attributes.
+ */
+ static final List<PolymerAttributeElement> EMPTY_ARRAY = new List<PolymerAttributeElement>(0);
+
+ /**
+ * Return the [FieldElement] associated with this attribute. Maybe `null` if
+ * [PolymerTagDartElement] does not have a field associated with it.
+ */
+ FieldElement get field;
+}
+
+/**
+ * The interface `PolymerElement` defines the behavior of objects representing information
+ * about a Polymer specific element.
+ */
+abstract class PolymerElement implements ToolkitObjectElement {
+ /**
+ * An empty array of Polymer elements.
+ */
+ static final List<PolymerElement> EMPTY_ARRAY = new List<PolymerElement>(0);
+}
+
+/**
+ * The interface `PolymerTagDartElement` defines a Polymer custom tag in Dart.
+ *
+ * <pre>
+ * @CustomTag('my-example')
+ * </pre>
+ */
+abstract class PolymerTagDartElement implements PolymerElement {
+ /**
+ * Return the [ClassElement] that is associated with this Polymer custom tag. Not
+ * `null`, because [PolymerTagDartElement]s are created for [ClassElement]s
+ * marked with the `@CustomTag` annotation.
+ */
+ ClassElement get classElement;
+
+ /**
+ * Return the [PolymerTagHtmlElement] part of this Polymer custom tag. Maybe `null` if
+ * it has not been resolved yet or there are no corresponding Dart part defined.
+ */
+ PolymerTagHtmlElement get htmlElement;
+}
+
+/**
+ * The interface `PolymerTagHtmlElement` defines a Polymer custom tag in HTML.
+ *
+ * <pre>
+ * <polymer-element name="my-example" attributes='attrA attrB'>
+ * </polymer-element>
+ * </pre>
+ */
+abstract class PolymerTagHtmlElement implements PolymerElement {
+ /**
+ * An empty array of [PolymerTagHtmlElement]s.
+ */
+ static final List<PolymerTagHtmlElement> EMPTY_ARRAY = new List<PolymerTagHtmlElement>(0);
+
+ /**
+ * Return an array containing all of the attributes declared by this tag.
+ */
+ List<PolymerAttributeElement> get attributes;
+
+ /**
+ * Return the [PolymerTagDartElement] part on this Polymer custom tag. Maybe `null` if
+ * it has not been resolved yet or there are no corresponding Dart part defined.
+ */
+ PolymerTagDartElement get dartElement;
+}
+
+/**
* 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
* [RecursiveElementVisitor]). In addition, when an element of a specific type is visited not
@@ -2245,6 +2377,17 @@
R visitParameterElement(ParameterElement element) => visitLocalElement(element);
@override
+ R visitPolymerAttributeElement(PolymerAttributeElement element) => visitPolymerElement(element);
+
+ R visitPolymerElement(PolymerElement element) => visitToolkitObjectElement(element);
+
+ @override
+ R visitPolymerTagDartElement(PolymerTagDartElement element) => visitPolymerElement(element);
+
+ @override
+ R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) => visitPolymerElement(element);
+
+ @override
R visitPrefixElement(PrefixElement element) => visitElement(element);
@override
@@ -2431,6 +2574,24 @@
}
@override
+ R visitPolymerAttributeElement(PolymerAttributeElement element) {
+ element.visitChildren(this);
+ return null;
+ }
+
+ @override
+ R visitPolymerTagDartElement(PolymerTagDartElement element) {
+ element.visitChildren(this);
+ return null;
+ }
+
+ @override
+ R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) {
+ element.visitChildren(this);
+ return null;
+ }
+
+ @override
R visitPrefixElement(PrefixElement element) {
element.visitChildren(this);
return null;
@@ -2541,6 +2702,15 @@
R visitParameterElement(ParameterElement element) => null;
@override
+ R visitPolymerAttributeElement(PolymerAttributeElement element) => null;
+
+ @override
+ R visitPolymerTagDartElement(PolymerTagDartElement element) => null;
+
+ @override
+ R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) => null;
+
+ @override
R visitPrefixElement(PrefixElement element) => null;
@override
@@ -2652,6 +2822,16 @@
@override
accept(ElementVisitor visitor) => visitor.visitClassElement(this);
+ /**
+ * Set the toolkit specific information objects attached to this class.
+ *
+ * @param toolkitObjects the toolkit objects attached to this class
+ */
+ void addToolkitObjects(ToolkitObjectElement toolkitObject) {
+ (toolkitObject as ToolkitObjectElementImpl).enclosingElement = this;
+ _toolkitObjects = ArrayUtils.add(_toolkitObjects, toolkitObject);
+ }
+
@override
List<PropertyAccessorElement> get accessors => _accessors;
@@ -3008,18 +3188,6 @@
}
/**
- * Set the toolkit specific information objects attached to this class.
- *
- * @param toolkitObjects the toolkit objects attached to this class
- */
- void set toolkitObjects(List<ToolkitObjectElement> toolkitObjects) {
- for (ToolkitObjectElement toolkitObject in toolkitObjects) {
- (toolkitObject as ToolkitObjectElementImpl).enclosingElement = this;
- }
- this._toolkitObjects = toolkitObjects;
- }
-
- /**
* Set whether this class is defined by a typedef construct to correspond to the given value.
*
* @param isTypedef `true` if the class is defined by a typedef construct
@@ -3274,6 +3442,16 @@
@override
int get hashCode => source.hashCode;
+ @override
+ bool get hasLoadLibraryFunction {
+ for (int i = 0; i < _functions.length; i++) {
+ if (_functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Set the top-level accessors (getters and setters) contained in this compilation unit to the
* given accessors.
@@ -4958,6 +5136,11 @@
List<HtmlScriptElement> _scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
/**
+ * The [PolymerTagHtmlElement]s defined in the HTML file.
+ */
+ List<PolymerTagHtmlElement> _polymerTags = PolymerTagHtmlElement.EMPTY_ARRAY;
+
+ /**
* The source that corresponds to this HTML file.
*/
Source source;
@@ -4994,19 +5177,37 @@
ElementKind get kind => ElementKind.HTML;
@override
+ List<PolymerTagHtmlElement> get polymerTags => _polymerTags;
+
+ @override
List<HtmlScriptElement> get scripts => _scripts;
@override
int get hashCode => source.hashCode;
/**
+ * Set the [PolymerTagHtmlElement]s defined in the HTML file.
+ */
+ void set polymerTags(List<PolymerTagHtmlElement> polymerTags) {
+ if (polymerTags.length == 0) {
+ this._polymerTags = PolymerTagHtmlElement.EMPTY_ARRAY;
+ return;
+ }
+ for (PolymerTagHtmlElement tag in polymerTags) {
+ (tag as PolymerTagHtmlElementImpl).enclosingElement = this;
+ }
+ this._polymerTags = polymerTags;
+ }
+
+ /**
* Set the scripts contained in the HTML file to the given scripts.
*
* @param scripts the scripts
*/
void set scripts(List<HtmlScriptElement> scripts) {
if (scripts.length == 0) {
- scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
+ this._scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
+ return;
}
for (HtmlScriptElement script in scripts) {
(script as HtmlScriptElementImpl).enclosingElement = this;
@@ -5018,6 +5219,7 @@
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
safelyVisitChildren(_scripts, visitor);
+ safelyVisitChildren(_polymerTags, visitor);
}
@override
@@ -5088,6 +5290,18 @@
ElementKind get kind => ElementKind.IMPORT;
@override
+ bool get isDeferred => hasModifier(Modifier.DEFERRED);
+
+ /**
+ * Set whether this import is for a deferred library to correspond to the given value.
+ *
+ * @param isDeferred `true` if this import is for a deferred library
+ */
+ void set deferred(bool isDeferred) {
+ setModifier(Modifier.DEFERRED, isDeferred);
+ }
+
+ @override
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
safelyVisitChild(prefix, visitor);
@@ -5376,6 +5590,19 @@
int get hashCode => _definingCompilationUnit.hashCode;
@override
+ bool get hasLoadLibraryFunction {
+ if (_definingCompilationUnit.hasLoadLibraryFunction) {
+ return true;
+ }
+ for (int i = 0; i < _parts.length; i++) {
+ if (_parts[i].hasLoadLibraryFunction) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @override
bool get isAngularHtml => _isAngularHtml;
@override
@@ -5752,52 +5979,58 @@
static const Modifier CONST = const Modifier('CONST', 1);
/**
+ * Indicates that the import element represents a deferred library.
+ */
+ static const Modifier DEFERRED = const Modifier('DEFERRED', 2);
+
+ /**
* Indicates that the modifier 'factory' was applied to the element.
*/
- static const Modifier FACTORY = const Modifier('FACTORY', 2);
+ static const Modifier FACTORY = const Modifier('FACTORY', 3);
/**
* Indicates that the modifier 'final' was applied to the element.
*/
- static const Modifier FINAL = const Modifier('FINAL', 3);
+ static const Modifier FINAL = const Modifier('FINAL', 4);
/**
* Indicates that the pseudo-modifier 'get' was applied to the element.
*/
- static const Modifier GETTER = const Modifier('GETTER', 4);
+ static const Modifier GETTER = const Modifier('GETTER', 5);
/**
* A flag used for libraries indicating that the defining compilation unit contains at least one
* import directive whose URI uses the "dart-ext" scheme.
*/
- static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 5);
+ static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 6);
- static const Modifier MIXIN = const Modifier('MIXIN', 6);
+ static const Modifier MIXIN = const Modifier('MIXIN', 7);
- static const Modifier REFERENCES_SUPER = const Modifier('REFERENCES_SUPER', 7);
+ static const Modifier REFERENCES_SUPER = const Modifier('REFERENCES_SUPER', 8);
/**
* Indicates that the pseudo-modifier 'set' was applied to the element.
*/
- static const Modifier SETTER = const Modifier('SETTER', 8);
+ static const Modifier SETTER = const Modifier('SETTER', 9);
/**
* Indicates that the modifier 'static' was applied to the element.
*/
- static const Modifier STATIC = const Modifier('STATIC', 9);
+ static const Modifier STATIC = const Modifier('STATIC', 10);
/**
* Indicates that the element does not appear in the source code but was implicitly created. For
* example, if a class does not define any constructors, an implicit zero-argument constructor
* will be created and it will be marked as being synthetic.
*/
- static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 10);
+ static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 11);
- static const Modifier TYPEDEF = const Modifier('TYPEDEF', 11);
+ static const Modifier TYPEDEF = const Modifier('TYPEDEF', 12);
static const List<Modifier> values = const [
ABSTRACT,
CONST,
+ DEFERRED,
FACTORY,
FINAL,
GETTER,
@@ -8012,6 +8245,128 @@
}
/**
+ * Implementation of `PolymerAttributeElement`.
+ */
+class PolymerAttributeElementImpl extends PolymerElementImpl implements PolymerAttributeElement {
+ /**
+ * The [FieldElement] associated with this attribute.
+ */
+ FieldElement field;
+
+ /**
+ * Initialize a newly created Polymer attribute 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
+ */
+ PolymerAttributeElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+ @override
+ accept(ElementVisitor visitor) => visitor.visitPolymerAttributeElement(this);
+
+ @override
+ ElementKind get kind => ElementKind.POLYMER_ATTRIBUTE;
+}
+
+/**
+ * Implementation of `PolymerElement`.
+ */
+abstract class PolymerElementImpl extends ToolkitObjectElementImpl implements PolymerElement {
+ /**
+ * Initialize a newly created Polymer 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
+ */
+ PolymerElementImpl(String name, int nameOffset) : super(name, nameOffset);
+}
+
+/**
+ * Implementation of `PolymerTagDartElement`.
+ */
+class PolymerTagDartElementImpl extends PolymerElementImpl implements PolymerTagDartElement {
+ /**
+ * The [ClassElement] that is associated with this Polymer custom tag.
+ */
+ final ClassElement classElement;
+
+ /**
+ * The [PolymerTagHtmlElement] part of this Polymer custom tag. Maybe `null` if it has
+ * not been resolved yet or there are no corresponding Dart part defined.
+ */
+ PolymerTagHtmlElement htmlElement;
+
+ /**
+ * Initialize a newly created Dart part of a Polymer tag 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
+ */
+ PolymerTagDartElementImpl(String name, int nameOffset, this.classElement) : super(name, nameOffset);
+
+ @override
+ accept(ElementVisitor visitor) => visitor.visitPolymerTagDartElement(this);
+
+ @override
+ ElementKind get kind => ElementKind.POLYMER_TAG_DART;
+}
+
+/**
+ * Implementation of `PolymerTagHtmlElement`.
+ */
+class PolymerTagHtmlElementImpl extends PolymerElementImpl implements PolymerTagHtmlElement {
+ /**
+ * The [PolymerTagDartElement] part of this Polymer custom tag. Maybe `null` if it has
+ * not been resolved yet or there are no corresponding Dart part defined.
+ */
+ PolymerTagDartElement dartElement;
+
+ /**
+ * The array containing all of the attributes declared by this tag.
+ */
+ List<PolymerAttributeElement> _attributes = PolymerAttributeElement.EMPTY_ARRAY;
+
+ /**
+ * Initialize a newly created HTML part of a Polymer tag 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
+ */
+ PolymerTagHtmlElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+ @override
+ accept(ElementVisitor visitor) => visitor.visitPolymerTagHtmlElement(this);
+
+ @override
+ List<PolymerAttributeElement> get attributes => _attributes;
+
+ @override
+ ElementKind get kind => ElementKind.POLYMER_TAG_HTML;
+
+ /**
+ * Set an array containing all of the attributes declared by this tag.
+ *
+ * @param attributes the properties to set
+ */
+ void set attributes(List<PolymerAttributeElement> attributes) {
+ for (PolymerAttributeElement property in attributes) {
+ encloseElement(property as PolymerAttributeElementImpl);
+ }
+ this._attributes = attributes;
+ }
+
+ @override
+ void visitChildren(ElementVisitor visitor) {
+ safelyVisitChildren(_attributes, visitor);
+ super.visitChildren(visitor);
+ }
+}
+
+/**
* The unique instance of the class `BottomTypeImpl` implements the type `bottom`.
*/
class BottomTypeImpl extends TypeImpl {
@@ -8140,12 +8495,10 @@
if (secondTypes.length != firstTypes.length) {
return false;
}
- JavaIterator<MapEntry<String, DartType>> firstIterator = new JavaIterator(getMapEntrySet(firstTypes));
- JavaIterator<MapEntry<String, DartType>> secondIterator = new JavaIterator(getMapEntrySet(secondTypes));
- while (firstIterator.hasNext) {
- MapEntry<String, DartType> firstEntry = firstIterator.next();
- MapEntry<String, DartType> secondEntry = secondIterator.next();
- if (firstEntry.getKey() != secondEntry.getKey() || !(firstEntry.getValue() as TypeImpl).internalEquals(secondEntry.getValue(), visitedElementPairs)) {
+ MapIterator<String, DartType> firstIterator = SingleMapIterator.forMap(firstTypes);
+ MapIterator<String, DartType> secondIterator = SingleMapIterator.forMap(secondTypes);
+ while (firstIterator.moveNext() && secondIterator.moveNext()) {
+ if (firstIterator.key != secondIterator.key || !(firstIterator.value as TypeImpl).internalEquals(secondIterator.value, visitedElementPairs)) {
return false;
}
}
@@ -8221,15 +8574,15 @@
needsComma = false;
}
builder.append("{");
- for (MapEntry<String, DartType> entry in getMapEntrySet(namedParameterTypes)) {
+ for (MapIterator<String, DartType> iter = SingleMapIterator.forMap(namedParameterTypes); iter.moveNext();) {
if (needsComma) {
builder.append(", ");
} else {
needsComma = true;
}
- builder.append(entry.getKey());
+ builder.append(iter.key);
builder.append(": ");
- builder.append(entry.getValue().displayName);
+ builder.append(iter.value.displayName);
}
builder.append("}");
needsComma = true;
@@ -8400,14 +8753,13 @@
}
// Loop through each element in S verifying that T has a matching parameter name and that the
// corresponding type is more specific then the type in S.
- JavaIterator<MapEntry<String, DartType>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
- while (iteratorS.hasNext) {
- MapEntry<String, DartType> entryS = iteratorS.next();
- DartType typeT = namedTypesT[entryS.getKey()];
+ MapIterator<String, DartType> iteratorS = SingleMapIterator.forMap(namedTypesS);
+ while (iteratorS.moveNext()) {
+ DartType typeT = namedTypesT[iteratorS.key];
if (typeT == null) {
return false;
}
- if (!(typeT as TypeImpl).isMoreSpecificThan2(entryS.getValue(), withDynamic, visitedTypePairs)) {
+ if (!(typeT as TypeImpl).isMoreSpecificThan2(iteratorS.value, withDynamic, visitedTypePairs)) {
return false;
}
}
@@ -8520,15 +8872,15 @@
needsComma = false;
}
builder.append("{");
- for (MapEntry<String, DartType> entry in getMapEntrySet(namedParameterTypes)) {
+ for (MapIterator<String, DartType> iter = SingleMapIterator.forMap(namedParameterTypes); iter.moveNext();) {
if (needsComma) {
builder.append(", ");
} else {
needsComma = true;
}
- builder.append(entry.getKey());
+ builder.append(iter.key);
builder.append(": ");
- (entry.getValue() as TypeImpl).appendTo(builder);
+ (iter.value as TypeImpl).appendTo(builder);
}
builder.append("}");
needsComma = true;
@@ -8616,14 +8968,13 @@
}
// Loop through each element in S verifying that T has a matching parameter name and that the
// corresponding type is assignable to the type in S.
- JavaIterator<MapEntry<String, DartType>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
- while (iteratorS.hasNext) {
- MapEntry<String, DartType> entryS = iteratorS.next();
- DartType typeT = namedTypesT[entryS.getKey()];
+ MapIterator<String, DartType> iteratorS = SingleMapIterator.forMap(namedTypesS);
+ while (iteratorS.moveNext()) {
+ DartType typeT = namedTypesT[iteratorS.key];
if (typeT == null) {
return false;
}
- if (!(typeT as TypeImpl).isAssignableTo2(entryS.getValue(), visitedTypePairs)) {
+ if (!(typeT as TypeImpl).isAssignableTo2(iteratorS.value, visitedTypePairs)) {
return false;
}
}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index b16d920..18d00f7 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -827,6 +827,13 @@
bool get analyzeFunctionBodies;
/**
+ * Return `true` if analysis is to analyze Polymer.
+ *
+ * @return `true` if analysis is to analyze Polymer
+ */
+ bool get analyzePolymer;
+
+ /**
* Return the maximum number of sources for which AST structures should be kept in the cache.
*
* @return the maximum number of sources for which AST structures should be kept in the cache
@@ -1186,14 +1193,6 @@
}
/**
- * Return a collection containing all of the map entries mapping sources to cache entries. Clients
- * should not modify the returned collection.
- *
- * @return a collection containing all of the map entries mapping sources to cache entries
- */
- Iterable<MapEntry<Source, SourceEntry>> entrySet() => getMapEntrySet(_sourceMap);
-
- /**
* Return the entry associated with the given source.
*
* @param source the source whose entry is to be returned
@@ -1202,6 +1201,13 @@
SourceEntry get(Source source) => _sourceMap[source];
/**
+ * Return an iterator returning all of the map entries mapping sources to cache entries.
+ *
+ * @return an iterator returning all of the map entries mapping sources to cache entries
+ */
+ MapIterator<Source, SourceEntry> iterator() => new SingleMapIterator<Source, SourceEntry>(_sourceMap);
+
+ /**
* Associate the given entry with the given source.
*
* @param source the source with which the entry is to be associated
@@ -1402,6 +1408,11 @@
static final DataDescriptor<List<AnalysisError>> ANGULAR_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.ANGULAR_ERRORS");
/**
+ * The data descriptor representing the errors reported while building an element model.
+ */
+ static final DataDescriptor<List<AnalysisError>> BUILD_ELEMENT_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.BUILD_ELEMENT_ERRORS");
+
+ /**
* The data descriptor representing the list of libraries that contain this compilation unit.
*/
static final DataDescriptor<List<Source>> CONTAINING_LIBRARIES = new DataDescriptor<List<Source>>("DartEntry.CONTAINING_LIBRARIES");
@@ -1757,6 +1768,7 @@
ListUtilities.addAll(errors, _parseErrors);
DartEntryImpl_ResolutionState state = _resolutionState;
while (state != null) {
+ ListUtilities.addAll(errors, state._buildElementErrors);
ListUtilities.addAll(errors, state._resolutionErrors);
ListUtilities.addAll(errors, state._verificationErrors);
ListUtilities.addAll(errors, state._hints);
@@ -1880,7 +1892,9 @@
DartEntryImpl_ResolutionState state = _resolutionState;
while (state != null) {
if (librarySource == state._librarySource) {
- if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+ if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+ return state._buildElementErrorsState;
+ } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
return state._resolutionErrorsState;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
return state._resolvedUnitState;
@@ -1895,7 +1909,7 @@
state = state._nextState;
}
;
- if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
+ if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS) || identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
return CacheState.INVALID;
} else {
throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
@@ -1942,7 +1956,9 @@
DartEntryImpl_ResolutionState state = _resolutionState;
while (state != null) {
if (librarySource == state._librarySource) {
- if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+ if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+ return state._buildElementErrors;
+ } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
return state._resolutionErrors;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
return state._resolvedUnit;
@@ -1957,7 +1973,7 @@
state = state._nextState;
}
;
- if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
+ if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS) || identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
return AnalysisError.NO_ERRORS;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
return null;
@@ -1999,10 +2015,12 @@
return _sourceKindState == CacheState.INVALID;
} else if (identical(descriptor, DartEntry.TOKEN_STREAM)) {
return _tokenStreamState == CacheState.INVALID;
- } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
+ } else if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS) || 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) {
- if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+ if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+ return state._buildElementErrorsState == CacheState.INVALID;
+ } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
return state._resolutionErrorsState == CacheState.INVALID;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
return state._resolvedUnitState == CacheState.INVALID;
@@ -2361,7 +2379,10 @@
*/
void setStateInLibrary(DataDescriptor descriptor, Source librarySource, CacheState cacheState) {
DartEntryImpl_ResolutionState state = _getOrCreateResolutionState(librarySource);
- if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+ if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+ state._buildElementErrors = updatedValue(cacheState, state._buildElementErrors, AnalysisError.NO_ERRORS);
+ state._buildElementErrorsState = cacheState;
+ } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
state._resolutionErrors = updatedValue(cacheState, state._resolutionErrors, AnalysisError.NO_ERRORS);
state._resolutionErrorsState = cacheState;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
@@ -2435,7 +2456,10 @@
*/
void setValueInLibrary(DataDescriptor descriptor, Source librarySource, Object value) {
DartEntryImpl_ResolutionState state = _getOrCreateResolutionState(librarySource);
- if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+ if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+ state._buildElementErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
+ state._buildElementErrorsState = CacheState.VALID;
+ } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
state._resolutionErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
state._resolutionErrorsState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
@@ -2595,6 +2619,17 @@
Source _librarySource;
/**
+ * The state of the cached errors reported while building an element model.
+ */
+ CacheState _buildElementErrorsState = CacheState.INVALID;
+
+ /**
+ * The errors produced while building an element model, or an empty array if the errors are not
+ * currently cached.
+ */
+ List<AnalysisError> _buildElementErrors = AnalysisError.NO_ERRORS;
+
+ /**
* The state of the cached resolved compilation unit.
*/
CacheState _resolvedUnitState = CacheState.INVALID;
@@ -2646,6 +2681,8 @@
*/
void copyFrom(DartEntryImpl_ResolutionState other) {
_librarySource = other._librarySource;
+ _buildElementErrorsState = other._buildElementErrorsState;
+ _buildElementErrors = other._buildElementErrors;
_resolvedUnitState = other._resolvedUnitState;
_resolvedUnit = other._resolvedUnit;
_resolutionErrorsState = other._resolutionErrorsState;
@@ -2673,7 +2710,7 @@
}
}
- bool get hasErrorState => _resolvedUnitState == CacheState.ERROR || _resolutionErrorsState == CacheState.ERROR || _verificationErrorsState == CacheState.ERROR || _hintsState == CacheState.ERROR || (_nextState != null && _nextState.hasErrorState);
+ bool get hasErrorState => _buildElementErrorsState == CacheState.ERROR || _resolvedUnitState == CacheState.ERROR || _resolutionErrorsState == CacheState.ERROR || _verificationErrorsState == CacheState.ERROR || _hintsState == CacheState.ERROR || (_nextState != null && _nextState.hasErrorState);
/**
* Invalidate all of the resolution information associated with the compilation unit.
@@ -2681,6 +2718,8 @@
void invalidateAllResolutionInformation() {
_nextState = null;
_librarySource = null;
+ _buildElementErrorsState = CacheState.INVALID;
+ _buildElementErrors = AnalysisError.NO_ERRORS;
_resolvedUnitState = CacheState.INVALID;
_resolvedUnit = null;
_resolutionErrorsState = CacheState.INVALID;
@@ -2697,6 +2736,8 @@
* will not change the state of any parse results.
*/
void recordResolutionError() {
+ _buildElementErrorsState = CacheState.ERROR;
+ _buildElementErrors = AnalysisError.NO_ERRORS;
_resolvedUnitState = CacheState.ERROR;
_resolvedUnit = null;
_resolutionErrorsState = CacheState.ERROR;
@@ -2715,6 +2756,9 @@
* were invalidated before they could be recorded.
*/
void recordResolutionNotInProcess() {
+ if (_buildElementErrorsState == CacheState.IN_PROCESS) {
+ _buildElementErrorsState = CacheState.INVALID;
+ }
if (_resolvedUnitState == CacheState.IN_PROCESS) {
_resolvedUnitState = CacheState.INVALID;
}
@@ -2740,6 +2784,8 @@
*/
void writeOn(JavaStringBuilder builder) {
if (_librarySource != null) {
+ builder.append("; buildElementErrors = ");
+ builder.append(_buildElementErrorsState);
builder.append("; resolvedUnit = ");
builder.append(_resolvedUnitState);
builder.append("; resolutionErrors = ");
@@ -2840,6 +2886,16 @@
static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS = new DataDescriptor<List<AnalysisError>>("HtmlEntry.RESOLUTION_ERRORS");
/**
+ * The data descriptor representing the status of Polymer elements in the source.
+ */
+ static final DataDescriptor<List<AnalysisError>> POLYMER_BUILD_ERRORS = new DataDescriptor<List<AnalysisError>>("HtmlEntry.POLYMER_BUILD_ERRORS");
+
+ /**
+ * The data descriptor representing the errors reported during Polymer resolution.
+ */
+ static final DataDescriptor<List<AnalysisError>> POLYMER_RESOLUTION_ERRORS = new DataDescriptor<List<AnalysisError>>("HtmlEntry.POLYMER_RESOLUTION_ERRORS");
+
+ /**
* Return all of the errors associated with the compilation unit that are currently cached.
*
* @return all of the errors associated with the compilation unit
@@ -2978,6 +3034,28 @@
List<AnalysisError> _hints = AnalysisError.NO_ERRORS;
/**
+ * The state of the Polymer elements.
+ */
+ CacheState _polymerBuildErrorsState = CacheState.INVALID;
+
+ /**
+ * The hints produced while performing Polymer HTML elements building, or an empty array if the
+ * error are not currently cached.
+ */
+ List<AnalysisError> _polymerBuildErrors = AnalysisError.NO_ERRORS;
+
+ /**
+ * The state of the Polymer resolution errors.
+ */
+ CacheState _polymerResolutionErrorsState = CacheState.INVALID;
+
+ /**
+ * The hints produced while performing Polymer resolution, or an empty array if the error are not
+ * currently cached.
+ */
+ List<AnalysisError> _polymerResolutionErrors = AnalysisError.NO_ERRORS;
+
+ /**
* Flush any AST structures being maintained by this entry.
*/
void flushAstStructures() {
@@ -3020,6 +3098,16 @@
errors.add(error);
}
}
+ if (_polymerBuildErrors != null) {
+ for (AnalysisError error in _polymerBuildErrors) {
+ errors.add(error);
+ }
+ }
+ if (_polymerResolutionErrors != null) {
+ for (AnalysisError error in _polymerResolutionErrors) {
+ errors.add(error);
+ }
+ }
if (errors.length == 0) {
return AnalysisError.NO_ERRORS;
}
@@ -3066,6 +3154,10 @@
return _resolutionErrorsState;
} else if (identical(descriptor, HtmlEntry.HINTS)) {
return _hintsState;
+ } else if (identical(descriptor, HtmlEntry.POLYMER_BUILD_ERRORS)) {
+ return _polymerBuildErrorsState;
+ } else if (identical(descriptor, HtmlEntry.POLYMER_RESOLUTION_ERRORS)) {
+ return _polymerResolutionErrorsState;
}
return super.getState(descriptor);
}
@@ -3094,6 +3186,10 @@
return _resolutionErrors;
} else if (identical(descriptor, HtmlEntry.HINTS)) {
return _hints;
+ } else if (identical(descriptor, HtmlEntry.POLYMER_BUILD_ERRORS)) {
+ return _polymerBuildErrors;
+ } else if (identical(descriptor, HtmlEntry.POLYMER_RESOLUTION_ERRORS)) {
+ return _polymerResolutionErrors;
}
return super.getValue(descriptor);
}
@@ -3127,6 +3223,10 @@
_angularEntryState = CacheState.INVALID;
_angularErrors = AnalysisError.NO_ERRORS;
_angularErrorsState = CacheState.INVALID;
+ _polymerBuildErrors = AnalysisError.NO_ERRORS;
+ _polymerBuildErrorsState = CacheState.INVALID;
+ _polymerResolutionErrors = AnalysisError.NO_ERRORS;
+ _polymerResolutionErrorsState = CacheState.INVALID;
_element = null;
_elementState = CacheState.INVALID;
_resolutionErrors = AnalysisError.NO_ERRORS;
@@ -3163,6 +3263,8 @@
setState(HtmlEntry.ELEMENT, CacheState.ERROR);
setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.ERROR);
setState(HtmlEntry.HINTS, CacheState.ERROR);
+ setState(HtmlEntry.POLYMER_BUILD_ERRORS, CacheState.ERROR);
+ setState(HtmlEntry.POLYMER_RESOLUTION_ERRORS, CacheState.ERROR);
}
@override
@@ -3200,6 +3302,12 @@
} else if (identical(descriptor, HtmlEntry.HINTS)) {
_hints = updatedValue(state, _hints, AnalysisError.NO_ERRORS);
_hintsState = state;
+ } else if (identical(descriptor, HtmlEntry.POLYMER_BUILD_ERRORS)) {
+ _polymerBuildErrors = updatedValue(state, _polymerBuildErrors, null);
+ _polymerBuildErrorsState = state;
+ } else if (identical(descriptor, HtmlEntry.POLYMER_RESOLUTION_ERRORS)) {
+ _polymerResolutionErrors = updatedValue(state, _polymerResolutionErrors, null);
+ _polymerResolutionErrorsState = state;
} else {
super.setState(descriptor, state);
}
@@ -3240,6 +3348,12 @@
} else if (identical(descriptor, HtmlEntry.HINTS)) {
_hints = value as List<AnalysisError>;
_hintsState = CacheState.VALID;
+ } else if (identical(descriptor, HtmlEntry.POLYMER_BUILD_ERRORS)) {
+ _polymerBuildErrors = value as List<AnalysisError>;
+ _polymerBuildErrorsState = CacheState.VALID;
+ } else if (identical(descriptor, HtmlEntry.POLYMER_RESOLUTION_ERRORS)) {
+ _polymerResolutionErrors = value as List<AnalysisError>;
+ _polymerResolutionErrorsState = CacheState.VALID;
} else {
super.setValue(descriptor, value);
}
@@ -3265,16 +3379,20 @@
_resolvedUnit = other._resolvedUnit;
_referencedLibrariesState = other._referencedLibrariesState;
_referencedLibraries = other._referencedLibraries;
- _resolutionErrors = other._resolutionErrors;
_resolutionErrorsState = other._resolutionErrorsState;
+ _resolutionErrors = other._resolutionErrors;
_elementState = other._elementState;
_element = other._element;
- _hints = other._hints;
_hintsState = other._hintsState;
+ _hints = other._hints;
+ _polymerBuildErrorsState = other._polymerBuildErrorsState;
+ _polymerBuildErrors = other._polymerBuildErrors;
+ _polymerResolutionErrorsState = other._polymerResolutionErrorsState;
+ _polymerResolutionErrors = other._polymerResolutionErrors;
}
@override
- bool get hasErrorState => super.hasErrorState || _parsedUnitState == CacheState.ERROR || _resolvedUnitState == CacheState.ERROR || _parseErrorsState == CacheState.ERROR || _resolutionErrorsState == CacheState.ERROR || _referencedLibrariesState == CacheState.ERROR || _elementState == CacheState.ERROR || _angularErrorsState == CacheState.ERROR || _hintsState == CacheState.ERROR;
+ bool get hasErrorState => super.hasErrorState || _parsedUnitState == CacheState.ERROR || _resolvedUnitState == CacheState.ERROR || _parseErrorsState == CacheState.ERROR || _resolutionErrorsState == CacheState.ERROR || _referencedLibrariesState == CacheState.ERROR || _elementState == CacheState.ERROR || _angularErrorsState == CacheState.ERROR || _hintsState == CacheState.ERROR || _polymerBuildErrorsState == CacheState.ERROR || _polymerResolutionErrorsState == CacheState.ERROR;
@override
void writeOn(JavaStringBuilder builder) {
@@ -3300,6 +3418,10 @@
builder.append(_angularEntryState);
builder.append("; angularErrors = ");
builder.append(_angularErrorsState);
+ builder.append("; polymerBuildErrors = ");
+ builder.append(_polymerBuildErrorsState);
+ builder.append("; polymerResolutionErrors = ");
+ builder.append(_polymerResolutionErrorsState);
}
}
@@ -3940,9 +4062,10 @@
// only re-analyze those libraries.
// logInformation("Added Dart sources, invalidating all resolution information");
List<Source> sourcesToInvalidate = new List<Source>();
- for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
- Source source = mapEntry.getKey();
- SourceEntry sourceEntry = mapEntry.getValue();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ Source source = iterator.key;
+ SourceEntry sourceEntry = iterator.value;
if (!source.isInSystemLibrary && sourceEntry is DartEntry) {
sourcesToInvalidate.add(source);
}
@@ -4134,11 +4257,13 @@
InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) {
List<Source> sourcesToRemove = new List<Source>();
// Move sources in the specified directory to the new context
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- Source source = entry.getKey();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ Source source = iterator.key;
+ SourceEntry sourceEntry = iterator.value;
if (container.contains(source)) {
sourcesToRemove.add(source);
- newContext.addSourceInfo(source, entry.getValue().writableCopy);
+ newContext.addSourceInfo(source, sourceEntry.writableCopy);
}
}
return newContext;
@@ -4241,12 +4366,13 @@
if (sourceKind == SourceKind.LIBRARY) {
} else if (sourceKind == SourceKind.PART) {
List<Source> librarySources = getLibrariesContaining(source);
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- SourceEntry sourceEntry = entry.getValue();
+ MapIterator<Source, SourceEntry> partIterator = _cache.iterator();
+ while (partIterator.moveNext()) {
+ SourceEntry sourceEntry = partIterator.value;
if (sourceEntry.kind == SourceKind.HTML) {
List<Source> referencedLibraries = (sourceEntry as HtmlEntry).getValue(HtmlEntry.REFERENCED_LIBRARIES);
if (_containsAny(referencedLibraries, librarySources)) {
- htmlSources.add(entry.getKey());
+ htmlSources.add(partIterator.key);
}
}
}
@@ -4276,9 +4402,10 @@
// TODO(brianwilkerson) This needs to filter out libraries that do not reference dart:html,
// either directly or indirectly.
List<Source> sources = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- Source source = entry.getKey();
- SourceEntry sourceEntry = entry.getValue();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ Source source = iterator.key;
+ SourceEntry sourceEntry = iterator.value;
if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
// DartEntry dartEntry = (DartEntry) sourceEntry;
// if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && dartEntry.getValue(DartEntry.IS_CLIENT)) {
@@ -4293,9 +4420,10 @@
// TODO(brianwilkerson) This needs to filter out libraries that reference dart:html, either
// directly or indirectly.
List<Source> sources = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- Source source = entry.getKey();
- SourceEntry sourceEntry = entry.getValue();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ Source source = iterator.key;
+ SourceEntry sourceEntry = iterator.value;
if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
// DartEntry dartEntry = (DartEntry) sourceEntry;
// if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && !dartEntry.getValue(DartEntry.IS_CLIENT)) {
@@ -4317,14 +4445,15 @@
@override
List<Source> getLibrariesDependingOn(Source librarySource) {
List<Source> dependentLibraries = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- SourceEntry sourceEntry = entry.getValue();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ SourceEntry sourceEntry = iterator.value;
if (sourceEntry.kind == SourceKind.LIBRARY) {
if (_contains((sourceEntry as DartEntry).getValue(DartEntry.EXPORTED_LIBRARIES), librarySource)) {
- dependentLibraries.add(entry.getKey());
+ dependentLibraries.add(iterator.key);
}
if (_contains((sourceEntry as DartEntry).getValue(DartEntry.IMPORTED_LIBRARIES), librarySource)) {
- dependentLibraries.add(entry.getKey());
+ dependentLibraries.add(iterator.key);
}
}
}
@@ -4407,11 +4536,12 @@
@override
List<Source> get refactoringUnsafeSources {
List<Source> sources = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- SourceEntry sourceEntry = entry.getValue();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ SourceEntry sourceEntry = iterator.value;
if (sourceEntry is DartEntry) {
if (!sourceEntry.isRefactoringSafe) {
- sources.add(entry.getKey());
+ sources.add(iterator.key);
}
}
}
@@ -4467,8 +4597,9 @@
//
// Look for non-priority sources that need to be analyzed.
//
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- _getSourcesNeedingProcessing(entry.getKey(), entry.getValue(), false, hintsEnabled, sources);
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ _getSourcesNeedingProcessing(iterator.key, iterator.value, false, hintsEnabled, sources);
}
return new List<Source>.from(sources);
}
@@ -4477,12 +4608,12 @@
AnalysisContentStatistics get statistics {
bool hintsEnabled = _options.hint;
AnalysisContentStatisticsImpl statistics = new AnalysisContentStatisticsImpl();
- for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
- statistics.addSource(mapEntry.getKey());
- SourceEntry entry = mapEntry.getValue();
- if (entry is DartEntry) {
- Source source = mapEntry.getKey();
- DartEntry dartEntry = entry;
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ SourceEntry sourceEntry = iterator.value;
+ if (sourceEntry is DartEntry) {
+ Source source = iterator.key;
+ DartEntry dartEntry = sourceEntry;
SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
// get library independent values
statistics.putCacheItem(dartEntry, SourceEntry.LINE_INFO);
@@ -4509,8 +4640,8 @@
}
}
}
- } else if (entry is HtmlEntry) {
- HtmlEntry htmlEntry = entry;
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry;
statistics.putCacheItem(htmlEntry, SourceEntry.LINE_INFO);
statistics.putCacheItem(htmlEntry, HtmlEntry.PARSE_ERRORS);
statistics.putCacheItem(htmlEntry, HtmlEntry.PARSED_UNIT);
@@ -4559,12 +4690,13 @@
return;
}
// TODO(brianwilkerson) This does not lock against the other context's cacheLock.
- for (MapEntry<Source, SourceEntry> entry in (context as AnalysisContextImpl)._cache.entrySet()) {
- Source newSource = entry.getKey();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ Source newSource = iterator.key;
SourceEntry existingEntry = _getReadableSourceEntry(newSource);
if (existingEntry == null) {
// TODO(brianwilkerson) Decide whether we really need to copy the info.
- _cache.put(newSource, entry.getValue().writableCopy);
+ _cache.put(newSource, iterator.value.writableCopy);
} else {
}
}
@@ -4619,16 +4751,16 @@
@override
void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
- for (MapEntry<Source, LibraryElement> entry in getMapEntrySet(elementMap)) {
- Source librarySource = entry.getKey();
- LibraryElement library = entry.getValue();
+ for (MapIterator<Source, LibraryElement> iter = SingleMapIterator.forMap(elementMap); iter.moveNext();) {
+ Source librarySource = iter.key;
+ LibraryElement library = iter.value;
//
// Cache the element in the library's info.
//
DartEntry dartEntry = _getReadableDartEntry(librarySource);
if (dartEntry != null) {
DartEntryImpl dartCopy = dartEntry.writableCopy;
- _recordElementData(dartEntry, dartCopy, library, library.source, htmlSource);
+ _recordElementData(dartCopy, library, library.source, htmlSource);
_cache.put(librarySource, dartCopy);
}
}
@@ -4813,24 +4945,14 @@
CompilationUnit unit = library.getAST(source);
List<AnalysisError> errors = errorListener.getErrorsForSource(source);
LineInfo lineInfo = getLineInfo(source);
- DartEntry dartEntry = _cache.get(source) as DartEntry;
- int sourceTime = getModificationStamp(source);
- 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;
+ DartEntryImpl dartCopy = _cache.get(source).writableCopy as DartEntryImpl;
if (thrownException == null) {
dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
dartCopy.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
dartCopy.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource, errors);
if (source == librarySource) {
- _recordElementData(dartEntry, dartCopy, library.libraryElement, librarySource, htmlSource);
+ _recordElementData(dartCopy, library.libraryElement, librarySource, htmlSource);
}
_cache.storedAst(source);
} else {
@@ -4955,7 +5077,7 @@
dartCopy.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
dartCopy.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource, errors);
if (source == librarySource) {
- _recordElementData(dartEntry, dartCopy, library.libraryElement, librarySource, htmlSource);
+ _recordElementData(dartCopy, library.libraryElement, librarySource, htmlSource);
}
_cache.storedAst(source);
} else {
@@ -5044,8 +5166,9 @@
* @param container the source container containing the sources to be added to the list
*/
void _addSourcesInContainer(List<Source> sources, SourceContainer container) {
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- Source source = entry.getKey();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ Source source = iterator.key;
if (container.contains(source)) {
sources.add(source);
}
@@ -5536,6 +5659,42 @@
}
/**
+ * Create a [PolymerBuildHtmlTask] for the given source, marking the Polymer elements as
+ * being in-process.
+ *
+ * @param source the source whose content is to be processed
+ * @param htmlEntry the entry for the source
+ * @return task data representing the created task
+ */
+ AnalysisContextImpl_TaskData _createPolymerBuildHtmlTask(Source source, HtmlEntry htmlEntry) {
+ if (htmlEntry.getState(HtmlEntry.RESOLVED_UNIT) != CacheState.VALID) {
+ return _createResolveHtmlTask(source, htmlEntry);
+ }
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ htmlCopy.setState(HtmlEntry.POLYMER_BUILD_ERRORS, CacheState.IN_PROCESS);
+ _cache.put(source, htmlCopy);
+ return new AnalysisContextImpl_TaskData(new PolymerBuildHtmlTask(this, source, htmlCopy.modificationTime, htmlEntry.getValue(SourceEntry.LINE_INFO), htmlCopy.getValue(HtmlEntry.RESOLVED_UNIT)), false);
+ }
+
+ /**
+ * Create a [PolymerResolveHtmlTask] for the given source, marking the Polymer errors as
+ * being in-process.
+ *
+ * @param source the source whose content is to be resolved
+ * @param htmlEntry the entry for the source
+ * @return task data representing the created task
+ */
+ AnalysisContextImpl_TaskData _createPolymerResolveHtmlTask(Source source, HtmlEntry htmlEntry) {
+ if (htmlEntry.getState(HtmlEntry.RESOLVED_UNIT) != CacheState.VALID) {
+ return _createResolveHtmlTask(source, htmlEntry);
+ }
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ htmlCopy.setState(HtmlEntry.POLYMER_RESOLUTION_ERRORS, CacheState.IN_PROCESS);
+ _cache.put(source, htmlCopy);
+ return new AnalysisContextImpl_TaskData(new PolymerResolveHtmlTask(this, source, htmlCopy.modificationTime, htmlEntry.getValue(SourceEntry.LINE_INFO), htmlCopy.getValue(HtmlEntry.RESOLVED_UNIT)), false);
+ }
+
+ /**
* Create a [ResolveAngularComponentTemplateTask] for the given source, marking the angular
* errors as being in-process.
*
@@ -6182,6 +6341,21 @@
return _createResolveAngularComponentTemplateTask(source, htmlEntry);
}
}
+ //
+ // Polymer support
+ //
+ if (_options.analyzePolymer) {
+ // Build elements.
+ CacheState polymerBuildErrorsState = htmlEntry.getState(HtmlEntry.POLYMER_BUILD_ERRORS);
+ if (polymerBuildErrorsState == CacheState.INVALID || (isPriority && polymerBuildErrorsState == CacheState.FLUSHED)) {
+ return _createPolymerBuildHtmlTask(source, htmlEntry);
+ }
+ // Resolve references.
+ CacheState polymerResolutionErrorsState = htmlEntry.getState(HtmlEntry.POLYMER_RESOLUTION_ERRORS);
+ if (polymerResolutionErrorsState == CacheState.INVALID || (isPriority && polymerResolutionErrorsState == CacheState.FLUSHED)) {
+ return _createPolymerResolveHtmlTask(source, htmlEntry);
+ }
+ }
}
return new AnalysisContextImpl_TaskData(null, false);
}
@@ -6287,9 +6461,10 @@
*/
List<Source> _getSources(SourceKind kind) {
List<Source> sources = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- if (entry.getValue().kind == kind) {
- sources.add(entry.getKey());
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ if (iterator.value.kind == kind) {
+ sources.add(iterator.key);
}
}
return new List.from(sources);
@@ -6396,6 +6571,19 @@
}
}
}
+ // Polymer
+ if (_options.analyzePolymer) {
+ // Elements building.
+ CacheState polymerBuildErrorsState = htmlEntry.getState(HtmlEntry.POLYMER_BUILD_ERRORS);
+ if (polymerBuildErrorsState == CacheState.INVALID || (isPriority && polymerBuildErrorsState == CacheState.FLUSHED)) {
+ sources.add(source);
+ }
+ // Resolution.
+ CacheState polymerResolutionErrorsState = htmlEntry.getState(HtmlEntry.POLYMER_RESOLUTION_ERRORS);
+ if (polymerResolutionErrorsState == CacheState.INVALID || (isPriority && polymerResolutionErrorsState == CacheState.FLUSHED)) {
+ sources.add(source);
+ }
+ }
}
}
@@ -6406,19 +6594,20 @@
*/
void _invalidateAllResolutionInformation() {
Map<Source, List<Source>> oldPartMap = new Map<Source, List<Source>>();
- for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
- Source source = mapEntry.getKey();
- SourceEntry sourceEntry = mapEntry.getValue();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ Source source = iterator.key;
+ SourceEntry sourceEntry = iterator.value;
if (sourceEntry is HtmlEntry) {
HtmlEntryImpl htmlCopy = sourceEntry.writableCopy;
htmlCopy.invalidateAllResolutionInformation();
- mapEntry.setValue(htmlCopy);
+ iterator.value = htmlCopy;
} else if (sourceEntry is DartEntry) {
DartEntry dartEntry = sourceEntry;
oldPartMap[source] = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
DartEntryImpl dartCopy = dartEntry.writableCopy;
dartCopy.invalidateAllResolutionInformation();
- mapEntry.setValue(dartCopy);
+ iterator.value = dartCopy;
_workManager.add(source, SourcePriority.UNKNOWN);
}
}
@@ -6618,16 +6807,112 @@
}
/**
+ * Record the results produced by performing a [BuildDartElementModelTask]. 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 recorded results
+ * @throws AnalysisException if the results could not be recorded
+ */
+ DartEntry _recordBuildDartElementModelTask(BuildDartElementModelTask task) {
+ Source targetLibrary = task.targetLibrary;
+ List<ResolvableLibrary> builtLibraries = task.librariesInCycle;
+ AnalysisException thrownException = task.exception;
+ DartEntry targetEntry = null;
+ if (_allModificationTimesMatch(builtLibraries)) {
+ Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
+ RecordingErrorListener errorListener = task.errorListener;
+ for (ResolvableLibrary library in builtLibraries) {
+ Source librarySource = library.librarySource;
+ for (Source source in library.compilationUnitSources) {
+ CompilationUnit unit = library.getAST(source);
+ List<AnalysisError> errors = errorListener.getErrorsForSource(source);
+ LineInfo lineInfo = getLineInfo(source);
+ DartEntryImpl dartCopy = _cache.get(source).writableCopy as DartEntryImpl;
+ if (thrownException == null) {
+ dartCopy.setValueInLibrary(DartEntry.BUILD_ELEMENT_ERRORS, librarySource, errors);
+ if (source == librarySource) {
+ LibraryElementImpl libraryElement = library.libraryElement;
+ dartCopy.setValue(DartEntry.ELEMENT, libraryElement);
+ dartCopy.setValue(DartEntry.IS_LAUNCHABLE, libraryElement.entryPoint != null);
+ dartCopy.setValue(DartEntry.IS_CLIENT, _isClient(libraryElement, htmlSource, new Set<LibraryElement>()));
+ }
+ } else {
+ dartCopy.recordResolutionError();
+ _cache.remove(source);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ if (source != librarySource) {
+ _workManager.add(librarySource, SourcePriority.PRIORITY_PART);
+ }
+ if (source == targetLibrary) {
+ targetEntry = dartCopy;
+ }
+ ChangeNoticeImpl notice = _getNotice(source);
+ notice.compilationUnit = unit;
+ notice.setErrors(dartCopy.allErrors, lineInfo);
+ }
+ }
+ } else {
+ PrintStringWriter writer = new PrintStringWriter();
+ writer.println("Build element model results discarded for");
+ for (ResolvableLibrary library in builtLibraries) {
+ for (Source source in library.compilationUnitSources) {
+ DartEntry dartEntry = _getReadableDartEntry(source);
+ if (dartEntry != null) {
+ int resultTime = library.getModificationTime(source);
+ writer.println(" ${_debuggingString(source)}; sourceTime = ${getModificationStamp(source)}, resultTime = ${resultTime}, cacheTime = ${dartEntry.modificationTime}");
+ 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.recordResolutionNotInProcess();
+ } 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.recordResolutionError();
+ _cache.remove(source);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ if (source == targetLibrary) {
+ targetEntry = dartCopy;
+ }
+ } else {
+ writer.println(" ${_debuggingString(source)}; sourceTime = ${getModificationStamp(source)}, no entry");
+ }
+ }
+ }
+ _logInformation(writer.toString());
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ if (targetEntry == null) {
+ targetEntry = _getReadableDartEntry(targetLibrary);
+ if (targetEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${targetLibrary.fullName}");
+ }
+ }
+ return targetEntry;
+ }
+
+ /**
* Given a cache entry and a library element, record the library element and other information
* gleaned from the element in the cache entry.
*
- * @param dartEntry the original cache entry from which the copy was made
* @param dartCopy the cache entry in which data is to be recorded
* @param library the library element used to record information
* @param librarySource the source for the library used to record information
* @param htmlSource the source for the HTML library
*/
- void _recordElementData(DartEntry dartEntry, DartEntryImpl dartCopy, LibraryElement library, Source librarySource, Source htmlSource) {
+ void _recordElementData(DartEntryImpl dartCopy, LibraryElement library, Source librarySource, Source htmlSource) {
dartCopy.setValue(DartEntry.ELEMENT, library);
dartCopy.setValue(DartEntry.IS_LAUNCHABLE, library.entryPoint != null);
dartCopy.setValue(DartEntry.IS_CLIENT, _isClient(library, htmlSource, new Set<LibraryElement>()));
@@ -6742,9 +7027,9 @@
_cache.put(librarySource, dartCopy);
throw thrownException;
}
- for (MapEntry<Source, TimestampedData<List<AnalysisError>>> entry in getMapEntrySet(hintMap)) {
- Source unitSource = entry.getKey();
- TimestampedData<List<AnalysisError>> results = entry.getValue();
+ for (MapIterator<Source, TimestampedData<List<AnalysisError>>> iter = SingleMapIterator.forMap(hintMap); iter.moveNext();) {
+ Source unitSource = iter.key;
+ TimestampedData<List<AnalysisError>> results = iter.value;
SourceEntry sourceEntry = _cache.get(unitSource);
if (sourceEntry is! DartEntry) {
// This shouldn't be possible because we should never have performed the task if the source
@@ -7075,6 +7360,148 @@
}
/**
+ * Record the results produced by performing a [PolymerBuildHtmlTask]. 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
+ * @throws AnalysisException if the results could not be recorded
+ */
+ HtmlEntry _recordPolymerBuildHtmlTaskResults(PolymerBuildHtmlTask task) {
+ Source source = task.source;
+ AnalysisException thrownException = task.exception;
+ HtmlEntry htmlEntry = null;
+ SourceEntry sourceEntry = _cache.get(source);
+ 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 = getModificationStamp(source);
+ int resultTime = task.modificationTime;
+ if (sourceTime == resultTime) {
+ if (htmlEntry.modificationTime != sourceTime) {
+ // The source has changed without the context being notified. Simulate notification.
+ _sourceChanged(source);
+ htmlEntry = _getReadableHtmlEntry(source);
+ if (htmlEntry == null) {
+ throw new AnalysisException.con1("An HTML file became a non-HTML file: ${source.fullName}");
+ }
+ }
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ if (thrownException == null) {
+ htmlCopy.setValue(HtmlEntry.POLYMER_BUILD_ERRORS, task.errors);
+ // notify about errors
+ ChangeNoticeImpl notice = _getNotice(source);
+ notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO));
+ } else {
+ htmlCopy.recordResolutionError();
+ }
+ htmlCopy.exception = thrownException;
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ } else {
+ HtmlEntryImpl htmlCopy = htmlEntry.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.
+ //
+ htmlCopy.invalidateAllInformation();
+ htmlCopy.modificationTime = sourceTime;
+ _cache.removedAst(source);
+ } 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.
+ //
+ htmlCopy.recordResolutionError();
+ }
+ htmlCopy.exception = thrownException;
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return htmlEntry;
+ }
+
+ /**
+ * Record the results produced by performing a [PolymerResolveHtmlTask]. 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
+ * @throws AnalysisException if the results could not be recorded
+ */
+ HtmlEntry _recordPolymerResolveHtmlTaskResults(PolymerResolveHtmlTask task) {
+ Source source = task.source;
+ AnalysisException thrownException = task.exception;
+ HtmlEntry htmlEntry = null;
+ SourceEntry sourceEntry = _cache.get(source);
+ 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 = getModificationStamp(source);
+ int resultTime = task.modificationTime;
+ if (sourceTime == resultTime) {
+ if (htmlEntry.modificationTime != sourceTime) {
+ // The source has changed without the context being notified. Simulate notification.
+ _sourceChanged(source);
+ htmlEntry = _getReadableHtmlEntry(source);
+ if (htmlEntry == null) {
+ throw new AnalysisException.con1("An HTML file became a non-HTML file: ${source.fullName}");
+ }
+ }
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ if (thrownException == null) {
+ htmlCopy.setValue(HtmlEntry.POLYMER_RESOLUTION_ERRORS, task.errors);
+ // notify about errors
+ ChangeNoticeImpl notice = _getNotice(source);
+ notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO));
+ } else {
+ htmlCopy.recordResolutionError();
+ }
+ htmlCopy.exception = thrownException;
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ } else {
+ HtmlEntryImpl htmlCopy = htmlEntry.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.
+ //
+ htmlCopy.invalidateAllInformation();
+ htmlCopy.modificationTime = sourceTime;
+ _cache.removedAst(source);
+ } 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.
+ //
+ htmlCopy.recordResolutionError();
+ }
+ htmlCopy.exception = thrownException;
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return htmlEntry;
+ }
+
+ /**
* Record the results produced by performing a [ResolveAngularComponentTemplateTask]. If the
* results were computed from data that is now out-of-date, then the results will not be recorded.
*
@@ -7516,9 +7943,9 @@
* @param oldPartMap the table containing the parts associated with each library
*/
void _removeFromPartsUsingMap(Map<Source, List<Source>> oldPartMap) {
- for (MapEntry<Source, List<Source>> entry in getMapEntrySet(oldPartMap)) {
- Source librarySource = entry.getKey();
- List<Source> oldParts = entry.getValue();
+ for (MapIterator<Source, List<Source>> iter = SingleMapIterator.forMap(oldPartMap); iter.moveNext();) {
+ Source librarySource = iter.key;
+ List<Source> oldParts = iter.value;
for (int i = 0; i < oldParts.length; i++) {
Source partSource = oldParts[i];
if (partSource != librarySource) {
@@ -7667,9 +8094,10 @@
int consistencyCheckStart = JavaSystem.nanoTime();
List<Source> changedSources = new List<Source>();
List<Source> missingSources = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- Source source = entry.getKey();
- SourceEntry sourceEntry = entry.getValue();
+ MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ while (iterator.moveNext()) {
+ Source source = iterator.key;
+ SourceEntry sourceEntry = iterator.value;
int sourceTime = getModificationStamp(source);
if (sourceTime != sourceEntry.modificationTime) {
changedSources.add(source);
@@ -7716,6 +8144,9 @@
AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
@override
+ DartEntry visitBuildDartElementModelTask(BuildDartElementModelTask task) => AnalysisContextImpl_this._recordBuildDartElementModelTask(task);
+
+ @override
DartEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => AnalysisContextImpl_this._recordGenerateDartErrorsTask(task);
@override
@@ -7734,6 +8165,12 @@
HtmlEntry visitParseHtmlTask(ParseHtmlTask task) => AnalysisContextImpl_this._recordParseHtmlTaskResults(task);
@override
+ HtmlEntry visitPolymerBuildHtmlTask(PolymerBuildHtmlTask task) => AnalysisContextImpl_this._recordPolymerBuildHtmlTaskResults(task);
+
+ @override
+ HtmlEntry visitPolymerResolveHtmlTask(PolymerResolveHtmlTask task) => AnalysisContextImpl_this._recordPolymerResolveHtmlTaskResults(task);
+
+ @override
HtmlEntry visitResolveAngularComponentTemplateTask(ResolveAngularComponentTemplateTask task) => AnalysisContextImpl_this._recordResolveAngularComponentTemplateTaskResults(task);
@override
@@ -8419,6 +8856,11 @@
bool analyzeAngular = true;
/**
+ * A flag indicating whether analysis is to analyze Polymer.
+ */
+ bool analyzePolymer = true;
+
+ /**
* Initialize a newly created set of analysis options to have their default values.
*/
AnalysisOptionsImpl();
@@ -9836,11 +10278,6 @@
*/
class PerformanceStatistics {
/**
- * The [TimeCounter] for time spent in Angular analysis.
- */
- static TimeCounter angular = new TimeCounter();
-
- /**
* The [TimeCounter] for time spent in reading files.
*/
static TimeCounter io = new TimeCounter();
@@ -9861,6 +10298,16 @@
static TimeCounter resolve = new TimeCounter();
/**
+ * The [TimeCounter] for time spent in Angular analysis.
+ */
+ static TimeCounter angular = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in Polymer analysis.
+ */
+ static TimeCounter polymer = new TimeCounter();
+
+ /**
* The [TimeCounter] for time spent in error verifier.
*/
static TimeCounter errors = new TimeCounter();
@@ -9879,6 +10326,7 @@
parse = new TimeCounter();
resolve = new TimeCounter();
angular = new TimeCounter();
+ polymer = new TimeCounter();
errors = new TimeCounter();
hints = new TimeCounter();
}
@@ -9912,14 +10360,14 @@
* @return an array of errors (not `null`, contains no `null`s)
*/
List<AnalysisError> get errors {
- Iterable<MapEntry<Source, Set<AnalysisError>>> entrySet = getMapEntrySet(_errors);
- int numEntries = entrySet.length;
+ Iterable<Set<AnalysisError>> errorsSets = _errors.values;
+ int numEntries = errorsSets.length;
if (numEntries == 0) {
return AnalysisError.NO_ERRORS;
}
List<AnalysisError> resultList = new List<AnalysisError>();
- for (MapEntry<Source, Set<AnalysisError>> entry in entrySet) {
- resultList.addAll(entry.getValue());
+ for (Set<AnalysisError> errorsSet in errorsSets) {
+ resultList.addAll(errorsSet);
}
return new List.from(resultList);
}
@@ -11595,6 +12043,396 @@
}
/**
+ * Instances of the class [PolymerHtmlUnitBuilder] build Polymer specific elements.
+ */
+class PolymerHtmlUnitBuilder extends ht.RecursiveXmlVisitor<Object> {
+ /**
+ * These names are forbidden to use as a custom tag name.
+ *
+ * http://w3c.github.io/webcomponents/spec/custom/#concepts
+ */
+ static Set<String> _FORBIDDEN_TAG_NAMES = new Set();
+
+ static bool isValidAttributeName(String name) {
+ // cannot be empty
+ if (name.isEmpty) {
+ return false;
+ }
+ // check characters
+ int length = name.length;
+ for (int i = 0; i < length; i++) {
+ int c = name.codeUnitAt(i);
+ if (i == 0) {
+ if (!Character.isLetter(c)) {
+ return false;
+ }
+ } else {
+ if (!(Character.isLetterOrDigit(c) || c == 0x5F)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ static bool isValidTagName(String name) {
+ // cannot be empty
+ if (name.isEmpty) {
+ return false;
+ }
+ // check for forbidden name
+ if (_FORBIDDEN_TAG_NAMES.contains(name)) {
+ return false;
+ }
+ // check characters
+ int length = name.length;
+ bool hasDash = false;
+ for (int i = 0; i < length; i++) {
+ int c = name.codeUnitAt(i);
+ // check for '-'
+ if (c == 0x2D) {
+ hasDash = true;
+ }
+ // check character
+ if (i == 0) {
+ if (hasDash) {
+ return false;
+ }
+ if (!Character.isLetter(c)) {
+ return false;
+ }
+ } else {
+ if (!(Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F)) {
+ return false;
+ }
+ }
+ }
+ if (!hasDash) {
+ return false;
+ }
+ return true;
+ }
+
+ final InternalAnalysisContext _context;
+
+ TypeProvider _typeProvider;
+
+ final AnalysisErrorListener _errorListener;
+
+ final Source _source;
+
+ final LineInfo _lineInfo;
+
+ final ht.HtmlUnit _unit;
+
+ List<PolymerTagHtmlElement> _tagHtmlElements = [];
+
+ ht.XmlTagNode _elementNode;
+
+ String _elementName;
+
+ PolymerTagHtmlElementImpl _htmlElement;
+
+ PolymerTagDartElementImpl _dartElement;
+
+ PolymerHtmlUnitBuilder(this._context, this._errorListener, this._source, this._lineInfo, this._unit) {
+ this._typeProvider = _context.typeProvider;
+ }
+
+ /**
+ * Builds Polymer specific HTML elements.
+ */
+ void build() {
+ _unit.accept(this);
+ // set Polymer tags
+ HtmlElementImpl unitElement = _unit.element as HtmlElementImpl;
+ unitElement.polymerTags = new List.from(_tagHtmlElements);
+ }
+
+ @override
+ Object visitXmlTagNode(ht.XmlTagNode node) {
+ if (node.tag == "polymer-element") {
+ _createTagHtmlElement(node);
+ }
+ // visit children
+ return super.visitXmlTagNode(node);
+ }
+
+ void _createAttributeElements() {
+ // prepare "attributes" attribute
+ ht.XmlAttributeNode attributesAttribute = _elementNode.getAttribute("attributes");
+ if (attributesAttribute == null) {
+ return;
+ }
+ // check if there is a Dart part to resolve against it
+ if (_dartElement == null) {
+ // TODO(scheglov) maybe report error (if it is allowed at all to have element without Dart part)
+ return;
+ }
+ // prepare value of the "attributes" attribute
+ String attributesText = attributesAttribute.text;
+ if (attributesText.trim().isEmpty) {
+ _reportErrorForAttribute(attributesAttribute, PolymerCode.EMPTY_ATTRIBUTES, []);
+ return;
+ }
+ // prepare attribute name tokens
+ List<PolymerHtmlUnitBuilder_NameToken> nameTokens = [];
+ {
+ int index = 0;
+ int textOffset = attributesAttribute.textOffset;
+ int nameOffset = -1;
+ JavaStringBuilder nameBuilder = new JavaStringBuilder();
+ while (index < attributesText.length) {
+ int c = attributesText.codeUnitAt(index++);
+ if (Character.isWhitespace(c)) {
+ if (nameOffset != -1) {
+ nameTokens.add(new PolymerHtmlUnitBuilder_NameToken(nameOffset, nameBuilder.toString()));
+ nameBuilder = new JavaStringBuilder();
+ nameOffset = -1;
+ }
+ continue;
+ }
+ if (nameOffset == -1) {
+ nameOffset = textOffset + index - 1;
+ }
+ nameBuilder.appendChar(c);
+ }
+ if (nameOffset != -1) {
+ nameTokens.add(new PolymerHtmlUnitBuilder_NameToken(nameOffset, nameBuilder.toString()));
+ nameBuilder = new JavaStringBuilder();
+ }
+ }
+ // create attributes for name tokens
+ List<PolymerAttributeElement> attributes = [];
+ Set<String> definedNames = new Set();
+ ClassElement classElement = _dartElement.classElement;
+ for (PolymerHtmlUnitBuilder_NameToken nameToken in nameTokens) {
+ int offset = nameToken._offset;
+ // prepare name
+ String name = nameToken._value;
+ if (!isValidAttributeName(name)) {
+ _reportErrorForNameToken(nameToken, PolymerCode.INVALID_ATTRIBUTE_NAME, [name]);
+ continue;
+ }
+ if (!definedNames.add(name)) {
+ _reportErrorForNameToken(nameToken, PolymerCode.DUPLICATE_ATTRIBUTE_DEFINITION, [name]);
+ continue;
+ }
+ // create attribute
+ PolymerAttributeElementImpl attribute = new PolymerAttributeElementImpl(name, offset);
+ attributes.add(attribute);
+ // resolve field
+ FieldElement field = classElement.getField(name);
+ if (field == null) {
+ _reportErrorForNameToken(nameToken, PolymerCode.UNDEFINED_ATTRIBUTE_FIELD, [name, classElement.displayName]);
+ continue;
+ }
+ if (!_isPublishedField(field)) {
+ _reportErrorForNameToken(nameToken, PolymerCode.ATTRIBUTE_FIELD_NOT_PUBLISHED, [name, classElement.displayName]);
+ }
+ attribute.field = field;
+ }
+ _htmlElement.attributes = new List.from(attributes);
+ }
+
+ void _createTagHtmlElement(ht.XmlTagNode node) {
+ this._elementNode = node;
+ this._elementName = null;
+ this._htmlElement = null;
+ this._dartElement = null;
+ // prepare 'name' attribute
+ ht.XmlAttributeNode nameAttribute = node.getAttribute("name");
+ if (nameAttribute == null) {
+ _reportErrorForToken(node.tagToken, PolymerCode.MISSING_TAG_NAME, []);
+ return;
+ }
+ // prepare name
+ _elementName = nameAttribute.text;
+ if (!isValidTagName(_elementName)) {
+ _reportErrorForAttributeValue(nameAttribute, PolymerCode.INVALID_TAG_NAME, [_elementName]);
+ return;
+ }
+ // TODO(scheglov) Maybe check that at least one of "template" or "script" children.
+ // TODO(scheglov) Maybe check if more than one top-level "template".
+ // create HTML element
+ int nameOffset = nameAttribute.textOffset;
+ _htmlElement = new PolymerTagHtmlElementImpl(_elementName, nameOffset);
+ // bind to the corresponding Dart element
+ _dartElement = _findTagDartElement();
+ if (_dartElement != null) {
+ _htmlElement.dartElement = _dartElement;
+ _dartElement.htmlElement = _htmlElement;
+ }
+ // TODO(scheglov) create attributes
+ _createAttributeElements();
+ // done
+ _tagHtmlElements.add(_htmlElement);
+ }
+
+ /**
+ * Returns the [PolymerTagDartElement] that corresponds to the Polymer custom tag declared
+ * by the given [XmlTagNode].
+ */
+ PolymerTagDartElementImpl _findTagDartElement() {
+ LibraryElement dartLibraryElement = dartUnitElement;
+ if (dartLibraryElement == null) {
+ return null;
+ }
+ return _findTagDartElement_inLibrary(dartLibraryElement);
+ }
+
+ /**
+ * Returns the [PolymerTagDartElementImpl] declared in the given [LibraryElement] with
+ * the [elementName]. Maybe `null`.
+ */
+ PolymerTagDartElementImpl _findTagDartElement_inLibrary(LibraryElement library) {
+ try {
+ library.accept(new RecursiveElementVisitor_PolymerHtmlUnitBuilder_findTagDartElement_inLibrary(this));
+ } on PolymerHtmlUnitBuilder_FoundTagDartElementError catch (e) {
+ return e._result;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the only [LibraryElement] referenced by a direct `script` child. Maybe
+ * `null` if none.
+ */
+ LibraryElement get dartUnitElement {
+ // TODO(scheglov) Maybe check if more than one "script".
+ for (ht.XmlTagNode child in _elementNode.tagNodes) {
+ if (child is ht.HtmlScriptTagNode) {
+ HtmlScriptElement scriptElement = child.scriptElement;
+ if (scriptElement is ExternalHtmlScriptElement) {
+ Source scriptSource = scriptElement.scriptSource;
+ if (scriptSource != null) {
+ return _context.getLibraryElement(scriptSource);
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ bool _isPublishedAnnotation(ElementAnnotation annotation) {
+ Element element = annotation.element;
+ if (element != null && element.name == "published") {
+ return true;
+ }
+ return false;
+ }
+
+ bool _isPublishedField(FieldElement field) {
+ List<ElementAnnotation> annotations = field.metadata;
+ for (ElementAnnotation annotation in annotations) {
+ if (_isPublishedAnnotation(annotation)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Reports an error on the attribute's value, or (if absent) on the attribute's name.
+ */
+ void _reportErrorForAttribute(ht.XmlAttributeNode node, ErrorCode errorCode, List<Object> arguments) {
+ _reportErrorForOffset(node.offset, node.length, errorCode, arguments);
+ }
+
+ /**
+ * Reports an error on the attribute's value, or (if absent) on the attribute's name.
+ */
+ void _reportErrorForAttributeValue(ht.XmlAttributeNode node, ErrorCode errorCode, List<Object> arguments) {
+ ht.Token valueToken = node.valueToken;
+ if (valueToken == null || valueToken.isSynthetic) {
+ _reportErrorForAttribute(node, errorCode, arguments);
+ } else {
+ _reportErrorForToken(valueToken, errorCode, arguments);
+ }
+ }
+
+ void _reportErrorForNameToken(PolymerHtmlUnitBuilder_NameToken token, ErrorCode errorCode, List<Object> arguments) {
+ int offset = token._offset;
+ int length = token._value.length;
+ _reportErrorForOffset(offset, length, errorCode, arguments);
+ }
+
+ void _reportErrorForOffset(int offset, int length, ErrorCode errorCode, List<Object> arguments) {
+ _errorListener.onError(new AnalysisError.con2(_source, offset, length, errorCode, arguments));
+ }
+
+ void _reportErrorForToken(ht.Token token, ErrorCode errorCode, List<Object> arguments) {
+ int offset = token.offset;
+ int length = token.length;
+ _reportErrorForOffset(offset, length, errorCode, arguments);
+ }
+}
+
+class PolymerHtmlUnitBuilder_FoundTagDartElementError extends Error {
+ final PolymerTagDartElementImpl _result;
+
+ PolymerHtmlUnitBuilder_FoundTagDartElementError(this._result);
+}
+
+class PolymerHtmlUnitBuilder_NameToken {
+ final int _offset;
+
+ final String _value;
+
+ PolymerHtmlUnitBuilder_NameToken(this._offset, this._value);
+}
+
+class RecursiveElementVisitor_PolymerHtmlUnitBuilder_findTagDartElement_inLibrary extends RecursiveElementVisitor<Object> {
+ final PolymerHtmlUnitBuilder PolymerHtmlUnitBuilder_this;
+
+ RecursiveElementVisitor_PolymerHtmlUnitBuilder_findTagDartElement_inLibrary(this.PolymerHtmlUnitBuilder_this) : super();
+
+ @override
+ Object visitPolymerTagDartElement(PolymerTagDartElement element) {
+ if (element.name == PolymerHtmlUnitBuilder_this._elementName) {
+ throw new PolymerHtmlUnitBuilder_FoundTagDartElementError(element as PolymerTagDartElementImpl);
+ }
+ return null;
+ }
+}
+
+/**
+ * Instances of the class [PolymerHtmlUnitResolver] resolve Polymer specific
+ * [XmlTagNode]s and expressions.
+ *
+ * TODO(scheglov) implement it
+ */
+class PolymerHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
+ final InternalAnalysisContext _context;
+
+ TypeProvider _typeProvider;
+
+ final AnalysisErrorListener _errorListener;
+
+ final Source _source;
+
+ final LineInfo _lineInfo;
+
+ final ht.HtmlUnit _unit;
+
+ PolymerHtmlUnitResolver(this._context, this._errorListener, this._source, this._lineInfo, this._unit) {
+ this._typeProvider = _context.typeProvider;
+ }
+
+ /**
+ * Resolves Polymer specific features.
+ */
+ void resolveUnit() {
+ }
+
+ @override
+ Object visitXmlAttributeNode(ht.XmlAttributeNode node) => super.visitXmlAttributeNode(node);
+
+ @override
+ Object visitXmlTagNode(ht.XmlTagNode node) => super.visitXmlTagNode(node);
+}
+
+/**
* The abstract class `AnalysisTask` defines the behavior of objects used to perform an
* analysis task.
*/
@@ -11692,6 +12530,15 @@
*/
abstract class AnalysisTaskVisitor<E> {
/**
+ * Visit a [BuildDartElementModelTask].
+ *
+ * @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 visitBuildDartElementModelTask(BuildDartElementModelTask task);
+
+ /**
* Visit a [GenerateDartErrorsTask].
*
* @param task the task to be visited
@@ -11746,6 +12593,24 @@
E visitParseHtmlTask(ParseHtmlTask task);
/**
+ * Visit a [PolymerBuildHtmlTask].
+ *
+ * @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 visitPolymerBuildHtmlTask(PolymerBuildHtmlTask task);
+
+ /**
+ * Visit a [PolymerResolveHtmlTask].
+ *
+ * @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 visitPolymerResolveHtmlTask(PolymerResolveHtmlTask task);
+
+ /**
* Visit a [ResolveAngularComponentTemplateTask].
*
* @param task the task to be visited
@@ -11810,6 +12675,324 @@
}
/**
+ * Instances of the class `BuildDartElementModelTask` build the element models for all of the
+ * libraries in a cycle.
+ */
+class BuildDartElementModelTask extends AnalysisTask {
+ /**
+ * The library for which an element model was originally requested.
+ */
+ Source _targetLibrary;
+
+ /**
+ * The libraries that are part of the cycle to be resolved.
+ */
+ final List<ResolvableLibrary> librariesInCycle;
+
+ /**
+ * The listener to which analysis errors will be reported.
+ */
+ RecordingErrorListener _errorListener;
+
+ /**
+ * A source object representing the core library (dart:core).
+ */
+ Source _coreLibrarySource;
+
+ /**
+ * The object representing the core library.
+ */
+ ResolvableLibrary _coreLibrary;
+
+ /**
+ * A table mapping library sources to the information being maintained for those libraries.
+ */
+ Map<Source, ResolvableLibrary> _libraryMap = new Map<Source, ResolvableLibrary>();
+
+ /**
+ * 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 targetLibrary the library for which an element model was originally requested
+ * @param librariesInCycle the libraries that are part of the cycle to be resolved
+ */
+ BuildDartElementModelTask(InternalAnalysisContext context, Source targetLibrary, this.librariesInCycle) : super(context) {
+ this._errorListener = new RecordingErrorListener();
+ _coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
+ }
+
+ @override
+ accept(AnalysisTaskVisitor visitor) => visitor.visitBuildDartElementModelTask(this);
+
+ /**
+ * Return the listener to which analysis errors were (or will be) reported.
+ *
+ * @return the listener to which analysis errors were reported
+ */
+ RecordingErrorListener get errorListener => _errorListener;
+
+ /**
+ * Return the library for which an element model was originally requested.
+ *
+ * @return the library for which an element model was originally requested
+ */
+ Source get targetLibrary => _targetLibrary;
+
+ @override
+ String get taskDescription {
+ Source librarySource = librariesInCycle[0].librarySource;
+ if (librarySource == null) {
+ return "build an element model for unknown library";
+ }
+ return "build an element model for ${librarySource.fullName}";
+ }
+
+ @override
+ void internalPerform() {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.LibraryResolver.resolveLibrary");
+ try {
+ //
+ // Build the map of libraries that are known.
+ //
+ _libraryMap = _buildLibraryMap();
+ _coreLibrary = _libraryMap[_coreLibrarySource];
+ LibraryElement coreElement = _coreLibrary.libraryElement;
+ if (coreElement == null) {
+ throw new AnalysisException.con1("Could not resolve dart:core");
+ }
+ instrumentation.metric3("buildLibraryMap", "complete");
+ //
+ // Build the element models representing the libraries being resolved. This is done in three
+ // steps.
+ //
+ // 1. Build the basic element models without making any connections between elements other than
+ // the basic parent/child relationships. This includes building the elements representing the
+ // libraries.
+ //
+ _buildElementModels();
+ instrumentation.metric3("buildElementModels", "complete");
+ //
+ // 2. Build the elements for the import and export directives. This requires that we have the
+ // elements built for the referenced libraries, but because of the possibility of circular
+ // references needs to happen after all of the library elements have been created.
+ //
+ _buildDirectiveModels();
+ instrumentation.metric3("buildDirectiveModels", "complete");
+ //
+ // 3. Build the rest of the type model by connecting superclasses, mixins, and interfaces. This
+ // requires that we be able to compute the names visible in the libraries being resolved,
+ // which in turn requires that we have resolved the import directives.
+ //
+ _buildTypeHierarchies(new TypeProviderImpl(coreElement));
+ instrumentation.metric3("buildTypeHierarchies", "complete");
+ } finally {
+ instrumentation.log();
+ }
+ }
+
+ /**
+ * Build the element model representing the combinators declared by the given directive.
+ *
+ * @param directive the directive that declares the combinators
+ * @return an array containing the import combinators that were built
+ */
+ List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) {
+ List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
+ for (Combinator combinator in directive.combinators) {
+ if (combinator is HideCombinator) {
+ HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
+ hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
+ combinators.add(hide);
+ } else {
+ ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
+ show.offset = combinator.offset;
+ show.end = combinator.end;
+ show.shownNames = _getIdentifiers((combinator as ShowCombinator).shownNames);
+ combinators.add(show);
+ }
+ }
+ return new List.from(combinators);
+ }
+
+ /**
+ * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
+ * the import and export directives.
+ *
+ * @throws AnalysisException if the defining compilation unit for any of the libraries could not
+ * be accessed
+ */
+ void _buildDirectiveModels() {
+ AnalysisContext analysisContext = context;
+ for (ResolvableLibrary library in librariesInCycle) {
+ Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixElementImpl>();
+ List<ImportElement> imports = new List<ImportElement>();
+ List<ExportElement> exports = new List<ExportElement>();
+ for (Directive directive in library.definingCompilationUnit.directives) {
+ if (directive is ImportDirective) {
+ ImportDirective importDirective = directive;
+ String uriContent = importDirective.uriContent;
+ if (DartUriResolver.isDartExtUri(uriContent)) {
+ library.libraryElement.hasExtUri = true;
+ }
+ Source importedSource = importDirective.source;
+ if (importedSource != null && analysisContext.exists(importedSource)) {
+ // The imported source will be null if the URI in the import directive was invalid.
+ ResolvableLibrary importedLibrary = _libraryMap[importedSource];
+ if (importedLibrary != null) {
+ ImportElementImpl importElement = new ImportElementImpl(directive.offset);
+ StringLiteral uriLiteral = importDirective.uri;
+ if (uriLiteral != null) {
+ importElement.uriOffset = uriLiteral.offset;
+ importElement.uriEnd = uriLiteral.end;
+ }
+ importElement.uri = uriContent;
+ importElement.combinators = _buildCombinators(importDirective);
+ LibraryElement importedLibraryElement = importedLibrary.libraryElement;
+ if (importedLibraryElement != null) {
+ importElement.importedLibrary = importedLibraryElement;
+ }
+ SimpleIdentifier prefixNode = directive.prefix;
+ if (prefixNode != null) {
+ importElement.prefixOffset = prefixNode.offset;
+ String prefixName = prefixNode.name;
+ PrefixElementImpl prefix = nameToPrefixMap[prefixName];
+ if (prefix == null) {
+ prefix = new PrefixElementImpl(prefixNode);
+ nameToPrefixMap[prefixName] = prefix;
+ }
+ importElement.prefix = prefix;
+ prefixNode.staticElement = prefix;
+ }
+ directive.element = importElement;
+ imports.add(importElement);
+ if (analysisContext.computeKindOf(importedSource) != SourceKind.LIBRARY) {
+ _errorListener.onError(new AnalysisError.con2(library.librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, [uriLiteral.toSource()]));
+ }
+ }
+ }
+ } else if (directive is ExportDirective) {
+ ExportDirective exportDirective = directive;
+ Source exportedSource = exportDirective.source;
+ if (exportedSource != null && analysisContext.exists(exportedSource)) {
+ // The exported source will be null if the URI in the export directive was invalid.
+ ResolvableLibrary exportedLibrary = _libraryMap[exportedSource];
+ if (exportedLibrary != null) {
+ ExportElementImpl exportElement = new ExportElementImpl();
+ StringLiteral uriLiteral = exportDirective.uri;
+ if (uriLiteral != null) {
+ exportElement.uriOffset = uriLiteral.offset;
+ exportElement.uriEnd = uriLiteral.end;
+ }
+ exportElement.uri = exportDirective.uriContent;
+ exportElement.combinators = _buildCombinators(exportDirective);
+ LibraryElement exportedLibraryElement = exportedLibrary.libraryElement;
+ if (exportedLibraryElement != null) {
+ exportElement.exportedLibrary = exportedLibraryElement;
+ }
+ directive.element = exportElement;
+ exports.add(exportElement);
+ if (analysisContext.computeKindOf(exportedSource) != SourceKind.LIBRARY) {
+ _errorListener.onError(new AnalysisError.con2(library.librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, [uriLiteral.toSource()]));
+ }
+ }
+ }
+ }
+ }
+ Source librarySource = library.librarySource;
+ if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource) {
+ ImportElementImpl importElement = new ImportElementImpl(-1);
+ importElement.importedLibrary = _coreLibrary.libraryElement;
+ importElement.synthetic = true;
+ imports.add(importElement);
+ }
+ LibraryElementImpl libraryElement = library.libraryElement;
+ libraryElement.imports = new List.from(imports);
+ libraryElement.exports = new List.from(exports);
+ if (libraryElement.entryPoint == null) {
+ Namespace namespace = new NamespaceBuilder().createExportNamespaceForLibrary(libraryElement);
+ Element element = namespace.get(LibraryElementBuilder.ENTRY_POINT_NAME);
+ if (element is FunctionElement) {
+ libraryElement.entryPoint = element;
+ }
+ }
+ }
+ }
+
+ /**
+ * Build element models for all of the libraries in the current cycle.
+ *
+ * @throws AnalysisException if any of the element models cannot be built
+ */
+ void _buildElementModels() {
+ for (ResolvableLibrary library in librariesInCycle) {
+ LibraryElementBuilder builder = new LibraryElementBuilder(context, _errorListener);
+ LibraryElementImpl libraryElement = builder.buildLibrary2(library);
+ library.libraryElement = libraryElement;
+ }
+ }
+
+ /**
+ * Build a table mapping library sources to the resolvable libraries representing those libraries.
+ *
+ * @return the map that was built
+ */
+ Map<Source, ResolvableLibrary> _buildLibraryMap() {
+ Map<Source, ResolvableLibrary> libraryMap = new Map<Source, ResolvableLibrary>();
+ int libraryCount = librariesInCycle.length;
+ for (int i = 0; i < libraryCount; i++) {
+ ResolvableLibrary library = librariesInCycle[i];
+ library.errorListener = _errorListener;
+ libraryMap[library.librarySource] = library;
+ List<ResolvableLibrary> dependencies = library.importsAndExports;
+ int dependencyCount = dependencies.length;
+ for (int j = 0; j < dependencyCount; j++) {
+ ResolvableLibrary dependency = dependencies[j];
+ //dependency.setErrorListener(errorListener);
+ libraryMap[dependency.librarySource] = dependency;
+ }
+ }
+ return libraryMap;
+ }
+
+ /**
+ * Resolve the type hierarchy across all of the types declared in the libraries in the current
+ * cycle.
+ *
+ * @throws AnalysisException if any of the type hierarchies could not be resolved
+ */
+ void _buildTypeHierarchies(TypeProvider typeProvider) {
+ TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
+ try {
+ for (ResolvableLibrary library in librariesInCycle) {
+ for (ResolvableCompilationUnit unit in library.resolvableCompilationUnits) {
+ Source source = unit.source;
+ CompilationUnit ast = unit.compilationUnit;
+ TypeResolverVisitor visitor = new TypeResolverVisitor.con4(library, source, typeProvider);
+ ast.accept(visitor);
+ }
+ }
+ } finally {
+ timeCounter.stop();
+ }
+ }
+
+ /**
+ * Return an array containing the lexical identifiers associated with the nodes in the given list.
+ *
+ * @param names the AST nodes representing the identifiers
+ * @return the lexical identifiers associated with the nodes in the list
+ */
+ List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) {
+ int count = names.length;
+ List<String> identifiers = new List<String>(count);
+ for (int i = 0; i < count; i++) {
+ identifiers[i] = names[i].name;
+ }
+ return identifiers;
+ }
+}
+
+/**
* Instances of the class `GenerateDartErrorsTask` generate errors and warnings for a single
* Dart source.
*/
@@ -12576,6 +13759,122 @@
}
/**
+ * Instances of the class `PolymerBuildHtmlTask` build Polymer specific elements.
+ */
+class PolymerBuildHtmlTask extends AnalysisTask {
+ /**
+ * The source to build which Polymer HTML elements for.
+ */
+ final Source source;
+
+ /**
+ * The time at which the contents of the source were last modified.
+ */
+ final int modificationTime;
+
+ /**
+ * The line information associated with the source.
+ */
+ final LineInfo _lineInfo;
+
+ /**
+ * The HTML unit to be resolved.
+ */
+ final ht.HtmlUnit _unit;
+
+ /**
+ * The resolution errors that were discovered while building elements.
+ */
+ List<AnalysisError> _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 resolved
+ * @param modificationTime the time at which the contents of the source were last modified
+ * @param lineInfo the line information associated with the source
+ * @param unit the HTML unit to build Polymer elements for
+ */
+ PolymerBuildHtmlTask(InternalAnalysisContext context, this.source, this.modificationTime, this._lineInfo, this._unit) : super(context);
+
+ @override
+ accept(AnalysisTaskVisitor visitor) => visitor.visitPolymerBuildHtmlTask(this);
+
+ List<AnalysisError> get errors => _errors;
+
+ @override
+ String get taskDescription => "build Polymer elements ${source.fullName}";
+
+ @override
+ void internalPerform() {
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ PolymerHtmlUnitBuilder resolver = new PolymerHtmlUnitBuilder(context, errorListener, source, _lineInfo, _unit);
+ resolver.build();
+ _errors = errorListener.getErrorsForSource(source);
+ }
+}
+
+/**
+ * Instances of the class `PolymerResolveHtmlTask` performs Polymer specific HTML file
+ * resolution.
+ *
+ * TODO(scheglov) implement it
+ */
+class PolymerResolveHtmlTask extends AnalysisTask {
+ /**
+ * The source to be resolved.
+ */
+ final Source source;
+
+ /**
+ * The time at which the contents of the source were last modified.
+ */
+ final int modificationTime;
+
+ /**
+ * The line information associated with the source.
+ */
+ final LineInfo _lineInfo;
+
+ /**
+ * The HTML unit to be resolved.
+ */
+ final ht.HtmlUnit _unit;
+
+ /**
+ * The resolution errors that were discovered while resolving the source.
+ */
+ List<AnalysisError> _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 resolved
+ * @param modificationTime the time at which the contents of the source were last modified
+ * @param unit the HTML unit to be resolved
+ */
+ PolymerResolveHtmlTask(InternalAnalysisContext context, this.source, this.modificationTime, this._lineInfo, this._unit) : super(context);
+
+ @override
+ accept(AnalysisTaskVisitor visitor) => visitor.visitPolymerResolveHtmlTask(this);
+
+ List<AnalysisError> get errors => _errors;
+
+ @override
+ String get taskDescription => "resolve as Polymer ${source.fullName}";
+
+ @override
+ void internalPerform() {
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ PolymerHtmlUnitResolver resolver = new PolymerHtmlUnitResolver(context, errorListener, source, _lineInfo, _unit);
+ resolver.resolveUnit();
+ _errors = errorListener.getErrorsForSource(source);
+ }
+}
+
+/**
* Instances of the class `ResolveAngularComponentTemplateTask` resolve HTML template
* referenced by [AngularComponentElement].
*/
@@ -12640,7 +13939,7 @@
ht.HtmlUnit get resolvedUnit => _resolvedUnit;
@override
- String get taskDescription => "resolving Angular template ${source}";
+ String get taskDescription => "resolve as Angular template ${source}";
@override
void internalPerform() {
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index ace8cf6..e944834 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -138,6 +138,55 @@
}
/**
+ * The enumeration `PolymerCode` defines Polymer specific problems.
+ */
+class PolymerCode extends Enum<PolymerCode> implements ErrorCode {
+ static const PolymerCode ATTRIBUTE_FIELD_NOT_PUBLISHED = const PolymerCode('ATTRIBUTE_FIELD_NOT_PUBLISHED', 0, "Field '%s' in '%s' must be @published");
+
+ static const PolymerCode DUPLICATE_ATTRIBUTE_DEFINITION = const PolymerCode('DUPLICATE_ATTRIBUTE_DEFINITION', 1, "The attribute '%s' is already defined");
+
+ static const PolymerCode EMPTY_ATTRIBUTES = const PolymerCode('EMPTY_ATTRIBUTES', 2, "Empty 'attributes' attribute is useless");
+
+ static const PolymerCode INVALID_ATTRIBUTE_NAME = const PolymerCode('INVALID_ATTRIBUTE_NAME', 3, "'%s' is not a valid name for a custom element attribute");
+
+ static const PolymerCode INVALID_TAG_NAME = const PolymerCode('INVALID_TAG_NAME', 4, "'%s' is not a valid name for a custom element");
+
+ static const PolymerCode MISSING_TAG_NAME = const PolymerCode('MISSING_TAG_NAME', 5, "Missing tag name of the custom element. Please include an attribute like name='your-tag-name'");
+
+ static const PolymerCode UNDEFINED_ATTRIBUTE_FIELD = const PolymerCode('UNDEFINED_ATTRIBUTE_FIELD', 6, "There is no such field '%s' in '%s'");
+
+ static const List<PolymerCode> values = const [
+ ATTRIBUTE_FIELD_NOT_PUBLISHED,
+ DUPLICATE_ATTRIBUTE_DEFINITION,
+ EMPTY_ATTRIBUTES,
+ INVALID_ATTRIBUTE_NAME,
+ INVALID_TAG_NAME,
+ MISSING_TAG_NAME,
+ UNDEFINED_ATTRIBUTE_FIELD];
+
+ /**
+ * The template used to create the message to be displayed for this error.
+ */
+ final String message;
+
+ /**
+ * Initialize a newly created error code to have the given message.
+ *
+ * @param message the message template used to create the message to be displayed for the error
+ */
+ const PolymerCode(String name, int ordinal, this.message) : super(name, ordinal);
+
+ @override
+ String get correction => null;
+
+ @override
+ ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
+
+ @override
+ ErrorType get type => ErrorType.POLYMER;
+}
+
+/**
* The enumeration `AngularCode` defines Angular specific problems.
*/
class AngularCode extends Enum<AngularCode> implements ErrorCode {
@@ -648,39 +697,38 @@
static const HintCode IS_NOT_INT = const HintCode.con1('IS_NOT_INT', 10, "When compiled to JS, this test might return false when the left hand side is a double");
/**
+ * This hint is generated anywhere where the [StaticTypeWarningCode#INVALID_ASSIGNMENT]
+ * would have been generated, if we used propagated information for the warnings.
+ *
+ * @param rhsTypeName the name of the right hand side type
+ * @param lhsTypeName the name of the left hand side type
+ * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
+ */
+ static const HintCode INVALID_ASSIGNMENT = const HintCode.con1('INVALID_ASSIGNMENT', 11, "A value of type '%s' cannot be assigned to a variable of type '%s'");
+
+ /**
* Generate a hint for methods or functions that have a return type, but do not have a non-void
* return statement on all branches. At the end of methods or functions with no return, Dart
* implicitly returns `null`, avoiding these implicit returns is considered a best practice.
*
* @param returnType the name of the declared return type
*/
- static const HintCode MISSING_RETURN = const HintCode.con2('MISSING_RETURN', 11, "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 const HintCode MISSING_RETURN = const HintCode.con2('MISSING_RETURN', 12, "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 const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_GETTER', 12, "Getter does not override an inherited getter");
+ static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_GETTER', 13, "Getter does not override an inherited getter");
/**
* A method with the override annotation does not override an existing method.
*/
- static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_METHOD', 13, "Method does not override an inherited method");
+ static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_METHOD', 14, "Method does not override an inherited method");
/**
* A setter with the override annotation does not override an existing setter.
*/
- static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_SETTER', 14, "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
- * superclass- depending on where the superclass is (either in the same library, or out of the
- * same library), behavior can be different.
- *
- * @param memberType this is either "method", "getter" or "setter"
- * @param memberName some private member name
- * @param className the class name where the member is overriding the functionality
- */
- static const HintCode OVERRIDDING_PRIVATE_MEMBER = const HintCode.con1('OVERRIDDING_PRIVATE_MEMBER', 15, "The %s '%s' does not override the definition from '%s' because it is private and in a different library");
+ static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_SETTER', 15, "Setter does not override an inherited setter");
/**
* Hint for classes that override equals, but not hashCode.
@@ -783,11 +831,11 @@
IS_INT,
IS_NOT_DOUBLE,
IS_NOT_INT,
+ INVALID_ASSIGNMENT,
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,
TYPE_CHECK_IS_NULL,
@@ -924,6 +972,11 @@
*/
static const ErrorType ANGULAR = const ErrorType('ANGULAR', 7, ErrorSeverity.INFO);
+ /**
+ * Polymer specific semantic problems.
+ */
+ static const ErrorType POLYMER = const ErrorType('POLYMER', 8, ErrorSeverity.INFO);
+
static const List<ErrorType> values = const [
TODO,
HINT,
@@ -932,7 +985,8 @@
STATIC_WARNING,
STATIC_TYPE_WARNING,
SYNTACTIC_ERROR,
- ANGULAR];
+ ANGULAR,
+ POLYMER];
/**
* The severity of this type of error.
@@ -1454,11 +1508,16 @@
static const CompileTimeErrorCode IMPLICIT_THIS_REFERENCE_IN_INITIALIZER = const CompileTimeErrorCode.con1('IMPLICIT_THIS_REFERENCE_IN_INITIALIZER', 61, "Only static members can be accessed in initializers");
/**
+ * Speculative.
+ */
+ static const CompileTimeErrorCode IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION = const CompileTimeErrorCode.con1('IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION', 62, "The library '%s' defines a top-level function named 'loadLibrary' and therefore cannot be deferred");
+
+ /**
* SDK implementation libraries can be imported only by other SDK libraries.
*
* @param uri the uri pointing to a library
*/
- static const CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY = const CompileTimeErrorCode.con1('IMPORT_INTERNAL_LIBRARY', 62, "The library '%s' is internal and cannot be imported");
+ static const CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY = const CompileTimeErrorCode.con1('IMPORT_INTERNAL_LIBRARY', 63, "The library '%s' is internal and cannot be imported");
/**
* 14.1 Imports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -1466,7 +1525,7 @@
*
* @param uri the uri pointing to a non-library declaration
*/
- static const CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = const CompileTimeErrorCode.con1('IMPORT_OF_NON_LIBRARY', 63, "The imported library '%s' must not have a part-of directive");
+ static const CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = const CompileTimeErrorCode.con1('IMPORT_OF_NON_LIBRARY', 64, "The imported library '%s' must not have a part-of directive");
/**
* 13.9 Switch: It is a compile-time error if values of the expressions <i>e<sub>k</sub></i> are
@@ -1475,7 +1534,7 @@
* @param expressionSource the expression source code that is the unexpected type
* @param expectedType the name of the expected type
*/
- static const CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES = const CompileTimeErrorCode.con1('INCONSISTENT_CASE_EXPRESSION_TYPES', 64, "Case expressions must have the same types, '%s' is not a %s'");
+ static const CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES = const CompileTimeErrorCode.con1('INCONSISTENT_CASE_EXPRESSION_TYPES', 65, "Case expressions must have the same types, '%s' is not a %s'");
/**
* 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
@@ -1486,7 +1545,7 @@
* immediately enclosing class
* @see #INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD
*/
- static const CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = const CompileTimeErrorCode.con1('INITIALIZER_FOR_NON_EXISTANT_FIELD', 65, "'%s' is not a variable in the enclosing class");
+ static const CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = const CompileTimeErrorCode.con1('INITIALIZER_FOR_NON_EXISTANT_FIELD', 66, "'%s' is not a variable in the enclosing class");
/**
* 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
@@ -1497,7 +1556,7 @@
* enclosing class
* @see #INITIALIZING_FORMAL_FOR_STATIC_FIELD
*/
- static const CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD = const CompileTimeErrorCode.con1('INITIALIZER_FOR_STATIC_FIELD', 66, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
+ static const CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD = const CompileTimeErrorCode.con1('INITIALIZER_FOR_STATIC_FIELD', 67, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
/**
* 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
@@ -1509,7 +1568,7 @@
* @see #INITIALIZING_FORMAL_FOR_STATIC_FIELD
* @see #INITIALIZER_FOR_NON_EXISTANT_FIELD
*/
- static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD = const CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD', 67, "'%s' is not a variable in the enclosing class");
+ static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD = const CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD', 68, "'%s' is not a variable in the enclosing class");
/**
* 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
@@ -1520,20 +1579,20 @@
* enclosing class
* @see #INITIALIZER_FOR_STATIC_FIELD
*/
- static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD = const CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_STATIC_FIELD', 68, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
+ static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD = const CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_STATIC_FIELD', 69, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
/**
* 12.30 Identifier Reference: Otherwise, e is equivalent to the property extraction
* <b>this</b>.<i>id</i>.
*/
- static const CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC = const CompileTimeErrorCode.con1('INSTANCE_MEMBER_ACCESS_FROM_STATIC', 69, "Instance member cannot be accessed from static method");
+ static const CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC = const CompileTimeErrorCode.con1('INSTANCE_MEMBER_ACCESS_FROM_STATIC', 70, "Instance member cannot be accessed from static method");
/**
* 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
* character @, followed by a constant expression that must be either a reference to a
* compile-time constant variable, or a call to a constant constructor.
*/
- static const CompileTimeErrorCode INVALID_ANNOTATION = const CompileTimeErrorCode.con1('INVALID_ANNOTATION', 70, "Annotation can be only constant variable or constant constructor invocation");
+ static const CompileTimeErrorCode INVALID_ANNOTATION = const CompileTimeErrorCode.con1('INVALID_ANNOTATION', 71, "Annotation can be only constant variable or constant constructor invocation");
/**
* TODO(brianwilkerson) Remove this when we have decided on how to report errors in compile-time
@@ -1541,26 +1600,26 @@
*
* See TODOs in ConstantVisitor
*/
- static const CompileTimeErrorCode INVALID_CONSTANT = const CompileTimeErrorCode.con1('INVALID_CONSTANT', 71, "Invalid constant value");
+ static const CompileTimeErrorCode INVALID_CONSTANT = const CompileTimeErrorCode.con1('INVALID_CONSTANT', 72, "Invalid constant value");
/**
* 7.6 Constructors: It is a compile-time error if the name of a constructor is not a constructor
* name.
*/
- static const CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = const CompileTimeErrorCode.con1('INVALID_CONSTRUCTOR_NAME', 72, "Invalid constructor name");
+ static const CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = const CompileTimeErrorCode.con1('INVALID_CONSTRUCTOR_NAME', 73, "Invalid constructor name");
/**
* 7.6.2 Factories: It is a compile-time error if <i>M</i> is not the name of the immediately
* enclosing class.
*/
- static const CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = const CompileTimeErrorCode.con1('INVALID_FACTORY_NAME_NOT_A_CLASS', 73, "The name of the immediately enclosing class expected");
+ static const CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = const CompileTimeErrorCode.con1('INVALID_FACTORY_NAME_NOT_A_CLASS', 74, "The name of the immediately enclosing class expected");
/**
* 12.10 This: It is a compile-time error if this appears in a top-level function or variable
* initializer, in a factory constructor, or in a static method or variable initializer, or in the
* initializer of an instance variable.
*/
- static const CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = const CompileTimeErrorCode.con1('INVALID_REFERENCE_TO_THIS', 74, "Invalid reference to 'this' expression");
+ static const CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = const CompileTimeErrorCode.con1('INVALID_REFERENCE_TO_THIS', 75, "Invalid reference to 'this' expression");
/**
* 12.6 Lists: It is a compile time error if the type argument of a constant list literal includes
@@ -1568,7 +1627,7 @@
*
* @name the name of the type parameter
*/
- static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = const CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 75, "Constant list literals cannot include a type parameter as a type argument, such as '%s'");
+ static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = const CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 76, "Constant list literals cannot include a type parameter as a type argument, such as '%s'");
/**
* 12.7 Maps: It is a compile time error if the type arguments of a constant map literal include a
@@ -1576,7 +1635,7 @@
*
* @name the name of the type parameter
*/
- static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = const CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 76, "Constant map literals cannot include a type parameter as a type argument, such as '%s'");
+ static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = const CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 77, "Constant map literals cannot include a type parameter as a type argument, such as '%s'");
/**
* 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -1591,7 +1650,7 @@
* @param uri the URI that is invalid
* @see #URI_DOES_NOT_EXIST
*/
- static const CompileTimeErrorCode INVALID_URI = const CompileTimeErrorCode.con1('INVALID_URI', 77, "Invalid URI syntax: '%s'");
+ static const CompileTimeErrorCode INVALID_URI = const CompileTimeErrorCode.con1('INVALID_URI', 78, "Invalid URI syntax: '%s'");
/**
* 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
@@ -1602,7 +1661,7 @@
*
* @param labelName the name of the unresolvable label
*/
- static const CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = const CompileTimeErrorCode.con1('LABEL_IN_OUTER_SCOPE', 78, "Cannot reference label '%s' declared in an outer method");
+ static const CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = const CompileTimeErrorCode.con1('LABEL_IN_OUTER_SCOPE', 79, "Cannot reference label '%s' declared in an outer method");
/**
* 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
@@ -1613,7 +1672,7 @@
*
* @param labelName the name of the unresolvable label
*/
- static const CompileTimeErrorCode LABEL_UNDEFINED = const CompileTimeErrorCode.con1('LABEL_UNDEFINED', 79, "Cannot reference undefined label '%s'");
+ static const CompileTimeErrorCode LABEL_UNDEFINED = const CompileTimeErrorCode.con1('LABEL_UNDEFINED', 80, "Cannot reference undefined label '%s'");
/**
* 12.6 Lists: A run-time list literal <<i>E</i>> [<i>e<sub>1</sub></i> ...
@@ -1627,7 +1686,7 @@
* It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 <=
* j <= m</i>.
*/
- static const CompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 80, "The element type '%s' cannot be assigned to the list type '%s'");
+ static const CompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 81, "The element type '%s' cannot be assigned to the list type '%s'");
/**
* 12.7 Map: A run-time map literal <<i>K</i>, <i>V</i>> [<i>k<sub>1</sub></i> :
@@ -1641,7 +1700,7 @@
* It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 <=
* j <= m</i>.
*/
- static const CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 81, "The element type '%s' cannot be assigned to the map key type '%s'");
+ static const CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 82, "The element type '%s' cannot be assigned to the map key type '%s'");
/**
* 12.7 Map: A run-time map literal <<i>K</i>, <i>V</i>> [<i>k<sub>1</sub></i> :
@@ -1655,13 +1714,13 @@
* It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 <=
* j <= m</i>.
*/
- static const CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 82, "The element type '%s' cannot be assigned to the map value type '%s'");
+ static const CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 83, "The element type '%s' cannot be assigned to the map value type '%s'");
/**
* 7 Classes: It is a compile time error if a class <i>C</i> declares a member with the same name
* as <i>C</i>.
*/
- static const CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = const CompileTimeErrorCode.con1('MEMBER_WITH_CLASS_NAME', 83, "Class members cannot have the same name as the enclosing class");
+ static const CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = const CompileTimeErrorCode.con1('MEMBER_WITH_CLASS_NAME', 84, "Class members cannot have the same name as the enclosing class");
/**
* 7.2 Getters: It is a compile-time error if a class has both a getter and a method with the same
@@ -1669,17 +1728,17 @@
*
* @param name the conflicting name of the getter and method
*/
- static const CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME = const CompileTimeErrorCode.con1('METHOD_AND_GETTER_WITH_SAME_NAME', 84, "'%s' cannot be used to name a method, there is already a getter with the same name");
+ static const CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME = const CompileTimeErrorCode.con1('METHOD_AND_GETTER_WITH_SAME_NAME', 85, "'%s' cannot be used to name a method, there is already a getter with the same name");
/**
* 12.1 Constants: A constant expression is ... a constant list literal.
*/
- static const CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL = const CompileTimeErrorCode.con1('MISSING_CONST_IN_LIST_LITERAL', 85, "List literals must be prefixed with 'const' when used as a constant expression");
+ static const CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL = const CompileTimeErrorCode.con1('MISSING_CONST_IN_LIST_LITERAL', 86, "List literals must be prefixed with 'const' when used as a constant expression");
/**
* 12.1 Constants: A constant expression is ... a constant map literal.
*/
- static const CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL = const CompileTimeErrorCode.con1('MISSING_CONST_IN_MAP_LITERAL', 86, "Map literals must be prefixed with 'const' when used as a constant expression");
+ static const CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL = const CompileTimeErrorCode.con1('MISSING_CONST_IN_MAP_LITERAL', 87, "Map literals must be prefixed with 'const' when used as a constant expression");
/**
* 9 Mixins: It is a compile-time error if a declared or derived mixin explicitly declares a
@@ -1687,7 +1746,7 @@
*
* @param typeName the name of the mixin that is invalid
*/
- static const CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = const CompileTimeErrorCode.con1('MIXIN_DECLARES_CONSTRUCTOR', 87, "The class '%s' cannot be used as a mixin because it declares a constructor");
+ static const CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = const CompileTimeErrorCode.con1('MIXIN_DECLARES_CONSTRUCTOR', 88, "The class '%s' cannot be used as a mixin because it declares a constructor");
/**
* 9 Mixins: It is a compile-time error if a mixin is derived from a class whose superclass is not
@@ -1695,7 +1754,7 @@
*
* @param typeName the name of the mixin that is invalid
*/
- static const CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = const CompileTimeErrorCode.con1('MIXIN_INHERITS_FROM_NOT_OBJECT', 88, "The class '%s' cannot be used as a mixin because it extends a class other than Object");
+ static const CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = const CompileTimeErrorCode.con1('MIXIN_INHERITS_FROM_NOT_OBJECT', 89, "The class '%s' cannot be used as a mixin because it extends a class other than Object");
/**
* 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
@@ -1714,43 +1773,43 @@
* @param typeName the name of the type that cannot be extended
* @see #IMPLEMENTS_DISALLOWED_CLASS
*/
- static const CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS = const CompileTimeErrorCode.con1('MIXIN_OF_DISALLOWED_CLASS', 89, "Classes cannot mixin '%s'");
+ static const CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS = const CompileTimeErrorCode.con1('MIXIN_OF_DISALLOWED_CLASS', 90, "Classes cannot mixin '%s'");
/**
* 9.1 Mixin Application: It is a compile-time error if <i>M</i> does not denote a class or mixin
* available in the immediately enclosing scope.
*/
- static const CompileTimeErrorCode MIXIN_OF_NON_CLASS = const CompileTimeErrorCode.con1('MIXIN_OF_NON_CLASS', 90, "Classes can only mixin other classes");
+ static const CompileTimeErrorCode MIXIN_OF_NON_CLASS = const CompileTimeErrorCode.con1('MIXIN_OF_NON_CLASS', 91, "Classes can only mixin other classes");
/**
* 9 Mixins: It is a compile-time error if a declared or derived mixin refers to super.
*/
- static const CompileTimeErrorCode MIXIN_REFERENCES_SUPER = const CompileTimeErrorCode.con1('MIXIN_REFERENCES_SUPER', 91, "The class '%s' cannot be used as a mixin because it references 'super'");
+ static const CompileTimeErrorCode MIXIN_REFERENCES_SUPER = const CompileTimeErrorCode.con1('MIXIN_REFERENCES_SUPER', 92, "The class '%s' cannot be used as a mixin because it references 'super'");
/**
* 9.1 Mixin Application: It is a compile-time error if <i>S</i> does not denote a class available
* in the immediately enclosing scope.
*/
- static const CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = const CompileTimeErrorCode.con1('MIXIN_WITH_NON_CLASS_SUPERCLASS', 92, "Mixin can only be applied to class");
+ static const CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = const CompileTimeErrorCode.con1('MIXIN_WITH_NON_CLASS_SUPERCLASS', 93, "Mixin can only be applied to class");
/**
* 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
* only action is to invoke another generative constructor.
*/
- static const CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = const CompileTimeErrorCode.con1('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS', 93, "Constructor may have at most one 'this' redirection");
+ static const CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = const CompileTimeErrorCode.con1('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS', 94, "Constructor may have at most one 'this' redirection");
/**
* 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. Then <i>k</i> may
* include at most one superinitializer in its initializer list or a compile time error occurs.
*/
- static const CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = const CompileTimeErrorCode.con1('MULTIPLE_SUPER_INITIALIZERS', 94, "Constructor may have at most one 'super' initializer");
+ static const CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = const CompileTimeErrorCode.con1('MULTIPLE_SUPER_INITIALIZERS', 95, "Constructor may have at most one 'super' initializer");
/**
* 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
* character @, followed by a constant expression that must be either a reference to a
* compile-time constant variable, or a call to a constant constructor.
*/
- static const CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS = const CompileTimeErrorCode.con1('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS', 95, "Annotation creation must have arguments");
+ static const CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS = const CompileTimeErrorCode.con1('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS', 96, "Annotation creation must have arguments");
/**
* 7.6.1 Generative Constructors: If no superinitializer is provided, an implicit superinitializer
@@ -1760,7 +1819,7 @@
* 7.6.1 Generative constructors. It is a compile-time error if class <i>S</i> does not declare a
* generative constructor named <i>S</i> (respectively <i>S.id</i>)
*/
- static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = const CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 96, "The class '%s' does not have a default constructor");
+ static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = const CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 97, "The class '%s' does not have a default constructor");
/**
* 7.6 Constructors: Iff no constructor is specified for a class <i>C</i>, it implicitly has a
@@ -1769,13 +1828,13 @@
* 7.6.1 Generative constructors. It is a compile-time error if class <i>S</i> does not declare a
* generative constructor named <i>S</i> (respectively <i>S.id</i>)
*/
- static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = const CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 97, "The class '%s' does not have a default constructor");
+ static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = const CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 98, "The class '%s' does not have a default constructor");
/**
* 13.2 Expression Statements: It is a compile-time error if a non-constant map literal that has
* no explicit type arguments appears in a place where a statement is expected.
*/
- static const CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = const CompileTimeErrorCode.con1('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 98, "A non-constant map literal without type arguments cannot be used as an expression statement");
+ static const CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = const CompileTimeErrorCode.con1('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 99, "A non-constant map literal without type arguments cannot be used as an expression statement");
/**
* 13.9 Switch: Given a switch statement of the form <i>switch (e) { label<sub>11</sub> …
@@ -1786,44 +1845,44 @@
* s<sub>n</sub>}</i>, it is a compile-time error if the expressions <i>e<sub>k</sub></i> are not
* compile-time constants, for all <i>1 <= k <= n</i>.
*/
- static const CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = const CompileTimeErrorCode.con1('NON_CONSTANT_CASE_EXPRESSION', 99, "Case expressions must be constant");
+ static const CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = const CompileTimeErrorCode.con1('NON_CONSTANT_CASE_EXPRESSION', 100, "Case expressions must be constant");
/**
* 6.2.2 Optional Formals: It is a compile-time error if the default value of an optional
* parameter is not a compile-time constant.
*/
- static const CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = const CompileTimeErrorCode.con1('NON_CONSTANT_DEFAULT_VALUE', 100, "Default values of an optional parameter must be constant");
+ static const CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = const CompileTimeErrorCode.con1('NON_CONSTANT_DEFAULT_VALUE', 101, "Default values of an optional parameter must be constant");
/**
* 12.6 Lists: It is a compile time error if an element of a constant list literal is not a
* compile-time constant.
*/
- static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = const CompileTimeErrorCode.con1('NON_CONSTANT_LIST_ELEMENT', 101, "'const' lists must have all constant values");
+ static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = const CompileTimeErrorCode.con1('NON_CONSTANT_LIST_ELEMENT', 102, "'const' lists must have all constant values");
/**
* 12.7 Maps: It is a compile time error if either a key or a value of an entry in a constant map
* literal is not a compile-time constant.
*/
- static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY = const CompileTimeErrorCode.con1('NON_CONSTANT_MAP_KEY', 102, "The keys in a map must be constant");
+ static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY = const CompileTimeErrorCode.con1('NON_CONSTANT_MAP_KEY', 103, "The keys in a map must be constant");
/**
* 12.7 Maps: It is a compile time error if either a key or a value of an entry in a constant map
* literal is not a compile-time constant.
*/
- static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = const CompileTimeErrorCode.con1('NON_CONSTANT_MAP_VALUE', 103, "The values in a 'const' map must be constant");
+ static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = const CompileTimeErrorCode.con1('NON_CONSTANT_MAP_VALUE', 104, "The values in a 'const' map must be constant");
/**
* 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
* character @, followed by a constant expression that must be either a reference to a
* compile-time constant variable, or a call to a constant constructor.
*/
- static const CompileTimeErrorCode NON_CONSTANT_ANNOTATION_CONSTRUCTOR = const CompileTimeErrorCode.con1('NON_CONSTANT_ANNOTATION_CONSTRUCTOR', 104, "Annotation creation can use only 'const' constructor");
+ static const CompileTimeErrorCode NON_CONSTANT_ANNOTATION_CONSTRUCTOR = const CompileTimeErrorCode.con1('NON_CONSTANT_ANNOTATION_CONSTRUCTOR', 105, "Annotation creation can use only 'const' constructor");
/**
* 7.6.3 Constant Constructors: Any expression that appears within the initializer list of a
* constant constructor must be a potentially constant expression, or a compile-time error occurs.
*/
- static const CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = const CompileTimeErrorCode.con1('NON_CONSTANT_VALUE_IN_INITIALIZER', 105, "Initializer expressions in constant constructors must be constants");
+ static const CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = const CompileTimeErrorCode.con1('NON_CONSTANT_VALUE_IN_INITIALIZER', 106, "Initializer expressions in constant constructors must be constants");
/**
* 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i> or if <i>m > n</i>.
@@ -1834,7 +1893,7 @@
* @param requiredCount the expected number of required arguments
* @param argumentCount the actual number of positional arguments given
*/
- static const CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS = const CompileTimeErrorCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 106, "%d required argument(s) expected, but %d found");
+ static const CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS = const CompileTimeErrorCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 107, "%d required argument(s) expected, but %d found");
/**
* 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -1842,17 +1901,17 @@
* a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
* (respectively <i>S.id</i>)
*/
- static const CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode.con1('NON_GENERATIVE_CONSTRUCTOR', 107, "The generative constructor '%s' expected, but factory found");
+ static const CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode.con1('NON_GENERATIVE_CONSTRUCTOR', 108, "The generative constructor '%s' expected, but factory found");
/**
* 7.9 Superclasses: It is a compile-time error to specify an extends clause for class Object.
*/
- static const CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = const CompileTimeErrorCode.con1('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 108, "");
+ static const CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = const CompileTimeErrorCode.con1('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 109, "");
/**
* 7.1.1 Operators: It is a compile-time error to declare an optional parameter in an operator.
*/
- static const CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = const CompileTimeErrorCode.con1('OPTIONAL_PARAMETER_IN_OPERATOR', 109, "Optional parameters are not allowed when defining an operator");
+ static const CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = const CompileTimeErrorCode.con1('OPTIONAL_PARAMETER_IN_OPERATOR', 110, "Optional parameters are not allowed when defining an operator");
/**
* 14.3 Parts: It is a compile time error if the contents of the URI are not a valid part
@@ -1860,25 +1919,25 @@
*
* @param uri the uri pointing to a non-library declaration
*/
- static const CompileTimeErrorCode PART_OF_NON_PART = const CompileTimeErrorCode.con1('PART_OF_NON_PART', 110, "The included part '%s' must have a part-of directive");
+ static const CompileTimeErrorCode PART_OF_NON_PART = const CompileTimeErrorCode.con1('PART_OF_NON_PART', 111, "The included part '%s' must have a part-of directive");
/**
* 14.1 Imports: It is a compile-time error if the current library declares a top-level member
* named <i>p</i>.
*/
- static const CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = const CompileTimeErrorCode.con1('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 111, "The name '%s' is already used as an import prefix and cannot be used to name a top-level element");
+ static const CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = const CompileTimeErrorCode.con1('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 112, "The name '%s' is already used as an import prefix and cannot be used to name a top-level element");
/**
* 6.2.2 Optional Formals: It is a compile-time error if the name of a named optional parameter
* begins with an '_' character.
*/
- static const CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = const CompileTimeErrorCode.con1('PRIVATE_OPTIONAL_PARAMETER', 112, "Named optional parameters cannot start with an underscore");
+ static const CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = const CompileTimeErrorCode.con1('PRIVATE_OPTIONAL_PARAMETER', 113, "Named optional parameters cannot start with an underscore");
/**
* 12.1 Constants: It is a compile-time error if the value of a compile-time constant expression
* depends on itself.
*/
- static const CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = const CompileTimeErrorCode.con1('RECURSIVE_COMPILE_TIME_CONSTANT', 113, "");
+ static const CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = const CompileTimeErrorCode.con1('RECURSIVE_COMPILE_TIME_CONSTANT', 114, "");
/**
* 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
@@ -1889,13 +1948,13 @@
*
* https://code.google.com/p/dart/issues/detail?id=954
*/
- static const CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = const CompileTimeErrorCode.con1('RECURSIVE_CONSTRUCTOR_REDIRECT', 114, "Cycle in redirecting generative constructors");
+ static const CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = const CompileTimeErrorCode.con1('RECURSIVE_CONSTRUCTOR_REDIRECT', 115, "Cycle in redirecting generative constructors");
/**
* 7.6.2 Factories: It is a compile-time error if a redirecting factory constructor redirects to
* itself, either directly or indirectly via a sequence of redirections.
*/
- static const CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = const CompileTimeErrorCode.con1('RECURSIVE_FACTORY_REDIRECT', 115, "Cycle in redirecting factory constructors");
+ static const CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = const CompileTimeErrorCode.con1('RECURSIVE_FACTORY_REDIRECT', 116, "Cycle in redirecting factory constructors");
/**
* 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1908,7 +1967,7 @@
* @param className the name of the class that implements itself recursively
* @param strImplementsPath a string representation of the implements loop
*/
- static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE', 116, "'%s' cannot be a superinterface of itself: %s");
+ static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE', 117, "'%s' cannot be a superinterface of itself: %s");
/**
* 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1920,7 +1979,7 @@
*
* @param className the name of the class that implements itself recursively
*/
- static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS', 117, "'%s' cannot extend itself");
+ static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS', 118, "'%s' cannot extend itself");
/**
* 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1932,43 +1991,48 @@
*
* @param className the name of the class that implements itself recursively
*/
- static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS', 118, "'%s' cannot implement itself");
+ static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS', 119, "'%s' cannot implement itself");
/**
* 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with the const modifier but
* <i>k'</i> is not a constant constructor.
*/
- static const CompileTimeErrorCode REDIRECT_TO_MISSING_CONSTRUCTOR = const CompileTimeErrorCode.con1('REDIRECT_TO_MISSING_CONSTRUCTOR', 119, "The constructor '%s' could not be found in '%s'");
+ static const CompileTimeErrorCode REDIRECT_TO_MISSING_CONSTRUCTOR = const CompileTimeErrorCode.con1('REDIRECT_TO_MISSING_CONSTRUCTOR', 120, "The constructor '%s' could not be found in '%s'");
/**
* 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with the const modifier but
* <i>k'</i> is not a constant constructor.
*/
- static const CompileTimeErrorCode REDIRECT_TO_NON_CLASS = const CompileTimeErrorCode.con1('REDIRECT_TO_NON_CLASS', 120, "The name '%s' is not a type and cannot be used in a redirected constructor");
+ static const CompileTimeErrorCode REDIRECT_TO_NON_CLASS = const CompileTimeErrorCode.con1('REDIRECT_TO_NON_CLASS', 121, "The name '%s' is not a type and cannot be used in a redirected constructor");
/**
* 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with the const modifier but
* <i>k'</i> is not a constant constructor.
*/
- static const CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = const CompileTimeErrorCode.con1('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 121, "Constant factory constructor cannot delegate to a non-constant constructor");
+ static const CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = const CompileTimeErrorCode.con1('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 122, "Constant factory constructor cannot delegate to a non-constant constructor");
/**
* 5 Variables: A local variable may only be referenced at a source code location that is after
* its initializer, if any, is complete, or a compile-time error occurs.
*/
- static const CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION = const CompileTimeErrorCode.con1('REFERENCED_BEFORE_DECLARATION', 122, "Local variables cannot be referenced before they are declared");
+ static const CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION = const CompileTimeErrorCode.con1('REFERENCED_BEFORE_DECLARATION', 123, "Local variables cannot be referenced before they are declared");
/**
* 12.8.1 Rethrow: It is a compile-time error if an expression of the form <i>rethrow;</i> is not
* enclosed within a on-catch clause.
*/
- static const CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = const CompileTimeErrorCode.con1('RETHROW_OUTSIDE_CATCH', 123, "rethrow must be inside of a catch clause");
+ static const CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = const CompileTimeErrorCode.con1('RETHROW_OUTSIDE_CATCH', 124, "rethrow must be inside of a catch clause");
/**
* 13.12 Return: It is a compile-time error if a return statement of the form <i>return e;</i>
* appears in a generative constructor.
*/
- static const CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode.con1('RETURN_IN_GENERATIVE_CONSTRUCTOR', 124, "Constructors cannot return a value");
+ static const CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode.con1('RETURN_IN_GENERATIVE_CONSTRUCTOR', 125, "Constructors cannot return a value");
+
+ /**
+ * Speculative.
+ */
+ static const CompileTimeErrorCode SHARED_DEFERRED_PREFIX = const CompileTimeErrorCode.con1('SHARED_DEFERRED_PREFIX', 126, "The prefix of a deferred import cannot be used in other import directives");
/**
* 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -1978,19 +2042,19 @@
* initializer list, in class Object, in a factory constructor, or in a static method or variable
* initializer.
*/
- static const CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = const CompileTimeErrorCode.con1('SUPER_IN_INVALID_CONTEXT', 125, "Invalid context for 'super' invocation");
+ static const CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = const CompileTimeErrorCode.con1('SUPER_IN_INVALID_CONTEXT', 127, "Invalid context for 'super' invocation");
/**
* 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
* only action is to invoke another generative constructor.
*/
- static const CompileTimeErrorCode SUPER_IN_REDIRECTING_CONSTRUCTOR = const CompileTimeErrorCode.con1('SUPER_IN_REDIRECTING_CONSTRUCTOR', 126, "The redirecting constructor cannot have a 'super' initializer");
+ static const CompileTimeErrorCode SUPER_IN_REDIRECTING_CONSTRUCTOR = const CompileTimeErrorCode.con1('SUPER_IN_REDIRECTING_CONSTRUCTOR', 128, "The redirecting constructor cannot have a 'super' initializer");
/**
* 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
* error if a generative constructor of class Object includes a superinitializer.
*/
- static const CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = const CompileTimeErrorCode.con1('SUPER_INITIALIZER_IN_OBJECT', 127, "");
+ static const CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = const CompileTimeErrorCode.con1('SUPER_INITIALIZER_IN_OBJECT', 129, "");
/**
* 12.11 Instance Creation: It is a static type warning if any of the type arguments to a
@@ -2009,19 +2073,19 @@
* @param boundingTypeName the name of the bounding type
* @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
*/
- static const CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = const CompileTimeErrorCode.con1('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 128, "'%s' does not extend '%s'");
+ static const CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = const CompileTimeErrorCode.con1('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 130, "'%s' does not extend '%s'");
/**
* 15.3.1 Typedef: Any self reference, either directly, or recursively via another typedef, is a
* compile time error.
*/
- static const CompileTimeErrorCode TYPE_ALIAS_CANNOT_REFERENCE_ITSELF = const CompileTimeErrorCode.con1('TYPE_ALIAS_CANNOT_REFERENCE_ITSELF', 129, "Type alias cannot reference itself directly or recursively via another typedef");
+ static const CompileTimeErrorCode TYPE_ALIAS_CANNOT_REFERENCE_ITSELF = const CompileTimeErrorCode.con1('TYPE_ALIAS_CANNOT_REFERENCE_ITSELF', 131, "Type alias cannot reference itself directly or recursively via another typedef");
/**
* 12.11.2 Const: It is a compile-time error if <i>T</i> is not a class accessible in the current
* scope, optionally followed by type arguments.
*/
- static const CompileTimeErrorCode UNDEFINED_CLASS = const CompileTimeErrorCode.con1('UNDEFINED_CLASS', 130, "Undefined class '%s'");
+ static const CompileTimeErrorCode UNDEFINED_CLASS = const CompileTimeErrorCode.con1('UNDEFINED_CLASS', 132, "Undefined class '%s'");
/**
* 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -2029,7 +2093,7 @@
* a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
* (respectively <i>S.id</i>)
*/
- static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = const CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 131, "The class '%s' does not have a generative constructor '%s'");
+ static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = const CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 133, "The class '%s' does not have a generative constructor '%s'");
/**
* 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -2037,7 +2101,7 @@
* a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
* (respectively <i>S.id</i>)
*/
- static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = const CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 132, "The class '%s' does not have a default generative constructor");
+ static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = const CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 134, "The class '%s' does not have a default generative constructor");
/**
* 12.14.3 Unqualified Invocation: If there exists a lexically visible declaration named
@@ -2047,7 +2111,7 @@
*
* @param methodName the name of the method that is undefined
*/
- static const CompileTimeErrorCode UNDEFINED_FUNCTION = const CompileTimeErrorCode.con1('UNDEFINED_FUNCTION', 133, "The function '%s' is not defined");
+ static const CompileTimeErrorCode UNDEFINED_FUNCTION = const CompileTimeErrorCode.con1('UNDEFINED_FUNCTION', 135, "The function '%s' is not defined");
/**
* 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>, <i>1<=i<=l</i>,
@@ -2059,7 +2123,7 @@
*
* @param name the name of the requested named parameter
*/
- static const CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = const CompileTimeErrorCode.con1('UNDEFINED_NAMED_PARAMETER', 134, "The named parameter '%s' is not defined");
+ static const CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = const CompileTimeErrorCode.con1('UNDEFINED_NAMED_PARAMETER', 136, "The named parameter '%s' is not defined");
/**
* 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -2074,7 +2138,7 @@
* @param uri the URI pointing to a non-existent file
* @see #INVALID_URI
*/
- static const CompileTimeErrorCode URI_DOES_NOT_EXIST = const CompileTimeErrorCode.con1('URI_DOES_NOT_EXIST', 135, "Target of URI does not exist: '%s'");
+ static const CompileTimeErrorCode URI_DOES_NOT_EXIST = const CompileTimeErrorCode.con1('URI_DOES_NOT_EXIST', 137, "Target of URI does not exist: '%s'");
/**
* 14.1 Imports: It is a compile-time error if <i>x</i> is not a compile-time constant, or if
@@ -2086,7 +2150,7 @@
* 14.5 URIs: It is a compile-time error if the string literal <i>x</i> that describes a URI is
* not a compile-time constant, or if <i>x</i> involves string interpolation.
*/
- static const CompileTimeErrorCode URI_WITH_INTERPOLATION = const CompileTimeErrorCode.con1('URI_WITH_INTERPOLATION', 136, "URIs cannot use string interpolation");
+ static const CompileTimeErrorCode URI_WITH_INTERPOLATION = const CompileTimeErrorCode.con1('URI_WITH_INTERPOLATION', 138, "URIs cannot use string interpolation");
/**
* 7.1.1 Operators: It is a compile-time error if the arity of the user-declared operator []= is
@@ -2099,7 +2163,7 @@
* @param expectedNumberOfParameters the number of parameters expected
* @param actualNumberOfParameters the number of parameters found in the operator declaration
*/
- static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 137, "Operator '%s' should declare exactly %d parameter(s), but %d found");
+ static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 139, "Operator '%s' should declare exactly %d parameter(s), but %d found");
/**
* 7.1.1 Operators: It is a compile time error if the arity of the user-declared operator - is not
@@ -2107,13 +2171,13 @@
*
* @param actualNumberOfParameters the number of parameters found in the operator declaration
*/
- static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 138, "Operator '-' should declare 0 or 1 parameter, but %d found");
+ static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 140, "Operator '-' should declare 0 or 1 parameter, but %d found");
/**
* 7.3 Setters: It is a compile-time error if a setter's formal parameter list does not include
* exactly one required formal parameter <i>p</i>.
*/
- static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 139, "Setters should declare exactly one required parameter");
+ static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 141, "Setters should declare exactly one required parameter");
static const List<CompileTimeErrorCode> values = const [
AMBIGUOUS_EXPORT,
@@ -2178,6 +2242,7 @@
IMPLEMENTS_REPEATED,
IMPLEMENTS_SUPER_CLASS,
IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+ IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
IMPORT_INTERNAL_LIBRARY,
IMPORT_OF_NON_LIBRARY,
INCONSISTENT_CASE_EXPRESSION_TYPES,
@@ -2241,6 +2306,7 @@
REFERENCED_BEFORE_DECLARATION,
RETHROW_OUTSIDE_CATCH,
RETURN_IN_GENERATIVE_CONSTRUCTOR,
+ SHARED_DEFERRED_PREFIX,
SUPER_IN_INVALID_CONTEXT,
SUPER_IN_REDIRECTING_CONSTRUCTOR,
SUPER_INITIALIZER_IN_OBJECT,
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
index 7777598..2b26d5b 100644
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ b/pkg/analyzer/lib/src/generated/html.dart
@@ -1253,6 +1253,22 @@
}
/**
+ * Answer the offset of the value after the leading quote.
+ *
+ * @return the offset of the value, or `-1` if the value is not specified
+ */
+ int get textOffset {
+ if (_value == null) {
+ return -1;
+ }
+ String text = _value.lexeme;
+ if (StringUtilities.startsWithChar(text, 0x22) || StringUtilities.startsWithChar(text, 0x27)) {
+ return _value.offset + 1;
+ }
+ return _value.offset;
+ }
+
+ /**
* Answer the attribute value token. A properly formed value will start and end with matching
* quote characters, but the value returned may not be properly formed.
*
diff --git a/pkg/analyzer/lib/src/generated/index.dart b/pkg/analyzer/lib/src/generated/index.dart
index 544f582..4eda02c 100644
--- a/pkg/analyzer/lib/src/generated/index.dart
+++ b/pkg/analyzer/lib/src/generated/index.dart
@@ -17,6 +17,7 @@
import 'resolver.dart' show Namespace, NamespaceBuilder;
import 'engine.dart';
import 'html.dart' as ht;
+import 'utilities_collection.dart';
/**
* Instances of the [RemoveSourceOperation] implement an operation that removes from the index
@@ -1504,9 +1505,9 @@
importElementsMap[importElement] = elements;
}
// use import namespace to choose correct one
- for (MapEntry<ImportElement, Set<Element>> entry in getMapEntrySet(importElementsMap)) {
- if (entry.getValue().contains(usedElement)) {
- return entry.getKey();
+ for (MapIterator<ImportElement, Set<Element>> iter = SingleMapIterator.forMap(importElementsMap); iter.moveNext();) {
+ if (iter.value.contains(usedElement)) {
+ return iter.key;
}
}
// not found
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index f523e8f..3ce0ec1 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -174,6 +174,11 @@
}
class ArrayUtils {
+ static List add(List target, Object value) {
+ target = new List.from(target);
+ target.add(value);
+ return target;
+ }
static List addAll(List target, List source) {
List result = new List.from(target);
result.addAll(source);
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index 0957f27..1e1e445 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -103,6 +103,9 @@
}
return false;
}
+ bool isExecutable() {
+ return _newFile().statSync().mode & 0x111 != 0;
+ }
bool isFile() {
return _newFile().existsSync();
}
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 9b9dc17..2721627 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -4915,15 +4915,21 @@
ImportDirective _parseImportDirective(CommentAndMetadata commentAndMetadata) {
Token importKeyword = _expectKeyword(Keyword.IMPORT);
StringLiteral libraryUri = parseStringLiteral();
+ Token deferredToken = null;
Token asToken = null;
SimpleIdentifier prefix = null;
+ if (_matchesKeyword(Keyword.DEFERRED)) {
+ deferredToken = andAdvance;
+ }
if (_matchesKeyword(Keyword.AS)) {
asToken = andAdvance;
prefix = parseSimpleIdentifier();
+ } else if (deferredToken != null) {
+ _reportErrorForCurrentToken(ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT, []);
}
List<Combinator> combinators = _parseCombinators();
Token semicolon = _expectSemicolon();
- return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon);
+ return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, importKeyword, libraryUri, deferredToken, asToken, prefix, combinators, semicolon);
}
/**
@@ -6441,7 +6447,7 @@
* @param arguments the arguments to the error, used to compose the error message
*/
void _reportErrorForToken(ParserErrorCode errorCode, Token token, List<Object> arguments) {
- _reportError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, arguments));
+ _reportError(new AnalysisError.con2(_source, token.offset, Math.max(token.length, 1), errorCode, arguments));
}
/**
@@ -7497,107 +7503,109 @@
static const ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = const ParserErrorCode.con3('MISSING_NAME_IN_PART_OF_DIRECTIVE', 80, "Library directives must include a library name");
- static const ParserErrorCode MISSING_STATEMENT = const ParserErrorCode.con3('MISSING_STATEMENT', 81, "Expected a statement");
+ static const ParserErrorCode MISSING_PREFIX_IN_DEFERRED_IMPORT = const ParserErrorCode.con3('MISSING_PREFIX_IN_DEFERRED_IMPORT', 81, "Deferred imports must have a prefix");
- static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 82, "There is no '%s' to close the parameter group");
+ static const ParserErrorCode MISSING_STATEMENT = const ParserErrorCode.con3('MISSING_STATEMENT', 82, "Expected a statement");
- static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS = const ParserErrorCode.con3('MISSING_TYPEDEF_PARAMETERS', 83, "Type aliases for functions must have an explicit list of parameters");
+ static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 83, "There is no '%s' to close the parameter group");
- static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode.con3('MISSING_VARIABLE_IN_FOR_EACH', 84, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
+ static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS = const ParserErrorCode.con3('MISSING_TYPEDEF_PARAMETERS', 84, "Type aliases for functions must have an explicit list of parameters");
- static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode.con3('MIXED_PARAMETER_GROUPS', 85, "Cannot have both positional and named parameters in a single parameter list");
+ static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode.con3('MISSING_VARIABLE_IN_FOR_EACH', 85, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
- static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_EXTENDS_CLAUSES', 86, "Each class definition can have at most one extends clause");
+ static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode.con3('MIXED_PARAMETER_GROUPS', 86, "Cannot have both positional and named parameters in a single parameter list");
- static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_IMPLEMENTS_CLAUSES', 87, "Each class definition can have at most one implements clause");
+ static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_EXTENDS_CLAUSES', 87, "Each class definition can have at most one extends clause");
- static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_LIBRARY_DIRECTIVES', 88, "Only one library directive may be declared in a file");
+ static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_IMPLEMENTS_CLAUSES', 88, "Each class definition can have at most one implements clause");
- static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_NAMED_PARAMETER_GROUPS', 89, "Cannot have multiple groups of named parameters in a single parameter list");
+ static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_LIBRARY_DIRECTIVES', 89, "Only one library directive may be declared in a file");
- static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_PART_OF_DIRECTIVES', 90, "Only one part-of directive may be declared in a file");
+ static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_NAMED_PARAMETER_GROUPS', 90, "Cannot have multiple groups of named parameters in a single parameter list");
- static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 91, "Cannot have multiple groups of positional parameters in a single parameter list");
+ static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_PART_OF_DIRECTIVES', 91, "Only one part-of directive may be declared in a file");
- static const ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = const ParserErrorCode.con3('MULTIPLE_VARIABLES_IN_FOR_EACH', 92, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
+ static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 92, "Cannot have multiple groups of positional parameters in a single parameter list");
- static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode.con3('MULTIPLE_WITH_CLAUSES', 93, "Each class definition can have at most one with clause");
+ static const ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = const ParserErrorCode.con3('MULTIPLE_VARIABLES_IN_FOR_EACH', 93, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
- static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode.con3('NAMED_FUNCTION_EXPRESSION', 94, "Function expressions cannot be named");
+ static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode.con3('MULTIPLE_WITH_CLAUSES', 94, "Each class definition can have at most one with clause");
- static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('NAMED_PARAMETER_OUTSIDE_GROUP', 95, "Named parameters must be enclosed in curly braces ('{' and '}')");
+ static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode.con3('NAMED_FUNCTION_EXPRESSION', 95, "Function expressions cannot be named");
- static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_CLAUSE_IN_NON_SDK_CODE', 96, "Native clause can only be used in the SDK and code that is loaded through native extensions");
+ static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('NAMED_PARAMETER_OUTSIDE_GROUP', 96, "Named parameters must be enclosed in curly braces ('{' and '}')");
- static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 97, "Native functions can only be declared in the SDK and code that is loaded through native extensions");
+ static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_CLAUSE_IN_NON_SDK_CODE', 97, "Native clause can only be used in the SDK and code that is loaded through native extensions");
- static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode.con3('NON_CONSTRUCTOR_FACTORY', 98, "Only constructors can be declared to be a 'factory'");
+ static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 98, "Native functions can only be declared in the SDK and code that is loaded through native extensions");
- static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = const ParserErrorCode.con3('NON_IDENTIFIER_LIBRARY_NAME', 99, "The name of a library must be an identifier");
+ static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode.con3('NON_CONSTRUCTOR_FACTORY', 99, "Only constructors can be declared to be a 'factory'");
- static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = const ParserErrorCode.con3('NON_PART_OF_DIRECTIVE_IN_PART', 100, "The part-of directive must be the only directive in a part");
+ static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = const ParserErrorCode.con3('NON_IDENTIFIER_LIBRARY_NAME', 100, "The name of a library must be an identifier");
- static const ParserErrorCode NON_USER_DEFINABLE_OPERATOR = const ParserErrorCode.con3('NON_USER_DEFINABLE_OPERATOR', 101, "The operator '%s' is not user definable");
+ static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = const ParserErrorCode.con3('NON_PART_OF_DIRECTIVE_IN_PART', 101, "The part-of directive must be the only directive in a part");
- static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = const ParserErrorCode.con3('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 102, "Normal parameters must occur before optional parameters");
+ static const ParserErrorCode NON_USER_DEFINABLE_OPERATOR = const ParserErrorCode.con3('NON_USER_DEFINABLE_OPERATOR', 102, "The operator '%s' is not user definable");
- static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = const ParserErrorCode.con3('POSITIONAL_AFTER_NAMED_ARGUMENT', 103, "Positional arguments must occur before named arguments");
+ static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = const ParserErrorCode.con3('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 103, "Normal parameters must occur before optional parameters");
- static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 104, "Positional parameters must be enclosed in square brackets ('[' and ']')");
+ static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = const ParserErrorCode.con3('POSITIONAL_AFTER_NAMED_ARGUMENT', 104, "Positional arguments must occur before named arguments");
- static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR = const ParserErrorCode.con3('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR', 105, "Only factory constructor can specify '=' redirection.");
+ static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 105, "Positional parameters must be enclosed in square brackets ('[' and ']')");
- static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode.con3('SETTER_IN_FUNCTION', 106, "Setters cannot be defined within methods or functions");
+ static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR = const ParserErrorCode.con3('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR', 106, "Only factory constructor can specify '=' redirection.");
- static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode.con3('STATIC_AFTER_CONST', 107, "The modifier 'static' should be before the modifier 'const'");
+ static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode.con3('SETTER_IN_FUNCTION', 107, "Setters cannot be defined within methods or functions");
- static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode.con3('STATIC_AFTER_FINAL', 108, "The modifier 'static' should be before the modifier 'final'");
+ static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode.con3('STATIC_AFTER_CONST', 108, "The modifier 'static' should be before the modifier 'const'");
- static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode.con3('STATIC_AFTER_VAR', 109, "The modifier 'static' should be before the modifier 'var'");
+ static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode.con3('STATIC_AFTER_FINAL', 109, "The modifier 'static' should be before the modifier 'final'");
- static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode.con3('STATIC_CONSTRUCTOR', 110, "Constructors cannot be static");
+ static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode.con3('STATIC_AFTER_VAR', 110, "The modifier 'static' should be before the modifier 'var'");
- static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_GETTER_WITHOUT_BODY', 111, "A 'static' getter must have a body");
+ static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode.con3('STATIC_CONSTRUCTOR', 111, "Constructors cannot be static");
- static const ParserErrorCode STATIC_OPERATOR = const ParserErrorCode.con3('STATIC_OPERATOR', 112, "Operators cannot be static");
+ static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_GETTER_WITHOUT_BODY', 112, "A 'static' getter must have a body");
- static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_SETTER_WITHOUT_BODY', 113, "A 'static' setter must have a body");
+ static const ParserErrorCode STATIC_OPERATOR = const ParserErrorCode.con3('STATIC_OPERATOR', 113, "Operators cannot be static");
- static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = const ParserErrorCode.con3('STATIC_TOP_LEVEL_DECLARATION', 114, "Top-level declarations cannot be declared to be 'static'");
+ static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_SETTER_WITHOUT_BODY', 114, "A 'static' setter must have a body");
- static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = const ParserErrorCode.con3('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 115, "The 'default' case should be the last case in a switch statement");
+ static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = const ParserErrorCode.con3('STATIC_TOP_LEVEL_DECLARATION', 115, "Top-level declarations cannot be declared to be 'static'");
- static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = const ParserErrorCode.con3('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 116, "The 'default' case can only be declared once");
+ static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = const ParserErrorCode.con3('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 116, "The 'default' case should be the last case in a switch statement");
- static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode.con3('TOP_LEVEL_OPERATOR', 117, "Operators must be declared within a class");
+ static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = const ParserErrorCode.con3('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 117, "The 'default' case can only be declared once");
- static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 118, "There is no '%s' to open a parameter group");
+ static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode.con3('TOP_LEVEL_OPERATOR', 118, "Operators must be declared within a class");
- static const ParserErrorCode UNEXPECTED_TOKEN = const ParserErrorCode.con3('UNEXPECTED_TOKEN', 119, "Unexpected token '%s'");
+ static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 119, "There is no '%s' to open a parameter group");
- static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode.con3('WITH_BEFORE_EXTENDS', 120, "The extends clause must be before the with clause");
+ static const ParserErrorCode UNEXPECTED_TOKEN = const ParserErrorCode.con3('UNEXPECTED_TOKEN', 120, "Unexpected token '%s'");
- static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode.con3('WITH_WITHOUT_EXTENDS', 121, "The with clause cannot be used without an extends clause");
+ static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode.con3('WITH_BEFORE_EXTENDS', 121, "The extends clause must be before the with clause");
- static const ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 122, "The default value of a named parameter should be preceeded by ':'");
+ static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode.con3('WITH_WITHOUT_EXTENDS', 122, "The with clause cannot be used without an extends clause");
- static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 123, "The default value of a positional parameter should be preceeded by '='");
+ static const ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 123, "The default value of a named parameter should be preceeded by ':'");
- static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 124, "Expected '%s' to close parameter group");
+ static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 124, "The default value of a positional parameter should be preceeded by '='");
- static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode.con3('VAR_AND_TYPE', 125, "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
+ static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 125, "Expected '%s' to close parameter group");
- static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode.con3('VAR_AS_TYPE_NAME', 126, "The keyword 'var' cannot be used as a type name");
+ static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode.con3('VAR_AND_TYPE', 126, "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
- static const ParserErrorCode VAR_CLASS = const ParserErrorCode.con3('VAR_CLASS', 127, "Classes cannot be declared to be 'var'");
+ static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode.con3('VAR_AS_TYPE_NAME', 127, "The keyword 'var' cannot be used as a type name");
- static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode.con3('VAR_RETURN_TYPE', 128, "The return type cannot be 'var'");
+ static const ParserErrorCode VAR_CLASS = const ParserErrorCode.con3('VAR_CLASS', 128, "Classes cannot be declared to be 'var'");
- static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode.con3('VAR_TYPEDEF', 129, "Type aliases cannot be declared to be 'var'");
+ static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode.con3('VAR_RETURN_TYPE', 129, "The return type cannot be 'var'");
- static const ParserErrorCode VOID_PARAMETER = const ParserErrorCode.con3('VOID_PARAMETER', 130, "Parameters cannot have a type of 'void'");
+ static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode.con3('VAR_TYPEDEF', 130, "Type aliases cannot be declared to be 'var'");
- static const ParserErrorCode VOID_VARIABLE = const ParserErrorCode.con3('VOID_VARIABLE', 131, "Variables cannot have a type of 'void'");
+ static const ParserErrorCode VOID_PARAMETER = const ParserErrorCode.con3('VOID_PARAMETER', 131, "Parameters cannot have a type of 'void'");
+
+ static const ParserErrorCode VOID_VARIABLE = const ParserErrorCode.con3('VOID_VARIABLE', 132, "Variables cannot have a type of 'void'");
static const List<ParserErrorCode> values = const [
ABSTRACT_CLASS_MEMBER,
@@ -7681,6 +7689,7 @@
MISSING_KEYWORD_OPERATOR,
MISSING_NAME_IN_LIBRARY_DIRECTIVE,
MISSING_NAME_IN_PART_OF_DIRECTIVE,
+ MISSING_PREFIX_IN_DEFERRED_IMPORT,
MISSING_STATEMENT,
MISSING_TERMINATOR_FOR_PARAMETER_GROUP,
MISSING_TYPEDEF_PARAMETERS,
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 44dcd88..3572534 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -16,6 +16,7 @@
import 'scanner.dart' as sc;
import 'utilities_dart.dart';
import 'utilities_general.dart';
+import 'utilities_collection.dart';
import 'ast.dart';
import 'parser.dart' show Parser, ParserErrorCode;
import 'sdk.dart' show DartSdk, SdkLibrary;
@@ -242,11 +243,6 @@
ClassElementImpl _classElement;
/**
- * The [ToolkitObjectElement]s to set for [classElement].
- */
- List<ToolkitObjectElement> _classToolkitObjects = [];
-
- /**
* The [Annotation] that is currently being analyzed.
*/
Annotation _annotation;
@@ -270,7 +266,6 @@
if (unitMember is ClassDeclaration) {
this._classDeclaration = unitMember;
this._classElement = _classDeclaration.element as ClassElementImpl;
- this._classToolkitObjects.clear();
// process annotations
NodeList<Annotation> annotations = _classDeclaration.metadata;
for (Annotation annotation in annotations) {
@@ -300,11 +295,6 @@
continue;
}
}
- // set toolkit objects
- if (!_classToolkitObjects.isEmpty) {
- List<ToolkitObjectElement> objects = _classToolkitObjects;
- _classElement.toolkitObjects = new List.from(objects);
- }
}
}
}
@@ -414,7 +404,7 @@
element.styleUriOffset = styleUriOffset;
element.properties = _parseNgComponentProperties();
element.scopeProperties = _parseScopeProperties();
- _classToolkitObjects.add(element);
+ _classElement.addToolkitObjects(element);
}
}
@@ -566,7 +556,7 @@
int nameOffset = _getStringArgumentOffset(_PUBLISH_AS);
AngularControllerElementImpl element = new AngularControllerElementImpl(name, nameOffset);
element.selector = selector;
- _classToolkitObjects.add(element);
+ _classElement.addToolkitObjects(element);
}
}
@@ -591,7 +581,7 @@
AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offset);
element.selector = selector;
element.properties = _parseNgComponentProperties();
- _classToolkitObjects.add(element);
+ _classElement.addToolkitObjects(element);
}
}
@@ -606,7 +596,7 @@
if (isValid) {
String name = _getStringArgument(_NAME);
int nameOffset = _getStringArgumentOffset(_NAME);
- _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset));
+ _classElement.addToolkitObjects(new AngularFilterElementImpl(name, nameOffset));
}
}
@@ -2206,20 +2196,120 @@
}
/**
+ * Instances of the class `PolymerCompilationUnitBuilder` build a Polymer specific element
+ * model for a single compilation unit.
+ */
+class PolymerCompilationUnitBuilder {
+ static String _CUSTOM_TAG = "CustomTag";
+
+ static Element getElement(AstNode node, int offset) {
+ // maybe node is not SimpleStringLiteral
+ if (node is! SimpleStringLiteral) {
+ return null;
+ }
+ SimpleStringLiteral literal = node as SimpleStringLiteral;
+ // maybe has PolymerElement
+ {
+ Element element = literal.toolkitElement;
+ if (element is PolymerElement) {
+ return element;
+ }
+ }
+ // no Element
+ return null;
+ }
+
+ /**
+ * The compilation unit with built Dart element models.
+ */
+ final CompilationUnit _unit;
+
+ /**
+ * The [ClassDeclaration] that is currently being analyzed.
+ */
+ ClassDeclaration _classDeclaration;
+
+ /**
+ * The [ClassElementImpl] that is currently being analyzed.
+ */
+ ClassElementImpl _classElement;
+
+ /**
+ * The [Annotation] that is currently being analyzed.
+ */
+ Annotation _annotation;
+
+ /**
+ * Initialize a newly created compilation unit element builder.
+ *
+ * @param unit the compilation unit with built Dart element models
+ */
+ PolymerCompilationUnitBuilder(this._unit);
+
+ /**
+ * Builds Polymer specific element models and adds them to the existing Dart elements.
+ */
+ void build() {
+ // process classes
+ for (CompilationUnitMember unitMember in _unit.declarations) {
+ if (unitMember is ClassDeclaration) {
+ this._classDeclaration = unitMember;
+ this._classElement = _classDeclaration.element as ClassElementImpl;
+ // process annotations
+ NodeList<Annotation> annotations = _classDeclaration.metadata;
+ for (Annotation annotation in annotations) {
+ // verify annotation
+ if (annotation.arguments == null) {
+ continue;
+ }
+ this._annotation = annotation;
+ // @CustomTag
+ if (_isAnnotation(annotation, _CUSTOM_TAG)) {
+ _parseCustomTag();
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if given [Annotation] is an annotation with required name.
+ */
+ bool _isAnnotation(Annotation annotation, String name) {
+ Element element = annotation.element;
+ if (element is ConstructorElement) {
+ ConstructorElement constructorElement = element;
+ return constructorElement.returnType.displayName == name;
+ }
+ return false;
+ }
+
+ void _parseCustomTag() {
+ List<Expression> arguments = _annotation.arguments.arguments;
+ if (arguments.length == 1) {
+ Expression nameExpression = arguments[0];
+ if (nameExpression is SimpleStringLiteral) {
+ SimpleStringLiteral nameLiteral = nameExpression;
+ String name = nameLiteral.value;
+ int nameOffset = nameLiteral.valueOffset;
+ PolymerTagDartElementImpl element = new PolymerTagDartElementImpl(name, nameOffset, _classElement);
+ _classElement.addToolkitObjects(element);
+ nameLiteral.toolkitElement = element;
+ }
+ }
+ }
+}
+
+/**
* Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
* violations of Dart best practices.
*/
class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
- static String _GETTER = "getter";
-
static String _HASHCODE_GETTER_NAME = "hashCode";
- static String _METHOD = "method";
-
static String _NULL_TYPE_NAME = "Null";
- static String _SETTER = "setter";
-
static String _TO_INT_METHOD_NAME = "toInt";
/**
@@ -2273,10 +2363,11 @@
@override
Object visitAssignmentExpression(AssignmentExpression node) {
sc.TokenType operatorType = node.operator.type;
- if (operatorType != sc.TokenType.EQ) {
- _checkForDeprecatedMemberUse(node.bestElement, node);
- } else {
+ if (operatorType == sc.TokenType.EQ) {
_checkForUseOfVoidResult(node.rightHandSide);
+ _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
+ } else {
+ _checkForDeprecatedMemberUse(node.bestElement, node);
}
return super.visitAssignmentExpression(node);
}
@@ -2378,6 +2469,7 @@
@override
Object visitVariableDeclaration(VariableDeclaration node) {
_checkForUseOfVoidResult(node.initializer);
+ _checkForInvalidAssignment(node.name, node.initializer);
return super.visitVariableDeclaration(node);
}
@@ -2623,6 +2715,44 @@
}
/**
+ * This verifies that the passed left hand side and right hand side represent a valid assignment.
+ *
+ * This method corresponds to ErrorVerifier.checkForInvalidAssignment.
+ *
+ * @param lhs the left hand side expression
+ * @param rhs the right hand side expression
+ * @return `true` if and only if an error code is generated on the passed node
+ * @see HintCode#INVALID_ASSIGNMENT
+ */
+ bool _checkForInvalidAssignment(Expression lhs, Expression rhs) {
+ if (lhs == null || rhs == null) {
+ return false;
+ }
+ VariableElement leftElement = ErrorVerifier.getVariableElement(lhs);
+ DartType leftType = (leftElement == null) ? ErrorVerifier.getStaticType(lhs) : leftElement.type;
+ DartType staticRightType = ErrorVerifier.getStaticType(rhs);
+ if (!staticRightType.isAssignableTo(leftType)) {
+ // The warning was generated on this rhs
+ return false;
+ }
+ // Test for, and then generate the hint
+ DartType bestRightType = rhs.bestType;
+ if (leftType != null && bestRightType != null) {
+ if (!bestRightType.isAssignableTo(leftType)) {
+ String leftName = leftType.displayName;
+ String rightName = bestRightType.displayName;
+ if (leftName == rightName) {
+ leftName = ErrorVerifier.getExtendedDisplayName(leftType);
+ rightName = ErrorVerifier.getExtendedDisplayName(bestRightType);
+ }
+ _errorReporter.reportErrorForNode(HintCode.INVALID_ASSIGNMENT, rhs, [rightName, leftName]);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Generate a hint for functions or methods that have a return type, but do not have a return
* statement on all branches. At the end of blocks with no return, Dart implicitly returns
* `null`, avoiding these implicit returns is considered a best practice.
@@ -2680,75 +2810,6 @@
}
/**
- * Checks that if the passed method declaration is private, it does not override a private member
- * in a superclass.
- *
- * @param node the method declaration to check
- * @return `true` if and only if a hint code is generated on the passed node
- * @see HintCode#OVERRIDDING_PRIVATE_MEMBER
- */
- bool _checkForOverridingPrivateMember(MethodDeclaration node) {
- // If not in an enclosing class, return false
- if (_enclosingClass == null) {
- return false;
- }
- // If the member is not private, return false
- if (!Identifier.isPrivateName(node.name.name)) {
- return false;
- }
- // Get the element of the member, if null, return false
- ExecutableElement executableElement = node.element;
- if (executableElement == null) {
- return false;
- }
- // Loop through all of the superclasses looking for a matching method or accessor
- // TODO(jwren) If the HintGenerator needs or has easy access to the InheritanceManager in the
- // future then this could be refactored down to be more readable, however, since we are only
- // looking through super classes (and not the entire interface graph) there is no pressing need
- String elementName = executableElement.name;
- bool isGetterOrSetter = executableElement is PropertyAccessorElement;
- InterfaceType superType = _enclosingClass.supertype;
- if (superType == null) {
- return false;
- }
- ClassElement classElement = superType.element;
- while (classElement != null) {
- if (_enclosingClass.library != classElement.library) {
- if (isGetterOrSetter) {
- PropertyAccessorElement overriddenAccessor = null;
- List<PropertyAccessorElement> accessors = classElement.accessors;
- for (PropertyAccessorElement propertyAccessorElement in accessors) {
- if (elementName == propertyAccessorElement.name) {
- overriddenAccessor = propertyAccessorElement;
- break;
- }
- }
- if (overriddenAccessor != null) {
- String memberType = (executableElement as PropertyAccessorElement).isGetter ? _GETTER : _SETTER;
- _errorReporter.reportErrorForNode(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
- memberType,
- executableElement.displayName,
- classElement.displayName]);
- return true;
- }
- } else {
- MethodElement overriddenMethod = classElement.getMethod(elementName);
- if (overriddenMethod != null) {
- _errorReporter.reportErrorForNode(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
- _METHOD,
- executableElement.displayName,
- classElement.displayName]);
- return true;
- }
- }
- }
- superType = classElement.supertype;
- classElement = superType != null ? superType.element : null;
- }
- return false;
- }
-
- /**
* Check for the passed as expression for the [HintCode#UNNECESSARY_CAST] hint code.
*
* @param node the as expression to check
@@ -3000,10 +3061,10 @@
if (currentType.isObject) {
// Found catch clause clause that has Object as an exception type, this is equivalent to
// having a catch clause that doesn't have an exception type, visit the block, but
- // generate an error on any following catch clauses (and don't visit them).
+ // generate an error on any following catch clauses (and don't visit them).
_safelyVisit(catchClause);
if (i + 1 != numOfCatchClauses) {
- // this catch clause is not the last in the try statement
+ // this catch clause is not the last in the try statement
CatchClause nextCatchClause = catchClauses[i + 1];
CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
int offset = nextCatchClause.offset;
@@ -3025,7 +3086,7 @@
}
_safelyVisit(catchClause);
} else {
- // Found catch clause clause that doesn't have an exception type, visit the block, but
+ // Found catch clause clause that doesn't have an exception type, visit the block, but
// generate an error on any following catch clauses (and don't visit them).
_safelyVisit(catchClause);
if (i + 1 != numOfCatchClauses) {
@@ -3080,24 +3141,15 @@
}
// Don't consider situations where we could evaluate to a constant boolean expression with the
// ConstantVisitor
-//
- // else {
-//
- // EvaluationResultImpl result = expression.accept(new ConstantVisitor());
-//
- // if (result == ValidResult.RESULT_TRUE) {
-//
- // return ValidResult.RESULT_TRUE;
-//
- // } else if (result == ValidResult.RESULT_FALSE) {
-//
- // return ValidResult.RESULT_FALSE;
-//
- // }
-//
- // return null;
-//
- // }
+ // else {
+ // EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+ // if (result == ValidResult.RESULT_TRUE) {
+ // return ValidResult.RESULT_TRUE;
+ // } else if (result == ValidResult.RESULT_FALSE) {
+ // return ValidResult.RESULT_FALSE;
+ // }
+ // return null;
+ // }
return null;
}
@@ -8581,9 +8633,9 @@
//
// Loop through the entries in the unionMap, adding them to the resultMap appropriately.
//
- for (MapEntry<String, List<ExecutableElement>> entry in getMapEntrySet(unionMap)) {
- String key = entry.getKey();
- List<ExecutableElement> list = entry.getValue();
+ for (MapIterator<String, List<ExecutableElement>> iter = SingleMapIterator.forMap(unionMap); iter.moveNext();) {
+ String key = iter.key;
+ List<ExecutableElement> list = iter.value;
int numOfEltsWithMatchingNames = list.length;
if (numOfEltsWithMatchingNames == 1) {
//
@@ -8659,12 +8711,30 @@
} else {
if (subtypesOfAllOtherTypesIndexes.isEmpty) {
//
+ // Determine if the current class has a method or accessor with the member name, if it
+ // does then then this class does not "inherit" from any of the supertypes.
+ // See issue 16134.
+ //
+ bool classHasMember = false;
+ if (allMethods) {
+ classHasMember = classElt.getMethod(key) != null;
+ } else {
+ List<PropertyAccessorElement> accessors = classElt.accessors;
+ for (int i = 0; i < accessors.length; i++) {
+ if (accessors[i].name == key) {
+ classHasMember = true;
+ }
+ }
+ }
+ //
// Example: class A inherited only 2 method named 'm'. One has the function type
// '() -> int' and one has the function type '() -> String'. Since neither is a subtype
// of the other, we create a warning, and have this class inherit nothing.
//
- String firstTwoFuntionTypesStr = "${executableElementTypes[0].toString()}, ${executableElementTypes[1].toString()}";
- _reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFuntionTypesStr]);
+ if (!classHasMember) {
+ String firstTwoFuntionTypesStr = "${executableElementTypes[0].toString()}, ${executableElementTypes[1].toString()}";
+ _reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFuntionTypesStr]);
+ }
} else {
//
// Example: class A inherits 2 methods named 'm'. One has the function type
@@ -9725,6 +9795,7 @@
importElement.uriOffset = uriLiteral.offset;
importElement.uriEnd = uriLiteral.end;
importElement.uri = uriContent;
+ importElement.deferred = importDirective.deferredToken != null;
importElement.combinators = _buildCombinators(importDirective);
LibraryElement importedLibraryElement = importedLibrary.libraryElement;
if (importedLibraryElement != null) {
@@ -10074,6 +10145,16 @@
} finally {
timeCounter.stop();
}
+ // Polymer
+ timeCounter = PerformanceStatistics.polymer.start();
+ try {
+ for (Source source in library.compilationUnitSources) {
+ CompilationUnit ast = library.getAST(source);
+ new PolymerCompilationUnitBuilder(ast).build();
+ }
+ } finally {
+ timeCounter.stop();
+ }
}
/**
@@ -10296,6 +10377,7 @@
importElement.uriEnd = uriLiteral.end;
}
importElement.uri = uriContent;
+ importElement.deferred = importDirective.deferredToken != null;
importElement.combinators = _buildCombinators(importDirective);
LibraryElement importedLibraryElement = importedLibrary.libraryElement;
if (importedLibraryElement != null) {
@@ -10505,6 +10587,16 @@
} finally {
timeCounter.stop();
}
+ // Polymer
+ timeCounter = PerformanceStatistics.polymer.start();
+ try {
+ for (Source source in library.compilationUnitSources) {
+ CompilationUnit ast = library.getAST(source);
+ new PolymerCompilationUnitBuilder(ast).build();
+ }
+ } finally {
+ timeCounter.stop();
+ }
}
}
@@ -14902,8 +14994,8 @@
* @param overrides the overrides to be applied
*/
void applyOverrides(Map<Element, DartType> overrides) {
- for (MapEntry<Element, DartType> entry in getMapEntrySet(overrides)) {
- _overridenTypes[entry.getKey()] = entry.getValue();
+ for (MapIterator<Element, DartType> iter = SingleMapIterator.forMap(overrides); iter.moveNext();) {
+ _overridenTypes[iter.key] = iter.value;
}
}
@@ -17253,8 +17345,8 @@
* @param namespace the namespace containing the names to be added to this namespace
*/
void _addAllFromMap(Map<String, Element> definedNames, Map<String, Element> newNames) {
- for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) {
- definedNames[entry.getKey()] = entry.getValue();
+ for (MapIterator<String, Element> iter = SingleMapIterator.forMap(newNames); iter.moveNext();) {
+ definedNames[iter.key] = iter.value;
}
}
@@ -17336,8 +17428,8 @@
if (prefixElement != null) {
String prefix = prefixElement.name;
Map<String, Element> newNames = new Map<String, Element>();
- for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) {
- newNames["${prefix}.${entry.getKey()}"] = entry.getValue();
+ for (MapIterator<String, Element> iter = SingleMapIterator.forMap(definedNames); iter.moveNext();) {
+ newNames["${prefix}.${iter.key}"] = iter.value;
}
return newNames;
} else {
@@ -18086,6 +18178,56 @@
*/
class ErrorVerifier extends RecursiveAstVisitor<Object> {
/**
+ * Return a display name for the given type that includes the path to the compilation unit in
+ * which the type is defined.
+ *
+ * @param type the type for which an extended display name is to be returned
+ * @return a display name that can help distiguish between two types with the same name
+ */
+ static String getExtendedDisplayName(DartType type) {
+ Element element = type.element;
+ if (element != null) {
+ Source source = element.source;
+ if (source != null) {
+ return "${type.displayName} (${source.fullName})";
+ }
+ }
+ return type.displayName;
+ }
+
+ /**
+ * Return the static type of the given expression that is to be used for type analysis.
+ *
+ * @param expression the expression whose type is to be returned
+ * @return the static type of the given expression
+ */
+ static DartType getStaticType(Expression expression) {
+ DartType type = expression.staticType;
+ if (type == null) {
+ // TODO(brianwilkerson) This should never happen.
+ return DynamicTypeImpl.instance;
+ }
+ return type;
+ }
+
+ /**
+ * Return the variable element represented by the given expression, or `null` if there is no
+ * such element.
+ *
+ * @param expression the expression whose element is to be returned
+ * @return the variable element represented by the expression
+ */
+ static VariableElement getVariableElement(Expression expression) {
+ if (expression is Identifier) {
+ Element element = expression.staticElement;
+ if (element is VariableElement) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ /**
* The error reporter by which errors will be reported.
*/
final ErrorReporter _errorReporter;
@@ -18096,11 +18238,6 @@
final LibraryElement _currentLibrary;
/**
- * The type representing the type 'dynamic'.
- */
- DartType _dynamicType;
-
- /**
* The type representing the type 'bool'.
*/
InterfaceType _boolType;
@@ -18308,7 +18445,6 @@
_isInInstanceVariableInitializer = false;
_isInConstructorInitializer = false;
_isInStaticMethod = false;
- _dynamicType = _typeProvider.dynamicType;
_boolType = _typeProvider.boolType;
_intType = _typeProvider.intType;
_DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [
@@ -18334,8 +18470,7 @@
@override
Object visitAssignmentExpression(AssignmentExpression node) {
- sc.Token operator = node.operator;
- sc.TokenType operatorType = operator.type;
+ sc.TokenType operatorType = node.operator.type;
if (operatorType == sc.TokenType.EQ) {
_checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
} else {
@@ -18400,9 +18535,9 @@
try {
_isInNativeClass = node.nativeClause != null;
_enclosingClass = node.element;
- WithClause withClause = node.withClause;
- ImplementsClause implementsClause = node.implementsClause;
ExtendsClause extendsClause = node.extendsClause;
+ ImplementsClause implementsClause = node.implementsClause;
+ WithClause withClause = node.withClause;
_checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
_checkForMemberWithClassName();
_checkForNoDefaultSuperConstructorImplicit(node);
@@ -18412,7 +18547,7 @@
// Only check for all of the inheritance logic around clauses if there isn't an error code
// such as "Cannot extend double" already on the class.
if (!_checkForImplementsDisallowedClass(implementsClause) && !_checkForExtendsDisallowedClass(extendsClause) && !_checkForAllMixinErrorCodes(withClause)) {
- _checkForNonAbstractClassInheritsAbstractMember(node);
+ _checkForNonAbstractClassInheritsAbstractMember(node.name);
_checkForInconsistentMethodInheritance();
_checkForRecursiveInterfaceInheritance(_enclosingClass);
_checkForConflictingGetterAndMethod();
@@ -18446,14 +18581,16 @@
@override
Object visitClassTypeAlias(ClassTypeAlias node) {
_checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
- _checkForExtendsDisallowedClassInTypeAlias(node);
- _checkForImplementsDisallowedClass(node.implementsClause);
- _checkForAllMixinErrorCodes(node.withClause);
ClassElement outerClassElement = _enclosingClass;
try {
_enclosingClass = node.element;
- _checkForRecursiveInterfaceInheritance(node.element);
- _checkForTypeAliasCannotReferenceItself_mixin(node);
+ // Only check for all of the inheritance logic around clauses if there isn't an error code
+ // such as "Cannot extend double" already on the class.
+ if (!_checkForExtendsDisallowedClassInTypeAlias(node) && !_checkForImplementsDisallowedClass(node.implementsClause) && !_checkForAllMixinErrorCodes(node.withClause)) {
+ _checkForRecursiveInterfaceInheritance(node.element);
+ _checkForTypeAliasCannotReferenceItself_mixin(node);
+ _checkForNonAbstractClassInheritsAbstractMember(node.name);
+ }
} finally {
_enclosingClass = outerClassElement;
}
@@ -18471,6 +18608,12 @@
}
@override
+ Object visitCompilationUnit(CompilationUnit node) {
+ _checkForDeferredPrefixCollisions(node);
+ return super.visitCompilationUnit(node);
+ }
+
+ @override
Object visitConditionalExpression(ConditionalExpression node) {
_checkForNonBoolCondition(node.condition);
return super.visitConditionalExpression(node);
@@ -18671,6 +18814,9 @@
if (importElement != null) {
_checkForImportDuplicateLibraryName(node, importElement);
_checkForImportInternalLibrary(node, importElement);
+ if (importElement.isDeferred) {
+ _checkForLoadLibraryFunction(node, importElement);
+ }
}
return super.visitImportDirective(node);
}
@@ -19073,9 +19219,9 @@
}
}
// Visit all of the states in the map to ensure that none were never initialized.
- for (MapEntry<FieldElement, INIT_STATE> entry in getMapEntrySet(fieldElementsMap)) {
- if (entry.getValue() == INIT_STATE.NOT_INIT) {
- FieldElement fieldElement = entry.getKey();
+ for (MapIterator<FieldElement, INIT_STATE> iter = SingleMapIterator.forMap(fieldElementsMap); iter.moveNext();) {
+ if (iter.value == INIT_STATE.NOT_INIT) {
+ FieldElement fieldElement = iter.key;
if (fieldElement.isConst) {
_errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
foundError = true;
@@ -19249,22 +19395,21 @@
parameterIndex++;
}
// SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
- JavaIterator<MapEntry<String, DartType>> overriddenNamedPTIterator = new JavaIterator(getMapEntrySet(overriddenNamedPT));
- while (overriddenNamedPTIterator.hasNext) {
- MapEntry<String, DartType> overriddenNamedPTEntry = overriddenNamedPTIterator.next();
- DartType overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey()];
+ MapIterator<String, DartType> overriddenNamedPTIterator = SingleMapIterator.forMap(overriddenNamedPT);
+ while (overriddenNamedPTIterator.moveNext()) {
+ DartType overridingType = overridingNamedPT[overriddenNamedPTIterator.key];
if (overridingType == null) {
// Error, this is never reached- INVALID_OVERRIDE_NAMED would have been created above if
// this could be reached.
continue;
}
- if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) {
+ if (!overriddenNamedPTIterator.value.isAssignableTo(overridingType)) {
// lookup the parameter for the error to select
ParameterElement parameterToSelect = null;
AstNode parameterLocationToSelect = null;
for (int i = 0; i < parameters.length; i++) {
ParameterElement parameter = parameters[i];
- if (parameter.parameterKind == ParameterKind.NAMED && overriddenNamedPTEntry.getKey() == parameter.name) {
+ if (parameter.parameterKind == ParameterKind.NAMED && overriddenNamedPTIterator.key == parameter.name) {
parameterToSelect = parameter;
parameterLocationToSelect = parameterLocations[i];
break;
@@ -19273,7 +19418,7 @@
if (parameterToSelect != null) {
_errorReporter.reportErrorForNode(StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, parameterLocationToSelect, [
overridingType.displayName,
- overriddenNamedPTEntry.getValue().displayName,
+ overriddenNamedPTIterator.value.displayName,
overriddenExecutable.enclosingElement.displayName]);
return true;
}
@@ -19611,9 +19756,9 @@
// check exported names
Namespace namespace = new NamespaceBuilder().createExportNamespaceForDirective(exportElement);
Map<String, Element> definedNames = namespace.definedNames;
- for (MapEntry<String, Element> definedEntry in getMapEntrySet(definedNames)) {
- String name = definedEntry.getKey();
- Element element = definedEntry.getValue();
+ for (MapIterator<String, Element> iter = SingleMapIterator.forMap(definedNames); iter.moveNext();) {
+ String name = iter.key;
+ Element element = iter.value;
Element prevElement = _exportedElements[name];
if (element != null && prevElement != null && prevElement != element) {
_errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node, [
@@ -19699,7 +19844,7 @@
* @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
* @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
*/
- bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, DartType expectedStaticType, ErrorCode errorCode) => _checkForArgumentTypeNotAssignable(expression, expectedStaticType, _getStaticType(expression), errorCode);
+ bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, DartType expectedStaticType, ErrorCode errorCode) => _checkForArgumentTypeNotAssignable(expression, expectedStaticType, getStaticType(expression), errorCode);
/**
* This verifies that the passed arguments can be assigned to their corresponding parameters.
@@ -20552,6 +20697,47 @@
}
/**
+ * This verifies that any deferred imports in the given compilation unit have a unique prefix.
+ *
+ * @param node the compilation unit containing the imports to be checked
+ * @return `true` if an error was generated
+ * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
+ */
+ bool _checkForDeferredPrefixCollisions(CompilationUnit node) {
+ bool foundError = false;
+ NodeList<Directive> directives = node.directives;
+ int count = directives.length;
+ if (count > 0) {
+ Map<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = new Map<PrefixElement, List<ImportDirective>>();
+ for (int i = 0; i < count; i++) {
+ Directive directive = directives[i];
+ if (directive is ImportDirective) {
+ ImportDirective importDirective = directive;
+ SimpleIdentifier prefix = importDirective.prefix;
+ if (prefix != null) {
+ Element element = prefix.staticElement;
+ if (element is PrefixElement) {
+ PrefixElement prefixElement = element;
+ List<ImportDirective> elements = prefixToDirectivesMap[prefixElement];
+ if (elements == null) {
+ elements = new List<ImportDirective>();
+ prefixToDirectivesMap[prefixElement] = elements;
+ }
+ elements.add(importDirective);
+ }
+ }
+ }
+ }
+ for (List<ImportDirective> imports in prefixToDirectivesMap.values) {
+ if (_hasDeferredPrefixCollision(imports)) {
+ foundError = true;
+ }
+ }
+ }
+ return foundError;
+ }
+
+ /**
* This verifies that the enclosing class does not have an instance member with the given name of
* the static member.
*
@@ -20785,7 +20971,7 @@
return false;
}
// test the static type of the expression
- DartType staticType = _getStaticType(expression);
+ DartType staticType = getStaticType(expression);
if (staticType == null) {
return false;
}
@@ -21159,31 +21345,19 @@
if (lhs == null || rhs == null) {
return false;
}
- VariableElement leftElement = _getVariableElement(lhs);
- DartType leftType = (leftElement == null) ? _getStaticType(lhs) : leftElement.type;
- DartType staticRightType = _getStaticType(rhs);
- bool isStaticAssignable = staticRightType.isAssignableTo(leftType);
- if (!isStaticAssignable) {
+ VariableElement leftElement = getVariableElement(lhs);
+ DartType leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.type;
+ DartType staticRightType = getStaticType(rhs);
+ if (!staticRightType.isAssignableTo(leftType)) {
String leftName = leftType.displayName;
String rightName = staticRightType.displayName;
if (leftName == rightName) {
- leftName = _getExtendedDisplayName(leftType);
- rightName = _getExtendedDisplayName(staticRightType);
+ leftName = getExtendedDisplayName(leftType);
+ rightName = getExtendedDisplayName(staticRightType);
}
_errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightName, leftName]);
return true;
}
- // TODO(brianwilkerson) Define a hint corresponding to the warning and report it if appropriate.
- // Type propagatedRightType = rhs.getPropagatedType();
- // boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(leftType);
- // if (!isStaticAssignable && !isPropagatedAssignable) {
- // errorReporter.reportError(
- // StaticTypeWarningCode.INVALID_ASSIGNMENT,
- // rhs,
- // staticRightType.getDisplayName(),
- // leftType.getDisplayName());
- // return true;
- // }
return false;
}
@@ -21200,8 +21374,8 @@
if (lhs == null) {
return false;
}
- VariableElement leftElement = _getVariableElement(lhs);
- DartType leftType = (leftElement == null) ? _getStaticType(lhs) : leftElement.type;
+ VariableElement leftElement = getVariableElement(lhs);
+ DartType leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.type;
MethodElement invokedMethod = node.staticElement;
if (invokedMethod == null) {
return false;
@@ -21214,8 +21388,8 @@
String leftName = leftType.displayName;
String rightName = rightType.displayName;
if (leftName == rightName) {
- leftName = _getExtendedDisplayName(leftType);
- rightName = _getExtendedDisplayName(rightType);
+ leftName = getExtendedDisplayName(leftType);
+ rightName = getExtendedDisplayName(rightType);
}
_errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, node.rightHandSide, [rightName, leftName]);
return true;
@@ -21316,6 +21490,26 @@
}
/**
+ * Check that the imported library does not define a loadLibrary function.
+ *
+ * @param node the import directive to evaluate
+ * @param importElement the [ImportElement] retrieved from the node
+ * @return `true` if and only if an error code is generated on the passed node
+ * @see CompileTimeErrorCode#IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION
+ */
+ bool _checkForLoadLibraryFunction(ImportDirective node, ImportElement importElement) {
+ LibraryElement importedLibrary = importElement.importedLibrary;
+ if (importedLibrary == null) {
+ return false;
+ }
+ if (importedLibrary.hasLoadLibraryFunction) {
+ _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, node, [importedLibrary.name]);
+ return true;
+ }
+ return false;
+ }
+
+ /**
* This verifies that the key/value of entries of the given [MapLiteral] are subtypes of the
* key/value types specified in the type arguments.
*
@@ -21657,7 +21851,8 @@
* This checks that passed class declaration overrides all members required by its superclasses
* and interfaces.
*
- * @param node the [ClassDeclaration] to evaluate
+ * @param classNameNode the [SimpleIdentifier] to be used if there is a violation, this is
+ * either the named from the [ClassDeclaration] or from the [ClassTypeAlias].
* @return `true` if and only if an error code is generated on the passed node
* @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
* @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
@@ -21665,7 +21860,7 @@
* @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR
* @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS
*/
- bool _checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) {
+ bool _checkForNonAbstractClassInheritsAbstractMember(SimpleIdentifier classNameNode) {
if (_enclosingClass.isAbstract) {
return false;
}
@@ -21673,8 +21868,6 @@
// Store in local sets the set of all method and accessor names
//
List<MethodElement> methods = _enclosingClass.methods;
- List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
- Set<String> methodsInEnclosingClass = new Set<String>();
for (MethodElement method in methods) {
String methodName = method.name;
// If the enclosing class declares the method noSuchMethod(), then return.
@@ -21684,11 +21877,6 @@
if (methodName == ElementResolver.NO_SUCH_METHOD_METHOD_NAME) {
return false;
}
- methodsInEnclosingClass.add(methodName);
- }
- Set<String> accessorsInEnclosingClass = new Set<String>();
- for (PropertyAccessorElement accessor in accessors) {
- accessorsInEnclosingClass.add(accessor.name);
}
Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>();
//
@@ -21773,22 +21961,22 @@
List<String> stringMembersArray = new List.from(stringMembersArrayListSet);
AnalysisErrorWithProperties analysisError;
if (stringMembersArray.length == 1) {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, node.name, [stringMembersArray[0]]);
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, classNameNode, [stringMembersArray[0]]);
} else if (stringMembersArray.length == 2) {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, node.name, [stringMembersArray[0], stringMembersArray[1]]);
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, classNameNode, [stringMembersArray[0], stringMembersArray[1]]);
} else if (stringMembersArray.length == 3) {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, node.name, [
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, classNameNode, [
stringMembersArray[0],
stringMembersArray[1],
stringMembersArray[2]]);
} else if (stringMembersArray.length == 4) {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, node.name, [
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, classNameNode, [
stringMembersArray[0],
stringMembersArray[1],
stringMembersArray[2],
stringMembersArray[3]]);
} else {
- analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, node.name, [
+ analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, classNameNode, [
stringMembersArray[0],
stringMembersArray[1],
stringMembersArray[2],
@@ -21809,7 +21997,7 @@
* @see StaticTypeWarningCode#NON_BOOL_CONDITION
*/
bool _checkForNonBoolCondition(Expression condition) {
- DartType conditionType = _getStaticType(condition);
+ DartType conditionType = getStaticType(condition);
if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
_errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_CONDITION, condition, []);
return true;
@@ -21826,7 +22014,7 @@
*/
bool _checkForNonBoolExpression(AssertStatement node) {
Expression expression = node.condition;
- DartType type = _getStaticType(expression);
+ DartType type = getStaticType(expression);
if (type is InterfaceType) {
if (!type.isAssignableTo(_boolType)) {
_errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
@@ -21850,7 +22038,7 @@
* @see StaticTypeWarningCode#NON_BOOL_NEGATION_EXPRESSION
*/
bool _checkForNonBoolNegationExpression(Expression expression) {
- DartType conditionType = _getStaticType(expression);
+ DartType conditionType = getStaticType(expression);
if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
_errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression, []);
return true;
@@ -22193,7 +22381,7 @@
* @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
*/
bool _checkForReturnOfInvalidType(Expression returnExpression, DartType expectedReturnType) {
- DartType staticReturnType = _getStaticType(returnExpression);
+ DartType staticReturnType = getStaticType(returnExpression);
if (expectedReturnType.isVoid) {
if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnType.isBottom) {
return false;
@@ -22257,7 +22445,7 @@
bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) {
// prepare 'switch' expression type
Expression expression = node.expression;
- DartType expressionType = _getStaticType(expression);
+ DartType expressionType = getStaticType(expression);
if (expressionType == null) {
return false;
}
@@ -22270,7 +22458,7 @@
SwitchCase switchCase = switchMember as SwitchCase;
// prepare 'case' type
Expression caseExpression = switchCase.expression;
- DartType caseType = _getStaticType(caseExpression);
+ DartType caseType = getStaticType(caseExpression);
// check types
if (expressionType.isAssignableTo(caseType)) {
return false;
@@ -22667,24 +22855,6 @@
}
/**
- * Return a display name for the given type that includes the path to the compilation unit in
- * which the type is defined.
- *
- * @param type the type for which an extended display name is to be returned
- * @return a display name that can help distiguish between two types with the same name
- */
- String _getExtendedDisplayName(DartType type) {
- Element element = type.element;
- if (element != null) {
- Source source = element.source;
- if (source != null) {
- return "${type.displayName} (${source.fullName})";
- }
- }
- return type.displayName;
- }
-
- /**
* Returns the Type (return type) for a given getter.
*
* @param propertyAccessorElement
@@ -22716,35 +22886,26 @@
}
/**
- * Return the static type of the given expression that is to be used for type analysis.
+ * Given a list of directives that have the same prefix, generate an error if there is more than
+ * one import and any of those imports is deferred.
*
- * @param expression the expression whose type is to be returned
- * @return the static type of the given expression
+ * @param directives the list of directives that have the same prefix
+ * @return `true` if an error was generated
+ * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
*/
- DartType _getStaticType(Expression expression) {
- DartType type = expression.staticType;
- if (type == null) {
- // TODO(brianwilkerson) This should never happen.
- return _dynamicType;
- }
- return type;
- }
-
- /**
- * Return the variable element represented by the given expression, or `null` if there is no
- * such element.
- *
- * @param expression the expression whose element is to be returned
- * @return the variable element represented by the expression
- */
- VariableElement _getVariableElement(Expression expression) {
- if (expression is Identifier) {
- Element element = expression.staticElement;
- if (element is VariableElement) {
- return element;
+ bool _hasDeferredPrefixCollision(List<ImportDirective> directives) {
+ bool foundError = false;
+ int count = directives.length;
+ if (count > 1) {
+ for (int i = 0; i < count; i++) {
+ sc.Token deferredToken = directives[i].deferredToken;
+ if (deferredToken != null) {
+ _errorReporter.reportErrorForToken(CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken, []);
+ foundError = true;
+ }
}
}
- return null;
+ return foundError;
}
/**
@@ -22842,7 +23003,7 @@
/**
* Return `true` iff the passed [ClassElement] has a method, getter or setter that
* matches the name of the passed [ExecutableElement] in either the class itself, or one of
- * its' mixins.
+ * its' mixins that is concrete.
*
* By "match", only the name of the member is tested to match, it does not have to equal or be a
* subtype of the passed executable element, this is due to the specific use where this method is
@@ -22857,14 +23018,14 @@
String executableName = executableElt.name;
if (executableElt is MethodElement) {
foundElt = classElt.getMethod(executableName);
- if (foundElt != null) {
+ if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
return true;
}
List<InterfaceType> mixins = classElt.mixins;
for (int i = 0; i < mixins.length && foundElt == null; i++) {
foundElt = mixins[i].getMethod(executableName);
}
- if (foundElt != null) {
+ if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
return true;
}
} else if (executableElt is PropertyAccessorElement) {
@@ -22875,7 +23036,7 @@
if (foundElt == null && propertyAccessorElement.isSetter) {
foundElt = classElt.getSetter(executableName);
}
- if (foundElt != null) {
+ if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
return true;
}
List<InterfaceType> mixins = classElt.mixins;
@@ -22885,7 +23046,7 @@
foundElt = mixins[i].getSetter(executableName);
}
}
- if (foundElt != null) {
+ if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
return true;
}
}
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index 6960402..fa20569 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -335,31 +335,33 @@
static const Keyword AS = const Keyword.con2('AS', 34, "as", true);
- static const Keyword DYNAMIC = const Keyword.con2('DYNAMIC', 35, "dynamic", true);
+ static const Keyword DEFERRED = const Keyword.con2('DEFERRED', 35, "deferred", true);
- static const Keyword EXPORT = const Keyword.con2('EXPORT', 36, "export", true);
+ static const Keyword DYNAMIC = const Keyword.con2('DYNAMIC', 36, "dynamic", true);
- static const Keyword EXTERNAL = const Keyword.con2('EXTERNAL', 37, "external", true);
+ static const Keyword EXPORT = const Keyword.con2('EXPORT', 37, "export", true);
- static const Keyword FACTORY = const Keyword.con2('FACTORY', 38, "factory", true);
+ static const Keyword EXTERNAL = const Keyword.con2('EXTERNAL', 38, "external", true);
- static const Keyword GET = const Keyword.con2('GET', 39, "get", true);
+ static const Keyword FACTORY = const Keyword.con2('FACTORY', 39, "factory", true);
- static const Keyword IMPLEMENTS = const Keyword.con2('IMPLEMENTS', 40, "implements", true);
+ static const Keyword GET = const Keyword.con2('GET', 40, "get", true);
- static const Keyword IMPORT = const Keyword.con2('IMPORT', 41, "import", true);
+ static const Keyword IMPLEMENTS = const Keyword.con2('IMPLEMENTS', 41, "implements", true);
- static const Keyword LIBRARY = const Keyword.con2('LIBRARY', 42, "library", true);
+ static const Keyword IMPORT = const Keyword.con2('IMPORT', 42, "import", true);
- static const Keyword OPERATOR = const Keyword.con2('OPERATOR', 43, "operator", true);
+ static const Keyword LIBRARY = const Keyword.con2('LIBRARY', 43, "library", true);
- static const Keyword PART = const Keyword.con2('PART', 44, "part", true);
+ static const Keyword OPERATOR = const Keyword.con2('OPERATOR', 44, "operator", true);
- static const Keyword SET = const Keyword.con2('SET', 45, "set", true);
+ static const Keyword PART = const Keyword.con2('PART', 45, "part", true);
- static const Keyword STATIC = const Keyword.con2('STATIC', 46, "static", true);
+ static const Keyword SET = const Keyword.con2('SET', 46, "set", true);
- static const Keyword TYPEDEF = const Keyword.con2('TYPEDEF', 47, "typedef", true);
+ static const Keyword STATIC = const Keyword.con2('STATIC', 47, "static", true);
+
+ static const Keyword TYPEDEF = const Keyword.con2('TYPEDEF', 48, "typedef", true);
static const List<Keyword> values = const [
ASSERT,
@@ -397,6 +399,7 @@
WITH,
ABSTRACT,
AS,
+ DEFERRED,
DYNAMIC,
EXPORT,
EXTERNAL,
@@ -1457,11 +1460,6 @@
next = bigSwitch(next);
}
}
- if (next == -1) {
- return next;
- }
- next = _reader.advance();
- _beginToken();
return next;
}
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index eedc729..d09350b 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -20,7 +20,21 @@
/**
* Instances of the class `DirectoryBasedDartSdk` represent a Dart SDK installed in a
- * specified directory.
+ * specified directory. Typical Dart SDK layout is something like...
+ *
+ * <pre>
+ * dart-sdk/
+ * bin/
+ * dart[.exe] <-- VM
+ * lib/
+ * core/
+ * core.dart
+ * ... other core library files ...
+ * ... other libraries ...
+ * util/
+ * ... Dart utilities ...
+ * Chromium/ <-- Dartium typically exists in a sibling directory
+ * </pre>
*/
class DirectoryBasedDartSdk implements DartSdk {
/**
@@ -39,11 +53,26 @@
String _sdkVersion;
/**
+ * The file containing the dart2js executable.
+ */
+ JavaFile _dart2jsExecutable;
+
+ /**
+ * The file containing the dart formatter executable.
+ */
+ JavaFile _dartFmtExecutable;
+
+ /**
* The file containing the Dartium executable.
*/
JavaFile _dartiumExecutable;
/**
+ * The file containing the pub executable.
+ */
+ JavaFile _pubExecutable;
+
+ /**
* The file containing the VM executable.
*/
JavaFile _vmExecutable;
@@ -59,9 +88,34 @@
static String _BIN_DIRECTORY_NAME = "bin";
/**
- * The name of the directory within the SDK directory that contains Chromium.
+ * The name of the directory on Mac that contains dartium.
*/
- static String _CHROMIUM_DIRECTORY_NAME = "chromium";
+ static String _DARTIUM_DIRECTORY_NAME_MAC = "Chromium.app";
+
+ /**
+ * The name of the directory on non-Mac that contains dartium.
+ */
+ static String _DARTIUM_DIRECTORY_NAME = "chromium";
+
+ /**
+ * The name of the dart2js executable on non-windows operating systems.
+ */
+ static String _DART2JS_EXECUTABLE_NAME = "dart2js";
+
+ /**
+ * The name of the file containing the dart2js executable on Windows.
+ */
+ static String _DART2JS_EXECUTABLE_NAME_WIN = "dart2js.bat";
+
+ /**
+ * The name of the dart formatter executable on non-windows operating systems.
+ */
+ static String _DARTFMT_EXECUTABLE_NAME = "dartfmt";
+
+ /**
+ * The name of the dart formatter executable on windows operating systems.
+ */
+ static String _DARTFMT_EXECUTABLE_NAME_WIN = "dartfmt.bat";
/**
* The name of the file containing the Dartium executable on Linux.
@@ -122,9 +176,9 @@
static String _PUB_EXECUTABLE_NAME = "pub";
/**
- * The name of the file within the SDK directory that contains the revision number of the SDK.
+ * The name of the file within the SDK directory that contains the version number of the SDK.
*/
- static String _REVISION_FILE_NAME = "revision";
+ static String _VERSION_FILE_NAME = "version";
/**
* The name of the file containing the VM executable on the Windows operating system.
@@ -177,8 +231,7 @@
*/
DirectoryBasedDartSdk(JavaFile sdkDirectory, [bool useDart2jsPaths = false]) {
this._sdkDirectory = sdkDirectory.getAbsoluteFile();
- _initializeSdk();
- _initializeLibraryMap(useDart2jsPaths);
+ _libraryMap = initialLibraryMap(useDart2jsPaths);
_analysisContext = new AnalysisContextImpl();
_analysisContext.sourceFactory = new SourceFactory([new DartUriResolver(this)]);
List<String> uris = this.uris;
@@ -196,27 +249,57 @@
AnalysisContext get context => _analysisContext;
/**
+ * Return the file containing the dart2js executable, or `null` if it does not exist.
+ *
+ * @return the file containing the dart2js executable
+ */
+ JavaFile get dart2JsExecutable {
+ if (_dart2jsExecutable == null) {
+ _dart2jsExecutable = _verifyExecutable(new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), OSUtilities.isWindows() ? _DART2JS_EXECUTABLE_NAME_WIN : _DART2JS_EXECUTABLE_NAME));
+ }
+ return _dart2jsExecutable;
+ }
+
+ /**
+ * Return the file containing the dart formatter executable, or `null` if it does not exist.
+ *
+ * @return the file containing the dart formatter executable
+ */
+ JavaFile get dartFmtExecutable {
+ if (_dartFmtExecutable == null) {
+ _dartFmtExecutable = _verifyExecutable(new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), OSUtilities.isWindows() ? _DARTFMT_EXECUTABLE_NAME_WIN : _DARTFMT_EXECUTABLE_NAME));
+ }
+ return _dartFmtExecutable;
+ }
+
+ /**
* Return the file containing the Dartium executable, or `null` if it does not exist.
*
* @return the file containing the Dartium executable
*/
JavaFile get dartiumExecutable {
if (_dartiumExecutable == null) {
- JavaFile file = new JavaFile.relative(dartiumWorkingDirectory, dartiumBinaryName);
- if (file.exists()) {
- _dartiumExecutable = file;
- }
+ _dartiumExecutable = _verifyExecutable(new JavaFile.relative(dartiumWorkingDirectory, dartiumBinaryName));
}
return _dartiumExecutable;
}
/**
- * Return the directory where dartium can be found in the Dart SDK (the directory that will be the
- * working directory is Dartium is invoked without changing the default).
+ * Return the directory where dartium can be found (the directory that will be the working
+ * directory is Dartium is invoked without changing the default).
*
* @return the directory where dartium can be found
*/
- JavaFile get dartiumWorkingDirectory => new JavaFile.relative(_sdkDirectory.getParentFile(), _CHROMIUM_DIRECTORY_NAME);
+ JavaFile get dartiumWorkingDirectory => getDartiumWorkingDirectory(_sdkDirectory.getParentFile());
+
+ /**
+ * Return the directory where dartium can be found (the directory that will be the working
+ * directory is Dartium is invoked without changing the default).
+ *
+ * @param installDir the installation directory
+ * @return the directory where dartium can be found
+ */
+ JavaFile getDartiumWorkingDirectory(JavaFile installDir) => new JavaFile.relative(installDir, _DARTIUM_DIRECTORY_NAME);
/**
* Return the directory containing the SDK.
@@ -266,9 +349,10 @@
* @return the file containing the Pub executable
*/
JavaFile get pubExecutable {
- String pubBinaryName = OSUtilities.isWindows() ? _PUB_EXECUTABLE_NAME_WIN : _PUB_EXECUTABLE_NAME;
- JavaFile file = new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), pubBinaryName);
- return file.exists() ? file : null;
+ if (_pubExecutable == null) {
+ _pubExecutable = _verifyExecutable(new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), OSUtilities.isWindows() ? _PUB_EXECUTABLE_NAME_WIN : _PUB_EXECUTABLE_NAME));
+ }
+ return _pubExecutable;
}
@override
@@ -287,11 +371,11 @@
String get sdkVersion {
if (_sdkVersion == null) {
_sdkVersion = DartSdk.DEFAULT_VERSION;
- JavaFile revisionFile = new JavaFile.relative(_sdkDirectory, _REVISION_FILE_NAME);
+ JavaFile revisionFile = new JavaFile.relative(_sdkDirectory, _VERSION_FILE_NAME);
try {
String revision = revisionFile.readAsStringSync();
if (revision != null) {
- _sdkVersion = revision;
+ _sdkVersion = revision.trim();
}
} on JavaIOException catch (exception) {
}
@@ -314,10 +398,7 @@
*/
JavaFile get vmExecutable {
if (_vmExecutable == null) {
- JavaFile file = new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), vmBinaryName);
- if (file.exists()) {
- _vmExecutable = file;
- }
+ _vmExecutable = _verifyExecutable(new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), vmBinaryName));
}
return _vmExecutable;
}
@@ -346,6 +427,23 @@
}
/**
+ * 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
+ * @return the initialized library map
+ */
+ LibraryMap initialLibraryMap(bool useDart2jsPaths) {
+ JavaFile librariesFile = new JavaFile.relative(new JavaFile.relative(libraryDirectory, _INTERNAL_DIR), _LIBRARIES_FILE);
+ try {
+ String contents = librariesFile.readAsStringSync();
+ return new SdkLibrariesReader(useDart2jsPaths).readFromFile(librariesFile, contents);
+ } on JavaException catch (exception) {
+ AnalysisEngine.instance.logger.logError2("Could not initialize the library map from ${librariesFile.getAbsolutePath()}", exception);
+ return new LibraryMap();
+ }
+ }
+
+ /**
* Ensure that the dart VM is executable. If it is not, make it executable and log that it was
* necessary for us to do so.
*/
@@ -381,29 +479,12 @@
}
/**
- * Read all of the configuration files to initialize the library maps.
+ * Verify that the given executable file exists and is executable.
*
- * @param useDart2jsPaths `true` if the dart2js path should be used when it is available
+ * @param file the binary file
+ * @return the file if it exists and is executable, else `null`
*/
- 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(useDart2jsPaths).readFromFile(librariesFile, contents);
- } on JavaException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not initialize the library map from ${librariesFile.getAbsolutePath()}", exception);
- _libraryMap = new LibraryMap();
- }
- }
-
- /**
- * Initialize the state of the SDK.
- */
- void _initializeSdk() {
- if (!OSUtilities.isWindows()) {
- _ensureVmIsExecutable();
- }
- }
+ JavaFile _verifyExecutable(JavaFile file) => file.isExecutable() ? file : null;
}
/**
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 7dbcacd..c38eb08 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -611,6 +611,15 @@
*/
SourceRange getTranslated(int delta) => new SourceRange(offset + delta, length);
+ /**
+ * @return the minimal [SourceRange] that cover this and the given [SourceRange]s.
+ */
+ SourceRange getUnion(SourceRange other) {
+ int newOffset = Math.min(offset, other.offset);
+ int newEnd = Math.max(offset + length, other.offset + other.length);
+ return new SourceRange(newOffset, newEnd - newOffset);
+ }
+
@override
int get hashCode => 31 * offset + length;
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index f28e1f1..f70bc19 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -437,6 +437,52 @@
}
/**
+ * The interface `MapIterator` defines the behavior of objects that iterate over the entries
+ * in a map.
+ *
+ * This interface defines the concept of a current entry and provides methods to access the key and
+ * value in the current entry. When an iterator is first created it will be positioned before the
+ * first entry and there is no current entry until [moveNext] is invoked. When all of the
+ * entries have been accessed there will also be no current entry.
+ *
+ * There is no guarantee made about the order in which the entries are accessible.
+ */
+abstract class MapIterator<K, V> {
+ /**
+ * Return the key associated with the current element.
+ *
+ * @return the key associated with the current element
+ * @throws NoSuchElementException if there is no current element
+ */
+ K get key;
+
+ /**
+ * Return the value associated with the current element.
+ *
+ * @return the value associated with the current element
+ * @throws NoSuchElementException if there is no current element
+ */
+ V get value;
+
+ /**
+ * Advance to the next entry in the map. Return `true` if there is a current element that
+ * can be accessed after this method returns. It is safe to invoke this method even if the
+ * previous invocation returned `false`.
+ *
+ * @return `true` if there is a current element that can be accessed
+ */
+ bool moveNext();
+
+ /**
+ * Set the value associated with the current element to the given value.
+ *
+ * @param newValue the new value to be associated with the current element
+ * @throws NoSuchElementException if there is no current element
+ */
+ void set value(V newValue);
+}
+
+/**
* The class `ListUtilities` defines utility methods useful for working with [List
].
*/
@@ -453,4 +499,182 @@
list.add(elements[i]);
}
}
-}
\ No newline at end of file
+}
+
+/**
+ * Instances of the class `MultipleMapIterator` implement an iterator that can be used to
+ * sequentially access the entries in multiple maps.
+ */
+class MultipleMapIterator<K, V> implements MapIterator<K, V> {
+ /**
+ * The iterators used to access the entries.
+ */
+ List<MapIterator<K, V>> _iterators;
+
+ /**
+ * The index of the iterator currently being used to access the entries.
+ */
+ int _iteratorIndex = -1;
+
+ /**
+ * The current iterator, or `null` if there is no current iterator.
+ */
+ MapIterator<K, V> _currentIterator;
+
+ /**
+ * Initialize a newly created iterator to return the entries from the given maps.
+ *
+ * @param maps the maps containing the entries to be iterated
+ */
+ MultipleMapIterator(List<Map<K, V>> maps) {
+ int count = maps.length;
+ _iterators = new List<MapIterator>(count);
+ for (int i = 0; i < count; i++) {
+ _iterators[i] = new SingleMapIterator<K, V>(maps[i]);
+ }
+ }
+
+ @override
+ K get key {
+ if (_currentIterator == null) {
+ throw new NoSuchElementException();
+ }
+ return _currentIterator.key;
+ }
+
+ @override
+ V get value {
+ if (_currentIterator == null) {
+ throw new NoSuchElementException();
+ }
+ return _currentIterator.value;
+ }
+
+ @override
+ bool moveNext() {
+ if (_iteratorIndex < 0) {
+ if (_iterators.length == 0) {
+ _currentIterator = null;
+ return false;
+ }
+ if (_advanceToNextIterator()) {
+ return true;
+ } else {
+ _currentIterator = null;
+ return false;
+ }
+ }
+ if (_currentIterator.moveNext()) {
+ return true;
+ } else if (_advanceToNextIterator()) {
+ return true;
+ } else {
+ _currentIterator = null;
+ return false;
+ }
+ }
+
+ @override
+ void set value(V newValue) {
+ if (_currentIterator == null) {
+ throw new NoSuchElementException();
+ }
+ _currentIterator.value = newValue;
+ }
+
+ /**
+ * Under the assumption that there are no more entries that can be returned using the current
+ * iterator, advance to the next iterator that has entries.
+ *
+ * @return `true` if there is a current iterator that has entries
+ */
+ bool _advanceToNextIterator() {
+ _iteratorIndex++;
+ while (_iteratorIndex < _iterators.length) {
+ MapIterator<K, V> iterator = _iterators[_iteratorIndex];
+ if (iterator.moveNext()) {
+ _currentIterator = iterator;
+ return true;
+ }
+ _iteratorIndex++;
+ }
+ return false;
+ }
+}
+
+/**
+ * Instances of the class `SingleMapIterator` implement an iterator that can be used to access
+ * the entries in a single map.
+ */
+class SingleMapIterator<K, V> implements MapIterator<K, V> {
+ /**
+ * Returns a new [SingleMapIterator] instance for the given [Map].
+ */
+ static SingleMapIterator forMap(Map map) => new SingleMapIterator(map);
+
+ /**
+ * The [Map] containing the entries to be iterated over.
+ */
+ final Map<K, V> _map;
+
+ /**
+ * The iterator used to access the entries.
+ */
+ Iterator<K> _keyIterator;
+
+ /**
+ * The current key, or `null` if there is no current key.
+ */
+ K _currentKey;
+
+ /**
+ * The current value.
+ */
+ V _currentValue;
+
+ /**
+ * Initialize a newly created iterator to return the entries from the given map.
+ *
+ * @param map the map containing the entries to be iterated over
+ */
+ SingleMapIterator(this._map) {
+ this._keyIterator = _map.keys.iterator;
+ }
+
+ @override
+ K get key {
+ if (_currentKey == null) {
+ throw new NoSuchElementException();
+ }
+ return _currentKey;
+ }
+
+ @override
+ V get value {
+ if (_currentKey == null) {
+ throw new NoSuchElementException();
+ }
+ return _currentValue;
+ }
+
+ @override
+ bool moveNext() {
+ if (_keyIterator.moveNext()) {
+ _currentKey = _keyIterator.current;
+ _currentValue = _map[_currentKey];
+ return true;
+ } else {
+ _currentKey = null;
+ return false;
+ }
+ }
+
+ @override
+ void set value(V newValue) {
+ if (_currentKey == null) {
+ throw new NoSuchElementException();
+ }
+ _currentValue = newValue;
+ _map[_currentKey] = newValue;
+ }
+}
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index d889e35..78089ec 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -58,4 +58,4 @@
_prev._sw.start();
}
}
-}
+}
\ No newline at end of file
diff --git a/pkg/analyzer/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart
index 900b1d27..5c0c314 100644
--- a/pkg/analyzer/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer/lib/src/services/formatter_impl.dart
@@ -530,7 +530,7 @@
visitClassDeclaration(ClassDeclaration node) {
preserveLeadingNewlines();
- visitNodes(node.metadata, followedBy: newlines);
+ visitMemberMetadata(node.metadata);
modifier(node.abstractKeyword);
token(node.classKeyword);
space();
@@ -556,7 +556,7 @@
visitClassTypeAlias(ClassTypeAlias node) {
preserveLeadingNewlines();
- visitNodes(node.metadata, followedBy: newlines);
+ visitMemberMetadata(node.metadata);
modifier(node.abstractKeyword);
token(node.keyword);
space();
@@ -615,7 +615,7 @@
}
visitConstructorDeclaration(ConstructorDeclaration node) {
- visitNodes(node.metadata, followedBy: newlines);
+ visitMemberMetadata(node.metadata);
modifier(node.externalKeyword);
modifier(node.constKeyword);
modifier(node.factoryKeyword);
@@ -650,6 +650,7 @@
newlines();
} else {
preserveLeadingNewlines();
+ space();
}
indent(2);
token(node.separator /* : */);
@@ -742,7 +743,7 @@
}
visitExportDirective(ExportDirective node) {
- visitNodes(node.metadata, followedBy: newlines);
+ visitDirectiveMetadata(node.metadata);
token(node.keyword);
space();
visit(node.uri);
@@ -771,7 +772,7 @@
}
visitFieldDeclaration(FieldDeclaration node) {
- visitNodes(node.metadata, followedBy: newlines);
+ visitMemberMetadata(node.metadata);
modifier(node.staticKeyword);
visit(node.fields);
token(node.semicolon);
@@ -861,7 +862,7 @@
visitFunctionDeclaration(FunctionDeclaration node) {
preserveLeadingNewlines();
- visitNodes(node.metadata, followedBy: newlines);
+ visitMemberMetadata(node.metadata);
modifier(node.externalKeyword);
visitNode(node.returnType, followedBy: space);
modifier(node.propertyKeyword);
@@ -887,7 +888,7 @@
}
visitFunctionTypeAlias(FunctionTypeAlias node) {
- visitNodes(node.metadata, separatedBy: newlines, followedBy: newlines);
+ visitMemberMetadata(node.metadata);
token(node.keyword);
space();
visitNode(node.returnType, followedBy: space);
@@ -941,7 +942,7 @@
}
visitImportDirective(ImportDirective node) {
- visitNodes(node.metadata, followedBy: newlines);
+ visitDirectiveMetadata(node.metadata);
token(node.keyword);
nonBreakingSpace();
visit(node.uri);
@@ -1010,7 +1011,7 @@
}
visitLibraryDirective(LibraryDirective node) {
- visitNodes(node.metadata, followedBy: newlines);
+ visitDirectiveMetadata(node.metadata);
token(node.keyword);
space();
visit(node.name);
@@ -1054,7 +1055,7 @@
}
visitMethodDeclaration(MethodDeclaration node) {
- visitNodes(node.metadata, followedBy: newlines);
+ visitMemberMetadata(node.metadata);
modifier(node.externalKeyword);
modifier(node.modifierKeyword);
visitNode(node.returnType, followedBy: space);
@@ -1181,7 +1182,7 @@
}
visitSimpleFormalParameter(SimpleFormalParameter node) {
- visitNodes(node.metadata, followedBy: space);
+ visitMemberMetadata(node.metadata);
modifier(node.keyword);
visitNode(node.type, followedBy: space);
visit(node.identifier);
@@ -1304,7 +1305,7 @@
}
visitTypeParameter(TypeParameter node) {
- visitNodes(node.metadata, followedBy: space);
+ visitMemberMetadata(node.metadata);
visit(node.name);
token(node.keyword /* extends */, precededBy: space, followedBy: space);
visit(node.bound);
@@ -1335,7 +1336,7 @@
}
visitVariableDeclarationList(VariableDeclarationList node) {
- visitNodes(node.metadata, followedBy: newlines);
+ visitMemberMetadata(node.metadata);
modifier(node.keyword);
visitNode(node.type, followedBy: space);
@@ -1398,6 +1399,24 @@
}
}
+ /// Visit member metadata
+ visitMemberMetadata(NodeList<Annotation> metadata) {
+ visitNodes(metadata,
+ separatedBy: () {
+ space();
+ preserveLeadingNewlines();
+ },
+ followedBy: space);
+ if (metadata != null && metadata.length > 0) {
+ preserveLeadingNewlines();
+ }
+ }
+
+ /// Visit member metadata
+ visitDirectiveMetadata(NodeList<Annotation> metadata) {
+ visitNodes(metadata, separatedBy: newlines, followedBy: newlines);
+ }
+
/// Visit the given function [body], printing the [prefix] before if given
/// body is not empty.
visitPrefixedBody(prefix(), FunctionBody body) {
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index bf3f884..b11960a 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.13.4
+version: 0.13.5
author: Dart Team <misc@dartlang.org>
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 b582327..5a478f4 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -484,7 +484,7 @@
static ImplementsClause implementsClause(List<TypeName> types) => new ImplementsClause(TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS), list(types));
- static ImportDirective importDirective(List<Annotation> metadata, String uri, String prefix, List<Combinator> combinators) => new ImportDirective(null, metadata, TokenFactory.tokenFromKeyword(Keyword.IMPORT), string2(uri), prefix == null ? null : TokenFactory.tokenFromKeyword(Keyword.AS), prefix == null ? null : identifier3(prefix), list(combinators), TokenFactory.tokenFromType(TokenType.SEMICOLON));
+ static ImportDirective importDirective(List<Annotation> metadata, String uri, String prefix, List<Combinator> combinators) => new ImportDirective(null, metadata, TokenFactory.tokenFromKeyword(Keyword.IMPORT), string2(uri), null, prefix == null ? null : TokenFactory.tokenFromKeyword(Keyword.AS), prefix == null ? null : identifier3(prefix), list(combinators), TokenFactory.tokenFromType(TokenType.SEMICOLON));
static ImportDirective importDirective2(String uri, String prefix, List<Combinator> combinators) => importDirective(new List<Annotation>(), uri, prefix, combinators);
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index a20ce5f..3672606 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2745,10 +2745,22 @@
JUnitTestCase.assertNotNull(clause.keyword);
}
+ void test_parseImportDirective_deferred() {
+ ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' deferred as a;");
+ JUnitTestCase.assertNotNull(directive.keyword);
+ JUnitTestCase.assertNotNull(directive.uri);
+ JUnitTestCase.assertNotNull(directive.deferredToken);
+ JUnitTestCase.assertNotNull(directive.asToken);
+ JUnitTestCase.assertNotNull(directive.prefix);
+ EngineTestCase.assertSizeOfList(0, directive.combinators);
+ JUnitTestCase.assertNotNull(directive.semicolon);
+ }
+
void test_parseImportDirective_hide() {
ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' hide A, B;");
JUnitTestCase.assertNotNull(directive.keyword);
JUnitTestCase.assertNotNull(directive.uri);
+ JUnitTestCase.assertNull(directive.deferredToken);
JUnitTestCase.assertNull(directive.asToken);
JUnitTestCase.assertNull(directive.prefix);
EngineTestCase.assertSizeOfList(1, directive.combinators);
@@ -2759,6 +2771,7 @@
ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart';");
JUnitTestCase.assertNotNull(directive.keyword);
JUnitTestCase.assertNotNull(directive.uri);
+ JUnitTestCase.assertNull(directive.deferredToken);
JUnitTestCase.assertNull(directive.asToken);
JUnitTestCase.assertNull(directive.prefix);
EngineTestCase.assertSizeOfList(0, directive.combinators);
@@ -2769,6 +2782,7 @@
ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a;");
JUnitTestCase.assertNotNull(directive.keyword);
JUnitTestCase.assertNotNull(directive.uri);
+ JUnitTestCase.assertNull(directive.deferredToken);
JUnitTestCase.assertNotNull(directive.asToken);
JUnitTestCase.assertNotNull(directive.prefix);
EngineTestCase.assertSizeOfList(0, directive.combinators);
@@ -2779,6 +2793,7 @@
ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a hide A show B;");
JUnitTestCase.assertNotNull(directive.keyword);
JUnitTestCase.assertNotNull(directive.uri);
+ JUnitTestCase.assertNull(directive.deferredToken);
JUnitTestCase.assertNotNull(directive.asToken);
JUnitTestCase.assertNotNull(directive.prefix);
EngineTestCase.assertSizeOfList(2, directive.combinators);
@@ -2789,6 +2804,7 @@
ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a show B hide A;");
JUnitTestCase.assertNotNull(directive.keyword);
JUnitTestCase.assertNotNull(directive.uri);
+ JUnitTestCase.assertNull(directive.deferredToken);
JUnitTestCase.assertNotNull(directive.asToken);
JUnitTestCase.assertNotNull(directive.prefix);
EngineTestCase.assertSizeOfList(2, directive.combinators);
@@ -2799,6 +2815,7 @@
ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' show A, B;");
JUnitTestCase.assertNotNull(directive.keyword);
JUnitTestCase.assertNotNull(directive.uri);
+ JUnitTestCase.assertNull(directive.deferredToken);
JUnitTestCase.assertNull(directive.asToken);
JUnitTestCase.assertNull(directive.prefix);
EngineTestCase.assertSizeOfList(1, directive.combinators);
@@ -5887,6 +5904,10 @@
final __test = new SimpleParserTest();
runJUnitTest(__test, __test.test_parseImplementsClause_single);
});
+ _ut.test('test_parseImportDirective_deferred', () {
+ final __test = new SimpleParserTest();
+ runJUnitTest(__test, __test.test_parseImportDirective_deferred);
+ });
_ut.test('test_parseImportDirective_hide', () {
final __test = new SimpleParserTest();
runJUnitTest(__test, __test.test_parseImportDirective_hide);
@@ -7313,7 +7334,7 @@
* @param methodName the name of the parse method that should be invoked to parse the source
* @param objects the values of the arguments to the method
* @param source the source to be parsed by the parse method
- * @param errorCodes the error codes of the errors that should be generated
+ * @param errors the errors that should be generated
* @return the result of invoking the method
* @throws Exception if the method could not be invoked or throws an exception
* @throws AssertionFailedError if the result is `null` or the errors produced while
@@ -9995,6 +10016,13 @@
ParserTestCase.parse4("parseStringLiteral", "'\$x\$'", [ParserErrorCode.MISSING_IDENTIFIER]);
}
+ void test_expectedInterpolationIdentifier_emptyString() {
+ // The scanner inserts an empty string token between the two $'s; we need to make sure that the
+ // MISSING_IDENTIFIER error that is generated has a nonzero width so that it will show up in
+ // the editor UI.
+ ParserTestCase.parse2("parseStringLiteral", <Object> [], "'\$\$foo'", [new AnalysisError.con2(null, 2, 1, ParserErrorCode.MISSING_IDENTIFIER, [])]);
+ }
+
void test_expectedStringLiteral() {
StringLiteral expression = ParserTestCase.parse4("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
JUnitTestCase.assertTrue(expression.isSynthetic);
@@ -10422,6 +10450,10 @@
JUnitTestCase.assertNotNull(unit);
}
+ void test_missingPrefixInDeferredImport() {
+ ParserTestCase.parseCompilationUnit("import 'foo.dart' deferred;", [ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT]);
+ }
+
void test_missingStatement() {
ParserTestCase.parseStatement("is", [ParserErrorCode.MISSING_STATEMENT]);
}
@@ -11003,6 +11035,10 @@
final __test = new ErrorParserTest();
runJUnitTest(__test, __test.test_expectedInterpolationIdentifier);
});
+ _ut.test('test_expectedInterpolationIdentifier_emptyString', () {
+ final __test = new ErrorParserTest();
+ runJUnitTest(__test, __test.test_expectedInterpolationIdentifier_emptyString);
+ });
_ut.test('test_expectedStringLiteral', () {
final __test = new ErrorParserTest();
runJUnitTest(__test, __test.test_expectedStringLiteral);
@@ -11403,6 +11439,10 @@
final __test = new ErrorParserTest();
runJUnitTest(__test, __test.test_missingNameInPartOfDirective);
});
+ _ut.test('test_missingPrefixInDeferredImport', () {
+ final __test = new ErrorParserTest();
+ runJUnitTest(__test, __test.test_missingPrefixInDeferredImport);
+ });
_ut.test('test_missingStatement', () {
final __test = new ErrorParserTest();
runJUnitTest(__test, __test.test_missingStatement);
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 4054c21..b719bc4 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -20,6 +20,7 @@
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/utilities_collection.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
import 'package:unittest/unittest.dart' as _ut;
@@ -2077,6 +2078,17 @@
verify([source]);
}
+ void test_importDeferredLibraryWithLoadFunction() {
+ addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "f() {}"]));
+ Source source = addSource(EngineTestCase.createSource([
+ "library root;",
+ "import 'lib1.dart' deferred as lib1;",
+ "main() { lib1.f(); }"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_importDuplicatedLibraryName() {
Source source = addSource(EngineTestCase.createSource([
"library test;",
@@ -2219,6 +2231,57 @@
verify([source]);
}
+ void test_inconsistentMethodInheritance_overrideTrumpsInherits_getter() {
+ // 16134
+ Source source = addSource(EngineTestCase.createSource([
+ "class B<S> {",
+ " S get g => null;",
+ "}",
+ "abstract class I<U> {",
+ " U get g => null;",
+ "}",
+ "class C extends B<double> implements I<int> {",
+ " num get g => null;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_inconsistentMethodInheritance_overrideTrumpsInherits_method() {
+ // 16134
+ Source source = addSource(EngineTestCase.createSource([
+ "class B<S> {",
+ " m(S s) => null;",
+ "}",
+ "abstract class I<U> {",
+ " m(U u) => null;",
+ "}",
+ "class C extends B<double> implements I<int> {",
+ " m(num n) => null;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_inconsistentMethodInheritance_overrideTrumpsInherits_setter() {
+ // 16134
+ Source source = addSource(EngineTestCase.createSource([
+ "class B<S> {",
+ " set t(S s) {}",
+ "}",
+ "abstract class I<U> {",
+ " set t(U u) {}",
+ "}",
+ "class C extends B<double> implements I<int> {",
+ " set t(num n) {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_inconsistentMethodInheritance_simple() {
Source source = addSource(EngineTestCase.createSource([
"abstract class A {",
@@ -3024,6 +3087,46 @@
verify([source]);
}
+ void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() {
+ // 15979
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class M {}",
+ "abstract class A {}",
+ "abstract class I {",
+ " m();",
+ "}",
+ "abstract class B = A with M implements I;"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin() {
+ // 15979
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class M {",
+ " m();",
+ "}",
+ "abstract class A {}",
+ "abstract class B = A with M;"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() {
+ // 15979
+ Source source = addSource(EngineTestCase.createSource([
+ "class M {}",
+ "abstract class A {",
+ " m();",
+ "}",
+ "abstract class B = A with M;"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter() {
// 17034
Source source = addSource(EngineTestCase.createSource([
@@ -3881,6 +3984,21 @@
verify([source]);
}
+ void test_sharedDeferredPrefix() {
+ addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "f1() {}"]));
+ addNamedSource("/lib2.dart", EngineTestCase.createSource(["library lib2;", "f2() {}"]));
+ addNamedSource("/lib3.dart", EngineTestCase.createSource(["library lib3;", "f3() {}"]));
+ Source source = addSource(EngineTestCase.createSource([
+ "library root;",
+ "import 'lib1.dart' deferred as lib1;",
+ "import 'lib2.dart' as lib;",
+ "import 'lib3.dart' as lib;",
+ "main() { lib1.f1(); lib.f2(); lib.f3(); }"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_staticAccessToInstanceMember_annotation() {
Source source = addSource(EngineTestCase.createSource([
"class A {",
@@ -5008,6 +5126,10 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_typeParameter);
});
+ _ut.test('test_importDeferredLibraryWithLoadFunction', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_importDeferredLibraryWithLoadFunction);
+ });
_ut.test('test_importDuplicatedLibraryName', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_importDuplicatedLibraryName);
@@ -5048,6 +5170,18 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_inconsistentMethodInheritance_methods_typeParameters1);
});
+ _ut.test('test_inconsistentMethodInheritance_overrideTrumpsInherits_getter', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_inconsistentMethodInheritance_overrideTrumpsInherits_getter);
+ });
+ _ut.test('test_inconsistentMethodInheritance_overrideTrumpsInherits_method', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_inconsistentMethodInheritance_overrideTrumpsInherits_method);
+ });
+ _ut.test('test_inconsistentMethodInheritance_overrideTrumpsInherits_setter', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_inconsistentMethodInheritance_overrideTrumpsInherits_setter);
+ });
_ut.test('test_inconsistentMethodInheritance_simple', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_inconsistentMethodInheritance_simple);
@@ -5344,6 +5478,18 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_setter);
});
+ _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface);
+ });
+ _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin);
+ });
+ _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass);
+ });
_ut.test('test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter);
@@ -5624,6 +5770,10 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_reversedTypeArguments);
});
+ _ut.test('test_sharedDeferredPrefix', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_sharedDeferredPrefix);
+ });
_ut.test('test_staticAccessToInstanceMember_annotation', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_staticAccessToInstanceMember_annotation);
@@ -7774,55 +7924,6 @@
verify([source]);
}
- void fail_overriddingPrivateMember_getter() {
- Source source = addSource(EngineTestCase.createSource([
- "import 'lib1.dart';",
- "class B extends A {",
- " get _g => 0;",
- "}"]));
- Source source2 = addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " get _g => 0;", "}"]));
- resolve(source);
- assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
- verify([source, source2]);
- }
-
- void fail_overriddingPrivateMember_method() {
- Source source = addSource(EngineTestCase.createSource([
- "import 'lib1.dart';",
- "class B extends A {",
- " _m(int x) => 0;",
- "}"]));
- Source source2 = addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " _m(int x) => 0;", "}"]));
- resolve(source);
- assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
- verify([source, source2]);
- }
-
- void fail_overriddingPrivateMember_method2() {
- Source source = addSource(EngineTestCase.createSource([
- "import 'lib1.dart';",
- "class B extends A {}",
- "class C extends B {",
- " _m(int x) => 0;",
- "}"]));
- Source source2 = addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " _m(int x) => 0;", "}"]));
- resolve(source);
- assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
- verify([source, source2]);
- }
-
- void fail_overriddingPrivateMember_setter() {
- Source source = addSource(EngineTestCase.createSource([
- "import 'lib1.dart';",
- "class B extends A {",
- " set _s(int x) {}",
- "}"]));
- Source source2 = addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " set _s(int x) {}", "}"]));
- resolve(source);
- assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
- verify([source, source2]);
- }
-
void fail_overrideEqualsButNotHashCode() {
Source source = addSource(EngineTestCase.createSource(["class A {", " bool operator ==(x) {}", "}"]));
resolve(source);
@@ -8346,6 +8447,75 @@
verify([source]);
}
+ void test_invalidAssignment_instanceVariable() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {",
+ " int x;",
+ "}",
+ "f(var y) {",
+ " A a;",
+ " if(y is String) {",
+ " a.x = y;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_invalidAssignment_localVariable() {
+ Source source = addSource(EngineTestCase.createSource([
+ "f(var y) {",
+ " if(y is String) {",
+ " int x = y;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_invalidAssignment_message() {
+ // The implementation of HintCode.INVALID_ASSIGNMENT assumes that
+ // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message.
+ JUnitTestCase.assertEquals(HintCode.INVALID_ASSIGNMENT.message, StaticTypeWarningCode.INVALID_ASSIGNMENT.message);
+ }
+
+ void test_invalidAssignment_staticVariable() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {",
+ " static int x;",
+ "}",
+ "f(var y) {",
+ " if(y is String) {",
+ " A.x = y;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_invalidAssignment_variableDeclaration() {
+ // 17971
+ Source source = addSource(EngineTestCase.createSource([
+ "class Point {",
+ " final num x, y;",
+ " Point(this.x, this.y);",
+ " Point operator +(Point other) {",
+ " return new Point(x+other.x, y+other.y);",
+ " }",
+ "}",
+ "main() {",
+ " var p1 = new Point(0, 0);",
+ " var p2 = new Point(10, 10);",
+ " int n = p1 + p2;",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
void test_isDouble() {
Source source = addSource(EngineTestCase.createSource(["var v = 1 is double;"]));
resolve(source);
@@ -8943,6 +9113,26 @@
final __test = new HintCodeTest();
runJUnitTest(__test, __test.test_duplicateImport3);
});
+ _ut.test('test_invalidAssignment_instanceVariable', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_invalidAssignment_instanceVariable);
+ });
+ _ut.test('test_invalidAssignment_localVariable', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_invalidAssignment_localVariable);
+ });
+ _ut.test('test_invalidAssignment_message', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_invalidAssignment_message);
+ });
+ _ut.test('test_invalidAssignment_staticVariable', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_invalidAssignment_staticVariable);
+ });
+ _ut.test('test_invalidAssignment_variableDeclaration', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_invalidAssignment_variableDeclaration);
+ });
_ut.test('test_isDouble', () {
final __test = new HintCodeTest();
runJUnitTest(__test, __test.test_isDouble);
@@ -9634,6 +9824,12 @@
*/
CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) => _analysisContext.resolveCompilationUnit(source, library);
+ @override
+ void tearDown() {
+ _analysisContext = null;
+ super.tearDown();
+ }
+
/**
* Verify that all of the identifiers in the compilation units associated with the given sources
* have been resolved.
@@ -12341,6 +12537,17 @@
verify([source]);
}
+ void test_importDeferredLibraryWithLoadFunction() {
+ addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "loadLibrary() {}", "f() {}"]));
+ Source source = addSource(EngineTestCase.createSource([
+ "library root;",
+ "import 'lib1.dart' deferred as lib1;",
+ "main() { lib1.f(); }"]));
+ resolve(source);
+ assertErrors(source, [CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]);
+ verify([source]);
+ }
+
void test_importInternalLibrary() {
Source source = addSource(EngineTestCase.createSource(["import 'dart:_interceptors';"]));
resolve(source);
@@ -13732,6 +13939,19 @@
verify([source]);
}
+ void test_sharedDeferredPrefix() {
+ addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "f1() {}"]));
+ addNamedSource("/lib2.dart", EngineTestCase.createSource(["library lib2;", "f2() {}"]));
+ Source source = addSource(EngineTestCase.createSource([
+ "library root;",
+ "import 'lib1.dart' deferred as lib;",
+ "import 'lib2.dart' as lib;",
+ "main() { lib.f1(); lib.f2(); }"]));
+ resolve(source);
+ assertErrors(source, [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]);
+ verify([source]);
+ }
+
void test_superInInvalidContext_binaryExpression() {
Source source = addSource(EngineTestCase.createSource(["var v = super + 0;"]));
resolve(source);
@@ -14792,6 +15012,10 @@
final __test = new CompileTimeErrorCodeTest();
runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_superConstructorInvocation);
});
+ _ut.test('test_importDeferredLibraryWithLoadFunction', () {
+ final __test = new CompileTimeErrorCodeTest();
+ runJUnitTest(__test, __test.test_importDeferredLibraryWithLoadFunction);
+ });
_ut.test('test_importInternalLibrary', () {
final __test = new CompileTimeErrorCodeTest();
runJUnitTest(__test, __test.test_importInternalLibrary);
@@ -15396,6 +15620,10 @@
final __test = new CompileTimeErrorCodeTest();
runJUnitTest(__test, __test.test_returnInGenerativeConstructor_expressionFunctionBody);
});
+ _ut.test('test_sharedDeferredPrefix', () {
+ final __test = new CompileTimeErrorCodeTest();
+ runJUnitTest(__test, __test.test_sharedDeferredPrefix);
+ });
_ut.test('test_superInInvalidContext_binaryExpression', () {
final __test = new CompileTimeErrorCodeTest();
runJUnitTest(__test, __test.test_superInInvalidContext_binaryExpression);
@@ -17098,6 +17326,58 @@
}
class StaticWarningCodeTest extends ResolverTestCase {
+ void fail_invalidGetterOverrideReturnType_twoInterfaces_conflicting() {
+ // 17983
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class I<U> {",
+ " U get g => null;",
+ "}",
+ "abstract class J<V> {",
+ " V get g => null;",
+ "}",
+ "class B implements I<int>, J<String> {",
+ " double get g => null;",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]);
+ verify([source]);
+ }
+
+ void fail_invalidMethodOverrideNormalParamType_twoInterfaces_conflicting() {
+ // 17983
+ // language/override_inheritance_generic_test/08
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class I<U> {",
+ " m(U u) => null;",
+ "}",
+ "abstract class J<V> {",
+ " m(V v) => null;",
+ "}",
+ "class B implements I<int>, J<String> {",
+ " m(double d) {}",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]);
+ verify([source]);
+ }
+
+ void fail_invalidSetterOverrideNormalParamType_twoInterfaces_conflicting() {
+ // 17983
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class I<U> {",
+ " set s(U u) {}",
+ "}",
+ "abstract class J<V> {",
+ " set s(V v) {}",
+ "}",
+ "class B implements I<int>, J<String> {",
+ " set s(double d) {}",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
+ verify([source]);
+ }
+
void fail_undefinedGetter() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
@@ -18286,7 +18566,7 @@
verify([source]);
}
- void test_invalidMethodOverrideNormalParamType() {
+ void test_invalidMethodOverrideNormalParamType_interface() {
Source source = addSource(EngineTestCase.createSource([
"class A {",
" m(int a) {}",
@@ -18299,6 +18579,35 @@
verify([source]);
}
+ void test_invalidMethodOverrideNormalParamType_superclass() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {",
+ " m(int a) {}",
+ "}",
+ "class B extends A {",
+ " m(String a) {}",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]);
+ verify([source]);
+ }
+
+ void test_invalidMethodOverrideNormalParamType_superclass_interface() {
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class I<U> {",
+ " m(U u) => null;",
+ "}",
+ "abstract class J<V> {",
+ " m(V v) => null;",
+ "}",
+ "class B extends I<int> implements J<String> {",
+ " m(double d) {}",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]);
+ verify([source]);
+ }
+
void test_invalidMethodOverrideNormalParamType_twoInterfaces() {
Source source = addSource(EngineTestCase.createSource([
"abstract class I {",
@@ -18562,6 +18871,23 @@
verify([source]);
}
+ void test_invalidSetterOverrideNormalParamType_superclass_interface() {
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class I {",
+ " set setter14(int _) => null;",
+ "}",
+ "abstract class J {",
+ " set setter14(num _) => null;",
+ "}",
+ "abstract class A extends I implements J {}",
+ "class B extends A {",
+ " set setter14(String _) => null;",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
+ verify([source]);
+ }
+
void test_invalidSetterOverrideNormalParamType_twoInterfaces() {
// test from language/override_inheritance_field_test_34.dart
Source source = addSource(EngineTestCase.createSource([
@@ -18815,6 +19141,46 @@
verify([source]);
}
+ void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() {
+ // 15979
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class M {}",
+ "abstract class A {}",
+ "abstract class I {",
+ " m();",
+ "}",
+ "class B = A with M implements I;"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ verify([source]);
+ }
+
+ void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin() {
+ // 15979
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class M {",
+ " m();",
+ "}",
+ "abstract class A {}",
+ "class B = A with M;"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ verify([source]);
+ }
+
+ void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() {
+ // 15979
+ Source source = addSource(EngineTestCase.createSource([
+ "class M {}",
+ "abstract class A {",
+ " m();",
+ "}",
+ "class B = A with M;"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ verify([source]);
+ }
+
void test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation() {
// 15028
Source source = addSource(EngineTestCase.createSource([
@@ -19935,9 +20301,17 @@
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_invalidMethodOverrideNamedParamType);
});
- _ut.test('test_invalidMethodOverrideNormalParamType', () {
+ _ut.test('test_invalidMethodOverrideNormalParamType_interface', () {
final __test = new StaticWarningCodeTest();
- runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType);
+ runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType_interface);
+ });
+ _ut.test('test_invalidMethodOverrideNormalParamType_superclass', () {
+ final __test = new StaticWarningCodeTest();
+ runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType_superclass);
+ });
+ _ut.test('test_invalidMethodOverrideNormalParamType_superclass_interface', () {
+ final __test = new StaticWarningCodeTest();
+ runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType_superclass_interface);
});
_ut.test('test_invalidMethodOverrideNormalParamType_twoInterfaces', () {
final __test = new StaticWarningCodeTest();
@@ -20015,6 +20389,10 @@
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType);
});
+ _ut.test('test_invalidSetterOverrideNormalParamType_superclass_interface', () {
+ final __test = new StaticWarningCodeTest();
+ runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType_superclass_interface);
+ });
_ut.test('test_invalidSetterOverrideNormalParamType_twoInterfaces', () {
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType_twoInterfaces);
@@ -20099,6 +20477,18 @@
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberFour);
});
+ _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface', () {
+ final __test = new StaticWarningCodeTest();
+ runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface);
+ });
+ _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin', () {
+ final __test = new StaticWarningCodeTest();
+ runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin);
+ });
+ _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass', () {
+ final __test = new StaticWarningCodeTest();
+ runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass);
+ });
_ut.test('test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation', () {
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation);
@@ -20414,6 +20804,8 @@
return source;
}
+ CompilationUnitElement getDefiningUnitElement(Source source) => context.getCompilationUnitElement(source, source);
+
CompilationUnit resolveDefiningUnit(Source source) {
LibraryElement libraryElement = context.computeLibraryElement(source);
return context.resolveCompilationUnit(source, libraryElement);
@@ -20775,6 +21167,7 @@
//
// Force the referenced types to be cached.
//
+ objectType;
boolType;
stringType;
//
@@ -22393,8 +22786,8 @@
EngineTestCase.assertSizeOfMap(0, namedTypes);
} else {
EngineTestCase.assertSizeOfMap(expectedNamedTypes.length, namedTypes);
- for (MapEntry<String, DartType> entry in getMapEntrySet(expectedNamedTypes)) {
- JUnitTestCase.assertSame(entry.getValue(), namedTypes[entry.getKey()]);
+ for (MapIterator<String, DartType> iter = SingleMapIterator.forMap(expectedNamedTypes); iter.moveNext();) {
+ JUnitTestCase.assertSame(iter.value, namedTypes[iter.key]);
}
}
JUnitTestCase.assertSame(expectedReturnType, functionType.returnType);
@@ -23056,19 +23449,6 @@
verify([source]);
}
- void test_overriddingPrivateMember_sameLibrary() {
- Source source = addSource(EngineTestCase.createSource([
- "class A {",
- " _m(int x) => 0;",
- "}",
- "class B extends A {",
- " _m(int x) => 0;",
- "}"]));
- resolve(source);
- assertNoErrors(source);
- verify([source]);
- }
-
void test_overrideEqualsButNotHashCode() {
Source source = addSource(EngineTestCase.createSource([
"class A {",
@@ -23596,10 +23976,6 @@
final __test = new NonHintCodeTest();
runJUnitTest(__test, __test.test_missingReturn_voidReturnType);
});
- _ut.test('test_overriddingPrivateMember_sameLibrary', () {
- final __test = new NonHintCodeTest();
- runJUnitTest(__test, __test.test_overriddingPrivateMember_sameLibrary);
- });
_ut.test('test_overrideEqualsButNotHashCode', () {
final __test = new NonHintCodeTest();
runJUnitTest(__test, __test.test_overrideEqualsButNotHashCode);
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 0d52188..9bbf199 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -302,6 +302,14 @@
}
class ScannerTest extends JUnitTestCase {
+ void fail_incomplete_string_interpolation() {
+ // https://code.google.com/p/dart/issues/detail?id=18073
+ _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, "\"foo \${bar", [
+ new StringToken(TokenType.STRING, "\"foo ", 0),
+ new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 5),
+ new StringToken(TokenType.IDENTIFIER, "bar", 7)]);
+ }
+
void test_ampersand() {
_assertToken(TokenType.AMPERSAND, "&");
}
@@ -471,7 +479,7 @@
}
void test_illegalChar_cyrillicLetter_middle() {
- _assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "Shche\u0433lov");
+ _assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 5, "Shche\u0433lov");
}
void test_illegalChar_cyrillicLetter_start() {
@@ -542,6 +550,10 @@
_assertKeywordToken("default");
}
+ void test_keyword_deferred() {
+ _assertKeywordToken("deferred");
+ }
+
void test_keyword_do() {
_assertKeywordToken("do");
}
@@ -1092,6 +1104,22 @@
}
/**
+ * Assert that scanning the given source produces an error with the given code, and also produces
+ * the given tokens.
+ *
+ * @param expectedError the error that should be produced
+ * @param expectedOffset the string offset that should be associated with the error
+ * @param source the source to be scanned to produce the error
+ * @param expectedTokens the tokens that are expected to be in the source
+ */
+ void _assertErrorAndTokens(ScannerErrorCode expectedError, int expectedOffset, String source, List<Token> expectedTokens) {
+ GatheringErrorListener listener = new GatheringErrorListener();
+ Token token = _scanWithListener(source, listener);
+ listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [source.codeUnitAt(expectedOffset)])]);
+ _checkTokens(token, expectedTokens);
+ }
+
+ /**
* Assert that when scanned the given source contains a single keyword token with the same lexeme
* as the original source.
*
@@ -1190,7 +1218,12 @@
*/
void _assertTokens(String source, List<Token> expectedTokens) {
Token token = _scan(source);
- JUnitTestCase.assertNotNull(token);
+ _checkTokens(token, expectedTokens);
+ }
+
+ void _checkTokens(Token firstToken, List<Token> expectedTokens) {
+ JUnitTestCase.assertNotNull(firstToken);
+ Token token = firstToken;
for (int i = 0; i < expectedTokens.length; i++) {
Token expectedToken = expectedTokens[i];
JUnitTestCase.assertEqualsMsg("Wrong type for token ${i}", expectedToken.type, token.type);
@@ -1455,6 +1488,10 @@
final __test = new ScannerTest();
runJUnitTest(__test, __test.test_keyword_default);
});
+ _ut.test('test_keyword_deferred', () {
+ final __test = new ScannerTest();
+ runJUnitTest(__test, __test.test_keyword_deferred);
+ });
_ut.test('test_keyword_do', () {
final __test = new ScannerTest();
runJUnitTest(__test, __test.test_keyword_do);
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 2490233..435d3ce 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_junit.dart';
import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/scanner.dart';
@@ -142,9 +143,9 @@
//
// Compare the expected and actual number of each type of error.
//
- for (MapEntry<ErrorCode, int> entry in getMapEntrySet(expectedCounts)) {
- ErrorCode code = entry.getKey();
- int expectedCount = entry.getValue();
+ for (MapIterator<ErrorCode, int> iter = SingleMapIterator.forMap(expectedCounts); iter.moveNext();) {
+ ErrorCode code = iter.key;
+ int expectedCount = iter.value;
int actualCount;
List<AnalysisError> list = errorsByCode.remove(code);
if (list == null) {
@@ -168,9 +169,9 @@
//
// Check that there are no more errors in the actual-errors map, otherwise, record message.
//
- for (MapEntry<ErrorCode, List<AnalysisError>> entry in getMapEntrySet(errorsByCode)) {
- ErrorCode code = entry.getKey();
- List<AnalysisError> actualErrors = entry.getValue();
+ for (MapIterator<ErrorCode, List<AnalysisError>> iter = SingleMapIterator.forMap(errorsByCode); iter.moveNext();) {
+ ErrorCode code = iter.key;
+ List<AnalysisError> actualErrors = iter.value;
int actualCount = actualErrors.length;
if (builder.length == 0) {
builder.append("Expected ");
@@ -401,7 +402,7 @@
return true;
}
}
- return true;
+ return false;
}
}
diff --git a/pkg/analyzer/test/services/data/cu_tests.data b/pkg/analyzer/test/services/data/cu_tests.data
index 65b6c42..6ed971d 100644
--- a/pkg/analyzer/test/services/data/cu_tests.data
+++ b/pkg/analyzer/test/services/data/cu_tests.data
@@ -216,12 +216,12 @@
>>> Single initializers can be on one line
class Foo extends Bar {
final int b;
- Foo(int a, this.b): super(a);
+ Foo(int a, this.b) : super(a);
}
<<<
class Foo extends Bar {
final int b;
- Foo(int a, this.b): super(a);
+ Foo(int a, this.b) : super(a);
}
>>> (or not)
class Foo extends Bar {
@@ -246,4 +246,28 @@
Foo(int a, int b)
: super(a),
this.b = b == null ? 0 : b;
+}
+>>> dartbug.com/17837
+@meta class Foo {
+ @meta String foo;
+ @meta int bar() => 42;
+}
+@meta
+class Bar {
+ @meta
+ String foo;
+ @meta
+ int bar() => 42;
+}
+<<<
+@meta class Foo {
+ @meta String foo;
+ @meta int bar() => 42;
+}
+@meta
+class Bar {
+ @meta
+ String foo;
+ @meta
+ int bar() => 42;
}
\ No newline at end of file
diff --git a/pkg/barback/lib/src/transform.dart b/pkg/barback/lib/src/transform.dart
index 25c260a..268849d 100644
--- a/pkg/barback/lib/src/transform.dart
+++ b/pkg/barback/lib/src/transform.dart
@@ -57,7 +57,10 @@
/// Gets the asset for an input [id].
///
/// If an input with [id] cannot be found, throws an [AssetNotFoundException].
- Future<Asset> getInput(AssetId id) => _node.getInput(id);
+ Future<Asset> getInput(AssetId id) {
+ if (id == _node.primary.id) return syncFuture(() => primaryInput);
+ return _node.getInput(id);
+ }
/// A convenience method to the contents of the input with [id] as a string.
///
diff --git a/pkg/barback/lib/src/transform_node.dart b/pkg/barback/lib/src/transform_node.dart
index 5402849..ecd8d8f 100644
--- a/pkg/barback/lib/src/transform_node.dart
+++ b/pkg/barback/lib/src/transform_node.dart
@@ -10,6 +10,7 @@
import 'asset_id.dart';
import 'asset_node.dart';
import 'declaring_transform.dart';
+import 'declaring_transformer.dart';
import 'errors.dart';
import 'lazy_transformer.dart';
import 'log.dart';
@@ -55,6 +56,8 @@
/// The controllers for the asset nodes emitted by this node.
final _outputControllers = new Map<AssetId, AssetNodeController>();
+ /// The ids of inputs the transformer tried and failed to read last time it
+ /// ran.
final _missingInputs = new Set<AssetId>();
/// The controller that's used to pass [primary] through [this] if it's not
@@ -89,6 +92,9 @@
Stream<LogEntry> get onLog => _onLogPool.stream;
final _onLogPool = new StreamPool<LogEntry>.broadcast();
+ /// A controller for log entries emitted by this node.
+ final _onLogController = new StreamController<LogEntry>.broadcast(sync: true);
+
/// The current state of [this].
var _state = _State.COMPUTING_IS_PRIMARY;
@@ -102,10 +108,18 @@
/// [_State.APPLIED].
bool _consumePrimary = false;
+ /// The set of output ids that [transformer] declared it would emit.
+ ///
+ /// This is only non-null if [transformer] is a [DeclaringTransformer] and its
+ /// [declareOutputs] has been run successfully.
+ Set<AssetId> _declaredOutputs;
+
TransformNode(this.phase, Transformer transformer, this.primary,
this._location)
: transformer = transformer,
_isLazy = transformer is LazyTransformer {
+ _onLogPool.add(_onLogController.stream);
+
_primarySubscription = primary.onStateChange.listen((state) {
if (state.isRemoved) {
remove();
@@ -118,26 +132,7 @@
if (_missingInputs.contains(node.id)) _dirty();
});
- syncFuture(() => transformer.isPrimary(primary.id))
- .catchError((error, stackTrace) {
- if (_isRemoved) return false;
-
- // Catch all transformer errors and pipe them to the results stream. This
- // is so a broken transformer doesn't take down the whole graph.
- phase.cascade.reportError(_wrapException(error, stackTrace));
-
- return false;
- }).then((isPrimary) {
- if (_isRemoved) return;
- if (isPrimary) {
- _apply();
- return;
- }
-
- _emitPassThrough();
- _state = _State.NOT_PRIMARY;
- _onDoneController.add(null);
- });
+ _isPrimary();
}
/// The [TransformInfo] describing this node.
@@ -153,6 +148,7 @@
/// from the primary input, but it's possible for a transform to no longer be
/// valid even if its primary input still exists.
void remove() {
+ _onLogController.close();
_onAssetController.close();
_onDoneController.close();
_primarySubscription.cancel();
@@ -179,11 +175,11 @@
///
/// This causes all of the transform's outputs to be marked as dirty as well.
void _dirty() {
- if (_state == _State.COMPUTING_IS_PRIMARY) return;
if (_state == _State.NOT_PRIMARY) {
_emitPassThrough();
return;
}
+ if (_state == _State.COMPUTING_IS_PRIMARY || _isLazy) return;
if (_passThroughController != null) _passThroughController.setDirty();
for (var controller in _outputControllers.values) {
@@ -197,32 +193,87 @@
}
}
+ /// Runs [transformer.isPrimary] and adjusts [this]'s state according to the
+ /// result.
+ ///
+ /// This will also run [_declareOutputs] and/or [_apply] as appropriate.
+ void _isPrimary() {
+ syncFuture(() => transformer.isPrimary(primary.id))
+ .catchError((error, stackTrace) {
+ if (_isRemoved) return false;
+
+ // Catch all transformer errors and pipe them to the results stream. This
+ // is so a broken transformer doesn't take down the whole graph.
+ phase.cascade.reportError(_wrapException(error, stackTrace));
+
+ return false;
+ }).then((isPrimary) {
+ if (_isRemoved) return null;
+ if (isPrimary) {
+ return _declareOutputs().then((_) {
+ if (_isRemoved) return;
+ if (_isLazy) {
+ _state = _State.APPLIED;
+ _onDoneController.add(null);
+ } else {
+ _apply();
+ }
+ });
+ }
+
+ _emitPassThrough();
+ _state = _State.NOT_PRIMARY;
+ _onDoneController.add(null);
+ });
+ }
+
+ /// Runs [transform.declareOutputs] and emits the resulting assets as dirty
+ /// assets.
+ Future _declareOutputs() {
+ if (transformer is! DeclaringTransformer) return new Future.value();
+
+ var controller = new DeclaringTransformController(this);
+ return syncFuture(() {
+ return (transformer as DeclaringTransformer)
+ .declareOutputs(controller.transform);
+ }).then((_) {
+ if (_isRemoved) return;
+ if (controller.loggedError) return;
+
+ _consumePrimary = controller.consumePrimary;
+ _declaredOutputs = controller.outputIds;
+ var invalidIds = _declaredOutputs
+ .where((id) => id.package != phase.cascade.package).toSet();
+ for (var id in invalidIds) {
+ _declaredOutputs.remove(id);
+ // TODO(nweiz): report this as a warning rather than a failing error.
+ phase.cascade.reportError(new InvalidOutputException(info, id));
+ }
+
+ if (!_declaredOutputs.contains(primary.id)) _emitPassThrough();
+
+ for (var id in _declaredOutputs) {
+ var controller = transformer is LazyTransformer
+ ? new AssetNodeController.lazy(id, force, this)
+ : new AssetNodeController(id, this);
+ _outputControllers[id] = controller;
+ _onAssetController.add(controller.node);
+ }
+ }).catchError((error, stackTrace) {
+ if (_isRemoved) return;
+ phase.cascade.reportError(_wrapException(error, stackTrace));
+ });
+ }
+
/// Applies this transform.
void _apply() {
- assert(!_isRemoved);
+ assert(!_isRemoved && !_isLazy);
// Clear input subscriptions here as well as in [_process] because [_apply]
// may be restarted independently if only a secondary input changes.
_clearInputSubscriptions();
_state = _State.APPLYING;
- primary.whenAvailable((_) {
- if (_isRemoved) return null;
- _state = _State.APPLYING;
- // TODO(nweiz): If [transformer] is a [DeclaringTransformer] but not a
- // [LazyTransformer], we can get some mileage out of doing a declaration
- // first so we know how to hook up the assets.
- if (_isLazy) return _declareLazy();
- return _applyImmediate();
- }).catchError((error, stackTrace) {
- // If the transform became dirty while processing, ignore any errors from
- // it.
- if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
-
- // Catch all transformer errors and pipe them to the results stream. This
- // is so a broken transformer doesn't take down the whole graph.
- phase.cascade.reportError(_wrapException(error, stackTrace));
- return true;
- }).then((hadError) {
+ _runApply().then((hadError) {
if (_isRemoved) return;
if (_state == _State.NEEDS_APPLY) {
@@ -233,7 +284,16 @@
assert(_state == _State.APPLYING);
if (hadError) {
_clearOutputs();
- _dontEmitPassThrough();
+ // If the transformer threw an error, we don't want to emit the
+ // pass-through asset in case it will be overwritten by the transformer.
+ // However, if the transformer declared that it wouldn't overwrite or
+ // consume the pass-through asset, we can safely emit it.
+ if (_declaredOutputs != null && !_consumePrimary &&
+ !_declaredOutputs.contains(primary.id)) {
+ _emitPassThrough();
+ } else {
+ _dontEmitPassThrough();
+ }
}
_state = _State.APPLIED;
@@ -262,116 +322,88 @@
});
}
- /// Applies the transform so that it produces concrete (as opposed to lazy)
- /// outputs.
+ /// Run [Transformer.apply] as soon as [primary] is available.
///
- /// Returns whether or not the transformer logged an error.
- Future<bool> _applyImmediate() {
+ /// Returns whether or not an error occurred while running the transformer.
+ Future<bool> _runApply() {
var transformController = new TransformController(this);
_onLogPool.add(transformController.onLog);
- return syncFuture(() {
- return transformer.apply(transformController.transform);
+ return primary.whenAvailable((_) {
+ if (_isRemoved) return null;
+ _state = _State.APPLYING;
+ return syncFuture(() => transformer.apply(transformController.transform));
}).then((_) {
if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
if (transformController.loggedError) return true;
-
- _consumePrimary = transformController.consumePrimary;
-
- var newOutputs = transformController.outputs;
- // Any ids that are for a different package are invalid.
- var invalidIds = newOutputs
- .map((asset) => asset.id)
- .where((id) => id.package != phase.cascade.package)
- .toSet();
- for (var id in invalidIds) {
- newOutputs.removeId(id);
- // TODO(nweiz): report this as a warning rather than a failing error.
- phase.cascade.reportError(new InvalidOutputException(info, id));
- }
-
- // Remove outputs that used to exist but don't anymore.
- for (var id in _outputControllers.keys.toList()) {
- if (newOutputs.containsId(id)) continue;
- _outputControllers.remove(id).setRemoved();
- }
-
- // Emit or stop emitting the pass-through asset between removing and
- // adding outputs to ensure there are no collisions.
- if (!newOutputs.containsId(primary.id)) {
- _emitPassThrough();
- } else {
- _dontEmitPassThrough();
- }
-
- // Store any new outputs or new contents for existing outputs.
- for (var asset in newOutputs) {
- var controller = _outputControllers[asset.id];
- if (controller != null) {
- controller.setAvailable(asset);
- } else {
- var controller = new AssetNodeController.available(asset, this);
- _outputControllers[asset.id] = controller;
- _onAssetController.add(controller.node);
- }
- }
-
+ _handleApplyResults(transformController);
return false;
+ }).catchError((error, stackTrace) {
+ // If the transform became dirty while processing, ignore any errors from
+ // it.
+ if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
+
+ // Catch all transformer errors and pipe them to the results stream. This
+ // is so a broken transformer doesn't take down the whole graph.
+ phase.cascade.reportError(_wrapException(error, stackTrace));
+ return true;
});
}
- /// Applies the transform in declarative mode so that it produces lazy
- /// outputs.
+ /// Handle the results of running [Transformer.apply].
///
- /// Returns whether or not the transformer logged an error.
- Future<bool> _declareLazy() {
- var transformController = new DeclaringTransformController(this);
+ /// [transformController] should be the controller for the [Transform] passed
+ /// to [Transformer.apply].
+ void _handleApplyResults(TransformController transformController) {
+ _consumePrimary = transformController.consumePrimary;
- return syncFuture(() {
- return (transformer as LazyTransformer)
- .declareOutputs(transformController.transform);
- }).then((_) {
- if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
- if (transformController.loggedError) return true;
+ var newOutputs = transformController.outputs;
+ // Any ids that are for a different package are invalid.
+ var invalidIds = newOutputs
+ .map((asset) => asset.id)
+ .where((id) => id.package != phase.cascade.package)
+ .toSet();
+ for (var id in invalidIds) {
+ newOutputs.removeId(id);
+ // TODO(nweiz): report this as a warning rather than a failing error.
+ phase.cascade.reportError(new InvalidOutputException(info, id));
+ }
- _consumePrimary = transformController.consumePrimary;
-
- var newIds = transformController.outputIds;
- var invalidIds =
- newIds.where((id) => id.package != phase.cascade.package).toSet();
- for (var id in invalidIds) {
- newIds.remove(id);
- // TODO(nweiz): report this as a warning rather than a failing error.
- phase.cascade.reportError(new InvalidOutputException(info, id));
+ if (_declaredOutputs != null) {
+ var missingOutputs = _declaredOutputs.difference(
+ newOutputs.map((asset) => asset.id).toSet());
+ if (missingOutputs.isNotEmpty) {
+ _warn("This transformer didn't emit declared "
+ "${pluralize('output asset', missingOutputs.length)} "
+ "${toSentence(missingOutputs)}.");
}
+ }
- // Remove outputs that used to exist but don't anymore.
- for (var id in _outputControllers.keys.toList()) {
- if (newIds.contains(id)) continue;
- _outputControllers.remove(id).setRemoved();
- }
+ // Remove outputs that used to exist but don't anymore.
+ for (var id in _outputControllers.keys.toList()) {
+ if (newOutputs.containsId(id)) continue;
+ _outputControllers.remove(id).setRemoved();
+ }
- // Emit or stop emitting the pass-through asset between removing and
- // adding outputs to ensure there are no collisions.
- if (!newIds.contains(primary.id)) {
- _emitPassThrough();
+ // Emit or stop emitting the pass-through asset between removing and
+ // adding outputs to ensure there are no collisions.
+ if (!_consumePrimary && !newOutputs.containsId(primary.id)) {
+ _emitPassThrough();
+ } else {
+ _dontEmitPassThrough();
+ }
+
+ // Store any new outputs or new contents for existing outputs.
+ for (var asset in newOutputs) {
+ var controller = _outputControllers[asset.id];
+ if (controller != null) {
+ controller.setAvailable(asset);
} else {
- _dontEmitPassThrough();
+ var controller = new AssetNodeController.available(asset, this);
+ _outputControllers[asset.id] = controller;
+ _onAssetController.add(controller.node);
}
-
- for (var id in newIds) {
- var controller = _outputControllers[id];
- if (controller != null) {
- controller.setLazy(force);
- } else {
- var controller = new AssetNodeController.lazy(id, force, this);
- _outputControllers[id] = controller;
- _onAssetController.add(controller.node);
- }
- }
-
- return false;
- });
+ }
}
/// Cancels all subscriptions to secondary input nodes.
@@ -422,6 +454,12 @@
}
}
+ /// Emit a warning about the transformer on [id].
+ void _warn(String message) {
+ _onLogController.add(
+ new LogEntry(info, primary.id, LogLevel.WARNING, message, null));
+ }
+
String toString() =>
"transform node in $_location for $transformer on $primary";
}
@@ -452,6 +490,10 @@
/// The transform has finished running [Transformer.apply], whether or not it
/// emitted an error.
///
+ /// If the transformer is lazy, the [TransformNode] can also be in this state
+ /// when [Transformer.declareOutputs] has been run but [Transformer.apply] has
+ /// not.
+ ///
/// If an input changes, this will transition to [APPLYING].
static final APPLIED = const _State._("applied");
diff --git a/pkg/barback/test/package_graph/declaring_transformer_test.dart b/pkg/barback/test/package_graph/declaring_transformer_test.dart
new file mode 100644
index 0000000..94aef14
--- /dev/null
+++ b/pkg/barback/test/package_graph/declaring_transformer_test.dart
@@ -0,0 +1,170 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.test.package_graph.declaring_transformer_test;
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/utils.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../utils.dart';
+
+main() {
+ initConfig();
+
+ test("gets a declared output with a different path", () {
+ initGraph(["app|foo.blub"], {"app": [
+ [new DeclaringRewriteTransformer("blub", "blab")]
+ ]});
+ updateSources(["app|foo.blub"]);
+ expectAsset("app|foo.blab", "foo.blab");
+ buildShouldSucceed();
+ });
+
+ test("gets a declared output with the same path", () {
+ initGraph(["app|foo.blub"], {"app": [
+ [new DeclaringRewriteTransformer("blub", "blub")]
+ ]});
+ updateSources(["app|foo.blub"]);
+ expectAsset("app|foo.blub", "foo.blub");
+ buildShouldSucceed();
+ });
+
+ test("gets a passed-through asset", () {
+ initGraph(["app|foo.blub"], {"app": [
+ [new DeclaringRewriteTransformer("blub", "blab")]
+ ]});
+ updateSources(["app|foo.blub"]);
+ expectAsset("app|foo.blub", "foo");
+ buildShouldSucceed();
+ });
+
+ test("doesn't get a consumed asset", () {
+ initGraph(["app|foo.blub"], {"app": [
+ [new DeclaringRewriteTransformer("blub", "blab")..consumePrimary = true]
+ ]});
+ updateSources(["app|foo.blub"]);
+ expectNoAsset("app|foo.blub");
+ buildShouldSucceed();
+ });
+
+ test("gets a passed-through asset before apply is finished", () {
+ var transformer = new DeclaringRewriteTransformer("blub", "blab");
+ initGraph(["app|foo.blub"], {"app": [[transformer]]});
+
+ transformer.pauseApply();
+ updateSources(["app|foo.blub"]);
+ expectAsset("app|foo.blub", "foo");
+
+ transformer.resumeApply();
+ buildShouldSucceed();
+ });
+
+ test("fails to get a consumed asset before apply is finished", () {
+ var transformer = new DeclaringRewriteTransformer("blub", "blab")
+ ..consumePrimary = true;
+ initGraph(["app|foo.blub"], {"app": [[transformer]]});
+
+ transformer.pauseApply();
+ updateSources(["app|foo.blub"]);
+ expectNoAsset("app|foo.blub");
+
+ transformer.resumeApply();
+ buildShouldSucceed();
+ });
+
+ test("waits until apply is finished to get an overwritten asset", () {
+ var transformer = new DeclaringRewriteTransformer("blub", "blub");
+ initGraph(["app|foo.blub"], {"app": [[transformer]]});
+
+ transformer.pauseApply();
+ updateSources(["app|foo.blub"]);
+ expectAssetDoesNotComplete("app|foo.blub");
+
+ transformer.resumeApply();
+ expectAsset("app|foo.blub", "foo.blub");
+ buildShouldSucceed();
+ });
+
+ group("with an error in declareOutputs", () {
+ test("still runs apply", () {
+ initGraph(["app|foo.txt"], {"app": [[
+ new DeclaringBadTransformer("app|out.txt",
+ declareError: true, applyError: false)
+ ]]});
+
+ updateSources(["app|foo.txt"]);
+ expectAsset("app|out.txt", "bad out");
+ expectAsset("app|foo.txt", "foo");
+ buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
+ });
+
+ test("waits for apply to complete before passing through the input even if "
+ "consumePrimary was called", () {
+ var transformer = new DeclaringBadTransformer("app|out.txt",
+ declareError: true, applyError: false)..consumePrimary = true;
+ initGraph(["app|foo.txt"], {"app": [[transformer]]});
+
+ transformer.pauseApply();
+ updateSources(["app|foo.txt"]);
+ expectAssetDoesNotComplete("app|out.txt");
+ expectAssetDoesNotComplete("app|foo.txt");
+
+ transformer.resumeApply();
+ expectAsset("app|out.txt", "bad out");
+ expectNoAsset("app|foo.txt");
+ buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
+ });
+ });
+
+ test("with an error in apply still passes through the input", () {
+ initGraph(["app|foo.txt"], {"app": [[
+ new DeclaringBadTransformer("app|out.txt",
+ declareError: false, applyError: true)
+ ]]});
+
+ updateSources(["app|foo.txt"]);
+ expectNoAsset("app|out.txt");
+ expectAsset("app|foo.txt", "foo");
+ buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
+ });
+
+ test("can emit outputs it didn't declare", () {
+ initGraph(["app|foo.txt"], {"app": [
+ [new DeclareAssetsTransformer([], ["app|out.txt"])]
+ ]});
+
+ updateSources(["app|foo.txt"]);
+ // There's probably going to be some time when "out.txt" is unavailable,
+ // since it was undeclared.
+ schedule(pumpEventQueue);
+ expectAsset("app|out.txt", "app|out.txt");
+ buildShouldSucceed();
+ });
+
+ test("can overwrite the primary input even if it declared that it wouldn't",
+ () {
+ var transformer = new DeclareAssetsTransformer([], ["app|foo.txt"]);
+ initGraph(["app|foo.txt"], {"app": [[transformer]]});
+
+ transformer.pauseApply();
+ updateSources(["app|foo.txt"]);
+ expectAsset("app|foo.txt", "foo");
+
+ transformer.resumeApply();
+ schedule(pumpEventQueue);
+ expectAsset("app|foo.txt", "app|foo.txt");
+ buildShouldSucceed();
+ });
+
+ test("can declare outputs it doesn't emit", () {
+ initGraph(["app|foo.txt"], {"app": [
+ [new DeclareAssetsTransformer(["app|out.txt"], [])]
+ ]});
+
+ updateSources(["app|foo.txt"]);
+ expectNoAsset("app|out.txt");
+ buildShouldSucceed();
+ });
+}
\ No newline at end of file
diff --git a/pkg/barback/test/package_graph/lazy_transformer_test.dart b/pkg/barback/test/package_graph/lazy_transformer_test.dart
index df249b3..2f08772 100644
--- a/pkg/barback/test/package_graph/lazy_transformer_test.dart
+++ b/pkg/barback/test/package_graph/lazy_transformer_test.dart
@@ -82,9 +82,6 @@
expect(transformer.numRuns, completion(equals(1)));
});
- // TODO(nweiz): enable these once DeclaringTransformers forward laziness
- // properly (issue 16442).
- //
// test("a lazy asset piped into a declaring transformer isn't eagerly "
// "compiled", () {
// var transformer1 = new LazyRewriteTransformer("blub", "blab");
@@ -229,4 +226,27 @@
expectAllAssets(["app|foo.txt"]);
buildShouldSucceed();
});
+
+ // Regression test.
+ test("a lazy transformer that doesn't apply updates its passed-through asset",
+ () {
+ initGraph(["app|foo.txt"], {"app": [
+ [new LazyRewriteTransformer("blub", "blab")]
+ ]});
+
+ // Pause the provider so that the transformer will start forwarding the
+ // asset while it's dirty.
+ pauseProvider();
+ updateSources(["app|foo.txt"]);
+ expectAssetDoesNotComplete("app|foo.txt");
+
+ resumeProvider();
+ expectAsset("app|foo.txt", "foo");
+ buildShouldSucceed();
+
+ modifyAsset("app|foo.txt", "bar");
+ updateSources(["app|foo.txt"]);
+ expectAsset("app|foo.txt", "bar");
+ buildShouldSucceed();
+ });
}
diff --git a/pkg/barback/test/transformer/declare_assets.dart b/pkg/barback/test/transformer/declare_assets.dart
new file mode 100644
index 0000000..9a14525
--- /dev/null
+++ b/pkg/barback/test/transformer/declare_assets.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.test.transformer.declare_asset;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/utils.dart';
+
+import 'mock.dart';
+
+/// A transformer that declares some outputs and emits others.
+class DeclareAssetsTransformer extends MockTransformer
+ implements DeclaringTransformer {
+ /// The assets that the transformer declares that it will emit.
+ final List<AssetId> declared;
+
+ /// The assets that the transformer actually emits.
+ ///
+ /// These assets' contents will be identical to their ids.
+ final List<AssetId> emitted;
+
+ DeclareAssetsTransformer(Iterable<String> declared, Iterable<String> emitted)
+ : this.declared = declared.map((id) => new AssetId.parse(id)).toList(),
+ this.emitted = emitted.map((id) => new AssetId.parse(id)).toList();
+
+ Future<bool> doIsPrimary(AssetId id) => new Future.value(true);
+
+ Future doApply(Transform transform) {
+ return newFuture(() {
+ for (var id in emitted) {
+ transform.addOutput(new Asset.fromString(id, id.toString()));
+ }
+ });
+ }
+
+ Future declareOutputs(DeclaringTransform transform) {
+ return newFuture(() {
+ declared.forEach(transform.declareOutput);
+ });
+ }
+}
diff --git a/pkg/barback/test/transformer/declaring_bad.dart b/pkg/barback/test/transformer/declaring_bad.dart
new file mode 100644
index 0000000..41804ce
--- /dev/null
+++ b/pkg/barback/test/transformer/declaring_bad.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.test.transformer.declaring_bad;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/utils.dart';
+
+import 'bad.dart';
+import 'mock.dart';
+
+/// A transformer that throws an exception when run, after generating the
+/// given outputs.
+class DeclaringBadTransformer extends MockTransformer
+ implements DeclaringTransformer {
+ /// Whether this should throw an error in [declareOutputs].
+ final bool declareError;
+
+ /// Whether this should throw an error in [apply].
+ final bool applyError;
+
+ /// The id of the output asset to emit.
+ final AssetId output;
+
+ DeclaringBadTransformer(String output, {bool declareError: true,
+ bool applyError: false})
+ : this.output = new AssetId.parse(output),
+ this.declareError = declareError,
+ this.applyError = applyError;
+
+ Future<bool> doIsPrimary(AssetId id) => new Future.value(true);
+
+ Future doApply(Transform transform) {
+ return newFuture(() {
+ transform.addOutput(new Asset.fromString(output, "bad out"));
+ if (applyError) throw BadTransformer.ERROR;
+ });
+ }
+
+ Future declareOutputs(DeclaringTransform transform) {
+ return newFuture(() {
+ if (consumePrimary) transform.consumePrimary();
+ transform.declareOutput(output);
+ if (declareError) throw BadTransformer.ERROR;
+ });
+ }
+}
diff --git a/pkg/barback/test/transformer/declaring_rewrite.dart b/pkg/barback/test/transformer/declaring_rewrite.dart
new file mode 100644
index 0000000..063ebbe
--- /dev/null
+++ b/pkg/barback/test/transformer/declaring_rewrite.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.test.transformer.declaring_rewrite;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+
+import 'rewrite.dart';
+
+/// Like [RewriteTransformer], but declares its assets ahead of time.
+class DeclaringRewriteTransformer extends RewriteTransformer
+ implements LazyTransformer {
+ DeclaringRewriteTransformer(String from, String to)
+ : super(from, to);
+
+ Future declareOutputs(DeclaringTransform transform) {
+ if (consumePrimary) transform.consumePrimary();
+ for (var extension in to.split(" ")) {
+ var id = transform.primaryId.changeExtension(".$extension");
+ transform.declareOutput(id);
+ }
+ }
+}
diff --git a/pkg/barback/test/transformer/lazy_rewrite.dart b/pkg/barback/test/transformer/lazy_rewrite.dart
index 1a36778..33a92cd 100644
--- a/pkg/barback/test/transformer/lazy_rewrite.dart
+++ b/pkg/barback/test/transformer/lazy_rewrite.dart
@@ -8,20 +8,12 @@
import 'package:barback/barback.dart';
-import 'rewrite.dart';
+import 'declaring_rewrite.dart';
/// Like [RewriteTransformer], but returns a lazy asset that doesn't perform the
/// rewrite until it's materialized.
-class LazyRewriteTransformer extends RewriteTransformer
+class LazyRewriteTransformer extends DeclaringRewriteTransformer
implements LazyTransformer {
LazyRewriteTransformer(String from, String to)
: super(from, to);
-
- Future declareOutputs(DeclaringTransform transform) {
- if (consumePrimary) transform.consumePrimary();
- for (var extension in to.split(" ")) {
- var id = transform.primaryId.changeExtension(".$extension");
- transform.declareOutput(id);
- }
- }
}
diff --git a/pkg/barback/test/utils.dart b/pkg/barback/test/utils.dart
index 7a77f1b..66c6abf 100644
--- a/pkg/barback/test/utils.dart
+++ b/pkg/barback/test/utils.dart
@@ -23,6 +23,9 @@
export 'transformer/check_content_and_rename.dart';
export 'transformer/conditionally_consume_primary.dart';
export 'transformer/create_asset.dart';
+export 'transformer/declare_assets.dart';
+export 'transformer/declaring_bad.dart';
+export 'transformer/declaring_rewrite.dart';
export 'transformer/emit_nothing.dart';
export 'transformer/has_input.dart';
export 'transformer/lazy_bad.dart';
diff --git a/pkg/mock/pubspec.yaml b/pkg/mock/pubspec.yaml
index 877f56d..33acbdb 100644
--- a/pkg/mock/pubspec.yaml
+++ b/pkg/mock/pubspec.yaml
@@ -1,5 +1,5 @@
name: mock
-version: 0.10.0
+version: 0.10.0+1
author: Dart Team <misc@dartlang.org>
description: A library for mocking classes
homepage: http://www.dartlang.org
diff --git a/pkg/mock/test/mock_stepwise_negative_test.dart b/pkg/mock/test/mock_stepwise_negative_test.dart
index a9fe2b4..769e972 100644
--- a/pkg/mock/test/mock_stepwise_negative_test.dart
+++ b/pkg/mock/test/mock_stepwise_negative_test.dart
@@ -5,7 +5,7 @@
library mock.mock_stepwise_negative_test;
import 'package:unittest/unittest.dart' show test;
-import 'package:unittest/mock.dart';
+import 'package:mock/mock.dart';
main() {
test('Mocking: stepwiseValidate', () {
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 9cf80d5..b0bd22e 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -59,7 +59,6 @@
collection/test/equality_test/05: Fail # Issue 1533
collection/test/equality_test/none: Pass, Fail # Issue 14348
docgen/test/multi_library_test: Slow, Pass # issue 17060
-shelf/test/message_test: RuntimeError # Issue 18109
third_party/angular_tests/browser_test: Pass, Slow # Large dart2js compile time
typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
@@ -73,6 +72,7 @@
[ $runtime == jsshell ]
analyzer/test/generated/element_test: Pass, Slow # Issue 16473
+docgen/test/typedef_test: Slow, Pass # issue 17060
[ $runtime == d8 || $runtime == jsshell ]
async/test/stream_zip_test: RuntimeError, OK # Timers are not supported.
@@ -191,7 +191,7 @@
[ $compiler == dart2js && $browser ]
stack_trace/test/vm_test: Fail, OK # VM-specific traces
-stack_trace/test/chain_test: Fail # Issues 15171 and 15105
+stack_trace/test/chain_test: Fail, Timeout # Issues 15171, 15105, and 18142
crypto/test/sha256_test: Slow, Pass
crypto/test/sha1_test: Slow, Pass
polymer/example/component: Fail # Issue 13198
@@ -341,8 +341,6 @@
[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
matcher/test/matchers_test: StaticWarning, OK # testing error creating abstract class
-scheduled_test/test/scheduled_test/on_complete_test: StaticWarning # Issue 18113
-scheduled_test/test/scheduled_test/set_up_test: StaticWarning # Issue 18113
[ $runtime == vm && ($system == windows || $system == macos) ]
watcher/test/*/linux_test: Skip
diff --git a/pkg/polymer/lib/polymer.dart b/pkg/polymer/lib/polymer.dart
index 39f5779..66428bd 100644
--- a/pkg/polymer/lib/polymer.dart
+++ b/pkg/polymer/lib/polymer.dart
@@ -69,7 +69,6 @@
import 'package:logging/logging.dart' show Logger, Level;
import 'package:observe/observe.dart';
-import 'package:observe/src/dirty_check.dart' show dirtyCheckZone;
import 'package:path/path.dart' as path;
import 'package:polymer_expressions/polymer_expressions.dart'
show PolymerExpressions;
diff --git a/pkg/polymer/lib/src/build/common.dart b/pkg/polymer/lib/src/build/common.dart
index 26e6a26..e25a8a0 100644
--- a/pkg/polymer/lib/src/build/common.dart
+++ b/pkg/polymer/lib/src/build/common.dart
@@ -6,7 +6,6 @@
library polymer.src.build.common;
import 'dart:async';
-import 'dart:math' show min, max;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/error.dart';
diff --git a/pkg/polymer/lib/src/build/script_compactor.dart b/pkg/polymer/lib/src/build/script_compactor.dart
index bf8a51d..4690889 100644
--- a/pkg/polymer/lib/src/build/script_compactor.dart
+++ b/pkg/polymer/lib/src/build/script_compactor.dart
@@ -15,7 +15,6 @@
import 'package:analyzer/src/generated/element.dart' hide Element;
import 'package:analyzer/src/generated/element.dart' as analyzer show Element;
import 'package:barback/barback.dart';
-import 'package:code_transformers/assets.dart';
import 'package:path/path.dart' as path;
import 'package:source_maps/span.dart' show SourceFile;
import 'package:smoke/codegen/generator.dart';
@@ -571,7 +570,7 @@
}
}
-/// Holds types that are used in queries
+/// Holds types that are used in queries
class _ResolvedTypes {
/// Element representing `HtmlElement`.
final ClassElement htmlElementElement;
diff --git a/pkg/polymer/test/bind_test.dart b/pkg/polymer/test/bind_test.dart
index 0b3c6eb..512575a 100644
--- a/pkg/polymer/test/bind_test.dart
+++ b/pkg/polymer/test/bind_test.dart
@@ -7,7 +7,6 @@
import 'package:polymer/polymer.dart';
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
@CustomTag('x-bar')
class XBar extends PolymerElement {
diff --git a/pkg/polymer/test/entered_view_test.dart b/pkg/polymer/test/entered_view_test.dart
index afd6b2d..f1859ad 100644
--- a/pkg/polymer/test/entered_view_test.dart
+++ b/pkg/polymer/test/entered_view_test.dart
@@ -9,7 +9,6 @@
import 'package:polymer/polymer.dart';
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
@reflectable
class XOuter extends PolymerElement {
diff --git a/pkg/polymer/test/event_handlers_test.dart b/pkg/polymer/test/event_handlers_test.dart
index 0cbcfa0..567cea5 100644
--- a/pkg/polymer/test/event_handlers_test.dart
+++ b/pkg/polymer/test/event_handlers_test.dart
@@ -7,7 +7,6 @@
import 'dart:async';
import 'dart:html';
-import 'package:logging/logging.dart';
import 'package:polymer/polymer.dart';
import 'package:template_binding/template_binding.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/test/mirror_loader_1.dart b/pkg/polymer/test/mirror_loader_1.dart
index 4fbe74a..4c2f9f4 100644
--- a/pkg/polymer/test/mirror_loader_1.dart
+++ b/pkg/polymer/test/mirror_loader_1.dart
@@ -1,6 +1,5 @@
library mirror_loader_test1;
-import 'dart:html';
import 'package:polymer/polymer.dart';
@CustomTag('x-a')
diff --git a/pkg/polymer/test/mirror_loader_2.dart b/pkg/polymer/test/mirror_loader_2.dart
index d148571..4340245 100644
--- a/pkg/polymer/test/mirror_loader_2.dart
+++ b/pkg/polymer/test/mirror_loader_2.dart
@@ -1,6 +1,5 @@
library mirror_loader_test2;
-import 'dart:html';
import 'package:polymer/polymer.dart';
@CustomTag('x-a')
diff --git a/pkg/polymer/test/mirror_loader_3.dart b/pkg/polymer/test/mirror_loader_3.dart
index 1f3e511..96a449a 100644
--- a/pkg/polymer/test/mirror_loader_3.dart
+++ b/pkg/polymer/test/mirror_loader_3.dart
@@ -1,7 +1,5 @@
library mirror_loader_test3;
-import 'dart:html';
-
import 'package:polymer/polymer.dart';
@CustomTag('x-b')
diff --git a/pkg/polymer/test/mirror_loader_4.dart b/pkg/polymer/test/mirror_loader_4.dart
index 7d882af..11aa763 100644
--- a/pkg/polymer/test/mirror_loader_4.dart
+++ b/pkg/polymer/test/mirror_loader_4.dart
@@ -1,6 +1,5 @@
library mirror_loader_test4;
-import 'dart:html';
import 'package:polymer/polymer.dart';
@CustomTag('x-a')
diff --git a/pkg/polymer/test/mirror_loader_test.dart b/pkg/polymer/test/mirror_loader_test.dart
index 0de5500..dd34fe5 100644
--- a/pkg/polymer/test/mirror_loader_test.dart
+++ b/pkg/polymer/test/mirror_loader_test.dart
@@ -3,13 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'dart:html';
import 'dart:mirrors';
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
-import 'package:path/path.dart' show url;
import 'package:polymer/src/mirror_loader.dart';
import 'mirror_loader_1.dart' as m1;
diff --git a/pkg/polymer/test/nested_binding_test.dart b/pkg/polymer/test/nested_binding_test.dart
index 7cc8858..cdc3614 100644
--- a/pkg/polymer/test/nested_binding_test.dart
+++ b/pkg/polymer/test/nested_binding_test.dart
@@ -9,7 +9,6 @@
import 'package:polymer/polymer.dart';
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
@CustomTag('my-test')
class MyTest extends PolymerElement {
diff --git a/pkg/polymer/test/property_change_test.dart b/pkg/polymer/test/property_change_test.dart
index 621be39..392db92 100644
--- a/pkg/polymer/test/property_change_test.dart
+++ b/pkg/polymer/test/property_change_test.dart
@@ -8,7 +8,6 @@
import 'package:polymer/polymer.dart';
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
// Dart note: this is a tad different from the JS code. We don't support putting
// expandos on Dart objects and then observing them. On the other hand, we want
diff --git a/pkg/polymer/test/property_observe_test.dart b/pkg/polymer/test/property_observe_test.dart
index 6fe6a2b..f820e4d 100644
--- a/pkg/polymer/test/property_observe_test.dart
+++ b/pkg/polymer/test/property_observe_test.dart
@@ -9,7 +9,6 @@
import 'package:polymer/polymer.dart';
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
var _changes = 0;
final _done = new Completer();
diff --git a/pkg/polymer_expressions/test/bindings_test.dart b/pkg/polymer_expressions/test/bindings_test.dart
index d5e1063..957b358 100644
--- a/pkg/polymer_expressions/test/bindings_test.dart
+++ b/pkg/polymer_expressions/test/bindings_test.dart
@@ -84,7 +84,7 @@
return new Future(() {
var el = testDiv.query("#i1");
- var subscription = el.onInput.listen(expectAsync1((_) {}, count: 1));
+ var subscription = el.onInput.listen(expectAsync((_) {}, count: 1));
el.focus();
expect(el.value, 'abcde');
diff --git a/pkg/polymer_expressions/test/syntax_test.dart b/pkg/polymer_expressions/test/syntax_test.dart
index 618f999..5d15e17 100644
--- a/pkg/polymer_expressions/test/syntax_test.dart
+++ b/pkg/polymer_expressions/test/syntax_test.dart
@@ -33,11 +33,11 @@
<input id="input" value="{{ firstName }}">
</template>'''));
var person = new Person('John', 'Messerly', ['A', 'B', 'C']);
- templateBind(query('#test'))
+ templateBind(querySelector('#test'))
..bindingDelegate = new PolymerExpressions()
..model = person;
return new Future(() {}).then((_) {
- InputElement input = query('#input');
+ InputElement input = querySelector('#input');
expect(input.value, 'John');
input.focus();
input.value = 'Justin';
@@ -55,7 +55,7 @@
{{ item }}
</template>
</template>'''));
- templateBind(query('#test')).bindingDelegate =
+ templateBind(querySelector('#test')).bindingDelegate =
new PolymerExpressions(globals: {'items': null});
// the template should be the only node
expect(testDiv.nodes.length, 1);
@@ -67,7 +67,7 @@
runZoned(() {
testDiv.nodes.add(new Element.html('''
<template id="test" bind>{{ foo }}</template>'''));
- templateBind(query('#test'))
+ templateBind(querySelector('#test'))
..bindingDelegate = new PolymerExpressions()
..model = [];
return new Future(() {});
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index bba4687..720f260 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -222,7 +222,7 @@
///
/// If [body] returns a [Future], that future will automatically be wrapped with
/// [wrapFuture].
-void test(String description, Future body()) =>
+void test(String description, body()) =>
_test(description, body, unittest.test);
/// Creates a new test case with the given description and body that will be the
@@ -232,10 +232,10 @@
///
/// If [body] returns a [Future], that future will automatically be wrapped with
/// [wrapFuture].
-void solo_test(String description, Future body()) =>
+void solo_test(String description, body()) =>
_test(description, body, unittest.solo_test);
-void _test(String description, Future body(), Function testFn) {
+void _test(String description, body(), Function testFn) {
maybeWrapFuture(future, description) {
if (future != null) wrapFuture(future, description);
}
@@ -245,8 +245,13 @@
testFn(description, () {
var completer = new Completer();
+ // Capture this in a local variable in case we capture an out-of-band error
+ // after the schedule completes.
+ var errorHandler;
+
Chain.capture(() {
_currentSchedule = new Schedule();
+ errorHandler = _currentSchedule.signalError;
return currentSchedule.run(() {
if (_setUpFn != null) maybeWrapFuture(_setUpFn(), "set up");
maybeWrapFuture(body(), "test body");
@@ -259,7 +264,7 @@
unittest.registerException(error, new Chain.forTrace(stackTrace));
}
}).then(completer.complete);
- }, onError: (error, chain) => currentSchedule.signalError(error, chain));
+ }, onError: (error, stackTrace) => errorHandler(error, stackTrace));
return completer.future;
});
@@ -309,7 +314,7 @@
/// be scheduled for [currentSchedule.onComplete] or
/// [currentSchedule.onException]. These tasks will be run after each test's
/// schedule is completed.
-void setUp(void setUpFn()) {
+void setUp(setUpFn()) {
_setUpScheduledTest(setUpFn);
}
diff --git a/pkg/scheduled_test/pubspec.yaml b/pkg/scheduled_test/pubspec.yaml
index 4e0bc56..12316a9 100644
--- a/pkg/scheduled_test/pubspec.yaml
+++ b/pkg/scheduled_test/pubspec.yaml
@@ -1,6 +1,6 @@
name: scheduled_test
-version: 0.11.0-dev
-author: "Dart Team <misc@dartlang.org>"
+version: 0.11.0
+author: Dart Team <misc@dartlang.org>
homepage: http://www.dartlang.org
description: >
A package for writing readable tests of asynchronous behavior.
@@ -10,10 +10,10 @@
read like synchronous, linear code, despite executing asynchronously.
dependencies:
- http: ">=0.9.0 <0.11.0"
- path: ">=0.9.0 <2.0.0"
- stack_trace: ">=0.9.1 <0.10.0"
- unittest: ">=0.9.0 <0.11.0"
- shelf: ">=0.4.0 <0.5.0"
+ http: '>=0.9.0 <0.11.0'
+ path: '>=0.9.0 <2.0.0'
+ shelf: '>=0.4.0 <0.5.0'
+ stack_trace: '>=0.9.1 <0.10.0'
+ unittest: '>=0.9.0 <0.11.0'
environment:
- sdk: ">=0.8.10+6 <2.0.0"
\ No newline at end of file
+ sdk: '>=0.8.10+6 <2.0.0'
diff --git a/pkg/scheduled_test/test/metatest.dart b/pkg/scheduled_test/test/metatest.dart
index 13c5a1d..7550a20 100644
--- a/pkg/scheduled_test/test/metatest.dart
+++ b/pkg/scheduled_test/test/metatest.dart
@@ -52,6 +52,38 @@
});
}
+/// Declares a test with the given [description] and [body].
+///
+/// [body] corresponds
+/// to the `main` method of a test file, and will be run in an isolate.
+///
+/// All tests must have an expected result in [expectedResults].
+void expectTests(String description, void body(),
+ Map<String, String> expectedResults) {
+ _setUpTest(description, body, (results) {
+ expectedResults = new Map.from(expectedResults);
+
+ for (var testResult in results['results']) {
+ var description = testResult['description'];
+
+ expect(expectedResults, contains(description),
+ reason: '"$description" did not have an expected result set.\n'
+ '${_summarizeTests(results)}');
+
+ var result = testResult['result'];
+
+ expect(expectedResults, containsPair(description, result),
+ reason: 'The test "$description" not not have the expected result.\n'
+ '${_summarizeTests(results)}');
+
+ expectedResults.remove(description);
+ }
+ expect(expectedResults, isEmpty,
+ reason: 'Unexpected additional test results\n'
+ '${_summarizeTests(results)}');
+ });
+}
+
/// Declares a test with the given [description] and [body]. [body] corresponds
/// to the `main` method of a test file, and will be run in an isolate. Expects
/// all tests defined by [body] to fail.
diff --git a/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart b/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
index 048745d..d5c7370 100644
--- a/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
@@ -13,6 +13,17 @@
setUpTimeout();
+ expectTests('a scheduled test with an out-of-band error should fail', () {
+ mock_clock.mock().run();
+ test('test 1', () {
+ sleep(1).then((_) => throw 'error');
+ });
+
+ test('test 2', () {
+ return sleep(2);
+ });
+ }, {'test 1': ERROR, 'test 2': PASS});
+
expectTestsPass('currentSchedule.errors contains the error in the onComplete '
'queue', () {
var errors;
diff --git a/pkg/stack_trace/CHANGELOG.md b/pkg/stack_trace/CHANGELOG.md
index 5e2f2c7..0b45208 100644
--- a/pkg/stack_trace/CHANGELOG.md
+++ b/pkg/stack_trace/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.9.3+1
+
+* If an error is thrown in `Chain.capture`'s `onError` handler, that error is
+ handled by the parent zone. This matches the behavior of `runZoned` in
+ `dart:async`.
+
## 0.9.3
* Add a `Chain.foldFrames` method that parallels `Trace.foldFrames`.
diff --git a/pkg/stack_trace/lib/src/stack_zone_specification.dart b/pkg/stack_trace/lib/src/stack_zone_specification.dart
index 36e0717..9a4f7c0 100644
--- a/pkg/stack_trace/lib/src/stack_zone_specification.dart
+++ b/pkg/stack_trace/lib/src/stack_zone_specification.dart
@@ -145,10 +145,21 @@
/// [_onError] or [parent]'s error handler.
handleUncaughtError(Zone self, ZoneDelegate parent, Zone zone, error,
StackTrace stackTrace) {
+ var stackChain = chainFor(stackTrace);
if (_onError == null) {
- return parent.handleUncaughtError(zone, error, chainFor(stackTrace));
- } else {
- _onError(error, chainFor(stackTrace));
+ return parent.handleUncaughtError(zone, error, stackChain);
+ }
+
+ // TODO(nweiz): Currently this copies a lot of logic from [runZoned]. Just
+ // allow [runBinary] to throw instead once issue 18134 is fixed.
+ try {
+ return parent.runBinary(zone, _onError, error, stackChain);
+ } catch (newError, newStackTrace) {
+ if (identical(newError, error)) {
+ return parent.handleUncaughtError(zone, error, stackChain);
+ } else {
+ return parent.handleUncaughtError(zone, newError, newStackTrace);
+ }
}
}
diff --git a/pkg/stack_trace/pubspec.yaml b/pkg/stack_trace/pubspec.yaml
index 99abed7..d0cc30f 100644
--- a/pkg/stack_trace/pubspec.yaml
+++ b/pkg/stack_trace/pubspec.yaml
@@ -1,5 +1,5 @@
name: stack_trace
-version: 0.9.3
+version: 0.9.3+1
author: "Dart Team <misc@dartlang.org>"
homepage: http://www.dartlang.org
description: >
diff --git a/pkg/stack_trace/test/chain_test.dart b/pkg/stack_trace/test/chain_test.dart
index d9915eb..683544f 100644
--- a/pkg/stack_trace/test/chain_test.dart
+++ b/pkg/stack_trace/test/chain_test.dart
@@ -107,6 +107,29 @@
return completer.future;
});
+
+ test('and relays them to the parent zone', () {
+ var completer = new Completer();
+
+ runZoned(() {
+ Chain.capture(() {
+ inMicrotask(() => throw 'error');
+ }, onError: (error, chain) {
+ expect(error, equals('error'));
+ expect(chain.traces[1].frames,
+ contains(frameMember(startsWith('inMicrotask'))));
+ throw error;
+ });
+ }, onError: (error, chain) {
+ expect(error, equals('error'));
+ expect(chain, new isInstanceOf<Chain>());
+ expect(chain.traces[1].frames,
+ contains(frameMember(startsWith('inMicrotask'))));
+ completer.complete();
+ });
+
+ return completer.future;
+ });
});
test('capture() without onError passes exceptions to parent zone', () {
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index bb6461e..a68b7e5 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -160,7 +160,6 @@
Map<String, String> environment,
bool includeParentEnvironment,
bool runInShell) {
- runInShell = identical(runInShell, true);
if (runInShell) {
arguments = _getShellArguments(path, arguments);
path = _getShellCommand();
@@ -193,22 +192,22 @@
}
_environment = [];
- if (environment == null) {
- environment = {};
- }
- if (environment is !Map) {
- throw new ArgumentError("Environment is not a map: $environment");
- }
- if (identical(true, includeParentEnvironment)) {
- environment = new Map.from(Platform.environment)..addAll(environment);
- }
- environment.forEach((key, value) {
+ var environmentEntryHandler = (key, value) {
if (key is !String || value is !String) {
throw new ArgumentError(
- "Environment key or value is not a string: ($key, $value)");
+ "Environment key or value is not a string: ($key, $value)");
}
_environment.add('$key=$value');
- });
+ };
+ if (environment != null) {
+ if (environment is !Map) {
+ throw new ArgumentError("Environment is not a map: $environment");
+ }
+ environment.forEach(environmentEntryHandler);
+ }
+ if (includeParentEnvironment) {
+ Platform.environment.forEach(environmentEntryHandler);
+ }
// stdin going to process.
_stdin = new _StdSink(new _Socket._writePipe());
@@ -321,6 +320,7 @@
_stderr._stream._nativeSocket,
_exitHandler._nativeSocket,
status);
+ _environment = null; // The environment will not be needed going forward.
if (!success) {
completer.completeError(
new ProcessException(_path,
@@ -376,6 +376,7 @@
_stderr._stream._nativeSocket,
_exitHandler._nativeSocket,
status);
+ _environment = null; // The environment will not be needed going forward.
if (!success) {
throw new ProcessException(_path,
_arguments,
diff --git a/runtime/lib/deferred_load_patch.dart b/runtime/lib/deferred_load_patch.dart
index 2bd0027..800fdef 100644
--- a/runtime/lib/deferred_load_patch.dart
+++ b/runtime/lib/deferred_load_patch.dart
@@ -5,11 +5,11 @@
final Set<String> _loadedLibraries = new Set<String>();
patch class DeferredLibrary {
- /* patch */ Future<bool> load() {
+ /* patch */ Future<Null> load() {
// Dummy implementation that should eventually be replaced by real
// implementation.
Future future =
- new Future<bool>.value(!_loadedLibraries.contains(libraryName));
+ new Future<Null>.value(null);
_loadedLibraries.add(libraryName);
return future;
}
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 8c07d5b..2da262e 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -73,6 +73,136 @@
return fpu_reg_names[reg];
}
+
+static int CountLeadingZeros(uint64_t value, int width) {
+ ASSERT((width == 32) || (width == 64));
+ if (value == 0) {
+ return width;
+ }
+ int count = 0;
+ do {
+ count++;
+ } while (value >>= 1);
+ return width - count;
+}
+
+
+static int CountOneBits(uint64_t value, int width) {
+ // Mask out unused bits to ensure that they are not counted.
+ value &= (0xffffffffffffffffUL >> (64-width));
+
+ value = ((value >> 1) & 0x5555555555555555) + (value & 0x5555555555555555);
+ value = ((value >> 2) & 0x3333333333333333) + (value & 0x3333333333333333);
+ value = ((value >> 4) & 0x0f0f0f0f0f0f0f0f) + (value & 0x0f0f0f0f0f0f0f0f);
+ value = ((value >> 8) & 0x00ff00ff00ff00ff) + (value & 0x00ff00ff00ff00ff);
+ value = ((value >> 16) & 0x0000ffff0000ffff) + (value & 0x0000ffff0000ffff);
+ value = ((value >> 32) & 0x00000000ffffffff) + (value & 0x00000000ffffffff);
+
+ return value;
+}
+
+
+// Test if a given value can be encoded in the immediate field of a logical
+// instruction.
+// If it can be encoded, the function returns true, and values pointed to by n,
+// imm_s and imm_r are updated with immediates encoded in the format required
+// by the corresponding fields in the logical instruction.
+// If it can't be encoded, the function returns false, and the operand is
+// undefined.
+bool Assembler::IsImmLogical(uint64_t value, uint8_t width, Operand* imm_op) {
+ ASSERT(imm_op != NULL);
+ ASSERT((width == kWRegSizeInBits) || (width == kXRegSizeInBits));
+ ASSERT((width == kXRegSizeInBits) || (value <= 0xffffffffUL));
+ uint8_t n = 0;
+ uint8_t imm_s = 0;
+ uint8_t imm_r = 0;
+
+ // Logical immediates are encoded using parameters n, imm_s and imm_r using
+ // the following table:
+ //
+ // N imms immr size S R
+ // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr)
+ // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr)
+ // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr)
+ // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr)
+ // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr)
+ // 0 11110s xxxxxr 2 UInt(s) UInt(r)
+ // (s bits must not be all set)
+ //
+ // A pattern is constructed of size bits, where the least significant S+1
+ // bits are set. The pattern is rotated right by R, and repeated across a
+ // 32 or 64-bit value, depending on destination register width.
+ //
+ // To test if an arbitrary immediate can be encoded using this scheme, an
+ // iterative algorithm is used.
+
+ // 1. If the value has all set or all clear bits, it can't be encoded.
+ if ((value == 0) || (value == 0xffffffffffffffffULL) ||
+ ((width == kWRegSizeInBits) && (value == 0xffffffff))) {
+ return false;
+ }
+
+ int lead_zero = CountLeadingZeros(value, width);
+ int lead_one = CountLeadingZeros(~value, width);
+ int trail_zero = Utils::CountTrailingZeros(value);
+ int trail_one = Utils::CountTrailingZeros(~value);
+ int set_bits = CountOneBits(value, width);
+
+ // The fixed bits in the immediate s field.
+ // If width == 64 (X reg), start at 0xFFFFFF80.
+ // If width == 32 (W reg), start at 0xFFFFFFC0, as the iteration for 64-bit
+ // widths won't be executed.
+ int imm_s_fixed = (width == kXRegSizeInBits) ? -128 : -64;
+ int imm_s_mask = 0x3F;
+
+ for (;;) {
+ // 2. If the value is two bits wide, it can be encoded.
+ if (width == 2) {
+ n = 0;
+ imm_s = 0x3C;
+ imm_r = (value & 3) - 1;
+ *imm_op = Operand(n, imm_s, imm_r);
+ return true;
+ }
+
+ n = (width == 64) ? 1 : 0;
+ imm_s = ((imm_s_fixed | (set_bits - 1)) & imm_s_mask);
+ if ((lead_zero + set_bits) == width) {
+ imm_r = 0;
+ } else {
+ imm_r = (lead_zero > 0) ? (width - trail_zero) : lead_one;
+ }
+
+ // 3. If the sum of leading zeros, trailing zeros and set bits is equal to
+ // the bit width of the value, it can be encoded.
+ if (lead_zero + trail_zero + set_bits == width) {
+ *imm_op = Operand(n, imm_s, imm_r);
+ return true;
+ }
+
+ // 4. If the sum of leading ones, trailing ones and unset bits in the
+ // value is equal to the bit width of the value, it can be encoded.
+ if (lead_one + trail_one + (width - set_bits) == width) {
+ *imm_op = Operand(n, imm_s, imm_r);
+ return true;
+ }
+
+ // 5. If the most-significant half of the bitwise value is equal to the
+ // least-significant half, return to step 2 using the least-significant
+ // half of the value.
+ uint64_t mask = (1UL << (width >> 1)) - 1;
+ if ((value & mask) == ((value >> (width >> 1)) & mask)) {
+ width >>= 1;
+ set_bits >>= 1;
+ imm_s_fixed >>= 1;
+ continue;
+ }
+
+ // 6. Otherwise, the value can't be encoded.
+ return false;
+ }
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_ARM64
diff --git a/runtime/vm/assembler_arm64.h b/runtime/vm/assembler_arm64.h
index cd7bd36..fd9d7cb 100644
--- a/runtime/vm/assembler_arm64.h
+++ b/runtime/vm/assembler_arm64.h
@@ -176,6 +176,12 @@
Operand(const Operand& other)
: ValueObject(), encoding_(other.encoding_), type_(other.type_) { }
+ Operand& operator=(const Operand& other) {
+ type_ = other.type_;
+ encoding_ = other.encoding_;
+ return *this;
+ }
+
explicit Operand(Register rm) {
ASSERT((rm != R31) && (rm != SP));
const Register crm = ConcreteRegister(rm);
@@ -217,8 +223,19 @@
type_ = Immediate;
}
- // TODO(zra): Add bitfield immediate operand
- // Operand(int32_t n, int32_t imms, int32_t immr);
+ // Encodes the value of an immediate for a logical operation.
+ // Since these values are difficult to craft by hand, instead pass the
+ // logical mask to the function Assembler::IsImmLogical to get n, imm_s, and
+ // imm_r.
+ Operand(uint8_t n, int8_t imm_s, int8_t imm_r) {
+ ASSERT((n == 1) || (n == 0));
+ ASSERT(Utils::IsUint(6, imm_s) && Utils::IsUint(6, imm_r));
+ type_ = BitfieldImm;
+ encoding_ =
+ (static_cast<int32_t>(n) << kNShift) |
+ (static_cast<int32_t>(imm_s) << kImmSShift) |
+ (static_cast<int32_t>(imm_r) << kImmRShift);
+ }
enum OperandType {
Shifted,
@@ -326,12 +343,82 @@
void add(Register rd, Register rn, Operand o) {
AddSubHelper(kDoubleWord, false, false, rd, rn, o);
}
+ void adds(Register rd, Register rn, Operand o) {
+ AddSubHelper(kDoubleWord, true, false, rd, rn, o);
+ }
void addw(Register rd, Register rn, Operand o) {
AddSubHelper(kWord, false, false, rd, rn, o);
}
void sub(Register rd, Register rn, Operand o) {
AddSubHelper(kDoubleWord, false, true, rd, rn, o);
}
+ void subs(Register rd, Register rn, Operand o) {
+ AddSubHelper(kDoubleWord, true, true, rd, rn, o);
+ }
+
+ // Logical immediate operations.
+ // TODO(zra): Add macros that check IsImmLogical, and fall back on a longer
+ // sequence on failure.
+ void andi(Register rd, Register rn, uint64_t imm) {
+ Operand imm_op;
+ const bool immok = IsImmLogical(imm, kXRegSizeInBits, &imm_op);
+ ASSERT(immok);
+ EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord);
+ }
+ void orri(Register rd, Register rn, uint64_t imm) {
+ Operand imm_op;
+ const bool immok = IsImmLogical(imm, kXRegSizeInBits, &imm_op);
+ ASSERT(immok);
+ EmitLogicalImmOp(ORRI, rd, rn, imm_op, kDoubleWord);
+ }
+ void eori(Register rd, Register rn, uint64_t imm) {
+ Operand imm_op;
+ const bool immok = IsImmLogical(imm, kXRegSizeInBits, &imm_op);
+ ASSERT(immok);
+ EmitLogicalImmOp(EORI, rd, rn, imm_op, kDoubleWord);
+ }
+ void andis(Register rd, Register rn, uint64_t imm) {
+ Operand imm_op;
+ const bool immok = IsImmLogical(imm, kXRegSizeInBits, &imm_op);
+ ASSERT(immok);
+ EmitLogicalImmOp(ANDIS, rd, rn, imm_op, kDoubleWord);
+ }
+
+ // Logical (shifted) register operations.
+ void and_(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(AND, rd, rn, o, kDoubleWord);
+ }
+ void bic(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(BIC, rd, rn, o, kDoubleWord);
+ }
+ void orr(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(ORR, rd, rn, o, kDoubleWord);
+ }
+ void orn(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(ORN, rd, rn, o, kDoubleWord);
+ }
+ void eor(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(EOR, rd, rn, o, kDoubleWord);
+ }
+ void eon(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(EON, rd, rn, o, kDoubleWord);
+ }
+ void ands(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(ANDS, rd, rn, o, kDoubleWord);
+ }
+ void bics(Register rd, Register rn, Operand o) {
+ EmitLogicalShiftOp(BICS, rd, rn, o, kDoubleWord);
+ }
+
+ // Comparison.
+ // rn cmp o.
+ void cmp(Register rn, Operand o) {
+ subs(ZR, rn, o);
+ }
+ // rn cmp -o.
+ void cmn(Register rn, Operand o) {
+ adds(ZR, rn, o);
+ }
// Move wide immediate.
void movk(Register rd, int32_t imm, int32_t hw_idx) {
@@ -393,6 +480,8 @@
GrowableArray<CodeComment*> comments_;
+ bool IsImmLogical(uint64_t value, uint8_t width, Operand* imm_op);
+
void AddSubHelper(OperandSize os, bool set_flags, bool subtract,
Register rd, Register rn, Operand o) {
ASSERT((rd != R31) && (rn != R31));
@@ -412,9 +501,9 @@
}
void EmitAddSubImmOp(AddSubImmOp op, Register rd, Register rn,
- Operand o, OperandSize os, bool set_flags) {
- ASSERT((os == kDoubleWord) || (os == kWord));
- const int32_t size = (os == kDoubleWord) ? B31 : 0;
+ Operand o, OperandSize sz, bool set_flags) {
+ ASSERT((sz == kDoubleWord) || (sz == kWord));
+ const int32_t size = (sz == kDoubleWord) ? B31 : 0;
const int32_t s = set_flags ? B29 : 0;
const int32_t encoding =
op | size | s |
@@ -424,6 +513,42 @@
Emit(encoding);
}
+ void EmitLogicalImmOp(LogicalImmOp op, Register rd, Register rn,
+ Operand o, OperandSize sz) {
+ ASSERT((sz == kDoubleWord) || (sz == kWord));
+ ASSERT((rd != R31) && (rn != R31));
+ ASSERT(rn != SP);
+ ASSERT((op == ANDIS) || (rd != ZR)); // op != ANDIS => rd != ZR.
+ ASSERT((op != ANDIS) || (rd != SP)); // op == ANDIS => rd != SP.
+ ASSERT(o.type() == Operand::BitfieldImm);
+ const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+ const Register crd = ConcreteRegister(rd);
+ const Register crn = ConcreteRegister(rn);
+ const int32_t encoding =
+ op | size |
+ (static_cast<int32_t>(crd) << kRdShift) |
+ (static_cast<int32_t>(crn) << kRnShift) |
+ o.encoding();
+ Emit(encoding);
+ }
+
+ void EmitLogicalShiftOp(LogicalShiftOp op,
+ Register rd, Register rn, Operand o, OperandSize sz) {
+ ASSERT((sz == kDoubleWord) || (sz == kWord));
+ ASSERT((rd != R31) && (rn != R31));
+ ASSERT((rd != SP) && (rn != SP));
+ ASSERT(o.type() == Operand::Shifted);
+ const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+ const Register crd = ConcreteRegister(rd);
+ const Register crn = ConcreteRegister(rn);
+ const int32_t encoding =
+ op | size |
+ (static_cast<int32_t>(crd) << kRdShift) |
+ (static_cast<int32_t>(crn) << kRnShift) |
+ o.encoding();
+ Emit(encoding);
+ }
+
void EmitAddSubShiftExtOp(AddSubShiftExtOp op,
Register rd, Register rn, Operand o,
OperandSize sz, bool set_flags) {
diff --git a/runtime/vm/assembler_arm64_test.cc b/runtime/vm/assembler_arm64_test.cc
index 6e26fe8..72feb31 100644
--- a/runtime/vm/assembler_arm64_test.cc
+++ b/runtime/vm/assembler_arm64_test.cc
@@ -391,6 +391,170 @@
EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
}
+
+// Logical register operations.
+ASSEMBLER_TEST_GENERATE(AndRegs, assembler) {
+ __ movz(R1, 43, 0);
+ __ movz(R2, 42, 0);
+ __ and_(R0, R1, Operand(R2));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndRegs, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AndShiftRegs, assembler) {
+ __ movz(R1, 42, 0);
+ __ movz(R2, 21, 0);
+ __ and_(R0, R1, Operand(R2, LSL, 1));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndShiftRegs, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(BicRegs, assembler) {
+ __ movz(R1, 42, 0);
+ __ movz(R2, 5, 0);
+ __ bic(R0, R1, Operand(R2));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(BicRegs, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(OrrRegs, assembler) {
+ __ movz(R1, 32, 0);
+ __ movz(R2, 10, 0);
+ __ orr(R0, R1, Operand(R2));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(OrrRegs, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(OrnRegs, assembler) {
+ __ movz(R1, 32, 0);
+ __ movn(R2, 0, 0); // R2 <- 0xffffffffffffffff.
+ __ movk(R2, 0xffd5, 0); // R2 <- 0xffffffffffffffe5.
+ __ orn(R0, R1, Operand(R2));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(OrnRegs, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EorRegs, assembler) {
+ __ movz(R1, 0xffd5, 0);
+ __ movz(R2, 0xffff, 0);
+ __ eor(R0, R1, Operand(R2));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(EorRegs, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EonRegs, assembler) {
+ __ movz(R1, 0xffd5, 0);
+ __ movn(R2, 0xffff, 0);
+ __ eon(R0, R1, Operand(R2));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(EonRegs, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+// TODO(zra): ands and bics after branches are implemented.
+
+
+// Logical immediate operations.
+ASSEMBLER_TEST_GENERATE(AndImm, assembler) {
+ __ movz(R1, 42, 0);
+ __ andi(R0, R1, 0xaaaaaaaaaaaaaaaaULL);
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndImm, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AndOneImm, assembler) {
+ __ movz(R1, 43, 0);
+ __ andi(R0, R1, 1);
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndOneImm, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(1, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(OrrImm, assembler) {
+ __ movz(R1, 0, 0);
+ __ movz(R2, 0x3f, 0);
+ __ movz(R3, 0xa, 0);
+ __ orri(R1, R1, 0x0020002000200020ULL);
+ __ orr(R1, R1, Operand(R3));
+ __ and_(R0, R1, Operand(R2));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(OrrImm, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EorImm, assembler) {
+ __ movn(R0, 0, 0);
+ __ movk(R0, 0xffd5, 0); // R0 < 0xffffffffffffffd5.
+ __ movz(R1, 0x3f, 0);
+ __ eori(R0, R0, 0x3f3f3f3f3f3f3f3fULL);
+ __ and_(R0, R0, Operand(R1));
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(EorImm, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+// TODO(zra): andis after branches are implemented.
+
} // namespace dart
#endif // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 8eee03d..0266e1b 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -60,7 +60,14 @@
DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement.");
DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement.");
-DECLARE_FLAG(charp, deoptimize_filter);
+DEFINE_FLAG(int, stacktrace_every, 0,
+ "Compute debugger stacktrace on every N stack overflow checks");
+DEFINE_FLAG(charp, stacktrace_filter, NULL,
+ "Compute stacktrace in named function on stack overflow checks");
+DEFINE_FLAG(int, deoptimize_every, 0,
+ "Deoptimize on every N stack overflow checks");
+DEFINE_FLAG(charp, deoptimize_filter, NULL,
+ "Deoptimize in named function on stack overflow checks");
DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) {
@@ -1022,9 +1029,14 @@
#else
uword stack_pos = reinterpret_cast<uword>(&arguments);
#endif
+ // Always clear the stack overflow flags. They are meant for this
+ // particular stack overflow runtime call and are not meant to
+ // persist.
+ uword stack_overflow_flags = isolate->GetAndClearStackOverflowFlags();
// If an interrupt happens at the same time as a stack overflow, we
- // process the stack overflow first.
+ // process the stack overflow now and leave the interrupt for next
+ // time.
if (stack_pos < isolate->saved_stack_limit()) {
// Use the preallocated stack overflow exception to avoid calling
// into dart code.
@@ -1035,16 +1047,16 @@
}
uword interrupt_bits = isolate->GetAndClearInterrupts();
- if (interrupt_bits & Isolate::kStoreBufferInterrupt) {
+ if ((interrupt_bits & Isolate::kStoreBufferInterrupt) != 0) {
if (FLAG_verbose_gc) {
OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
}
isolate->heap()->CollectGarbage(Heap::kNew);
}
- if (interrupt_bits & Isolate::kMessageInterrupt) {
+ if ((interrupt_bits & Isolate::kMessageInterrupt) != 0) {
isolate->message_handler()->HandleOOBMessages();
}
- if (interrupt_bits & Isolate::kApiInterrupt) {
+ if ((interrupt_bits & Isolate::kApiInterrupt) != 0) {
// Signal isolate interrupt event.
Debugger::SignalIsolateInterrupted();
@@ -1058,14 +1070,15 @@
}
}
}
- if (interrupt_bits & Isolate::kVmStatusInterrupt) {
+ if ((interrupt_bits & Isolate::kVmStatusInterrupt) != 0) {
Dart_IsolateInterruptCallback callback = isolate->VmStatsCallback();
if (callback) {
(*callback)();
}
}
- if (FLAG_use_osr && (interrupt_bits == 0)) {
+ if ((stack_overflow_flags & Isolate::kOsrRequest) != 0) {
+ ASSERT(FLAG_use_osr);
DartFrameIterator iterator;
StackFrame* frame = iterator.NextFrame();
ASSERT(frame != NULL);
@@ -1112,24 +1125,65 @@
}
}
- if (FLAG_deoptimize_filter != NULL) {
+ // The following code is used to stress test deoptimization and
+ // debugger stack tracing.
+ bool do_deopt = false;
+ bool do_stacktrace = false;
+ if (FLAG_deoptimize_every > 0 ||
+ FLAG_stacktrace_every > 0) {
+ // TODO(turnidge): To make --deoptimize_every and
+ // --stacktrace-every faster we could move this increment/test to
+ // the generated code.
+ int32_t count = isolate->IncrementAndGetStackOverflowCount();
+ if (FLAG_deoptimize_every > 0 &&
+ (count % FLAG_deoptimize_every) == 0) {
+ do_deopt = true;
+ }
+ if (FLAG_stacktrace_every > 0 &&
+ (count % FLAG_stacktrace_every) == 0) {
+ do_stacktrace = true;
+ }
+ }
+ if (FLAG_deoptimize_filter != NULL ||
+ FLAG_stacktrace_filter != NULL) {
DartFrameIterator iterator;
StackFrame* frame = iterator.NextFrame();
ASSERT(frame != NULL);
const Code& code = Code::Handle(frame->LookupDartCode());
ASSERT(!code.IsNull());
- if (code.is_optimized()) {
- const Function& function = Function::Handle(code.function());
- ASSERT(!function.IsNull());
- if (strstr(function.ToFullyQualifiedCString(),
- FLAG_deoptimize_filter) != NULL) {
- if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
- OS::PrintErr("*** Forcing deoptimization (%s)\n",
- function.ToFullyQualifiedCString());
- // TODO(turnidge): Consider changing to DeoptimizeAt for
- // just the top frame.
- DeoptimizeAll();
- }
+ const Function& function = Function::Handle(code.function());
+ ASSERT(!function.IsNull());
+ const char* function_name = function.ToFullyQualifiedCString();
+ ASSERT(function_name != NULL);
+ if (code.is_optimized() &&
+ FLAG_deoptimize_filter != NULL &&
+ strstr(function_name, FLAG_deoptimize_filter) != NULL) {
+ OS::PrintErr("*** Forcing deoptimization (%s)\n",
+ function.ToFullyQualifiedCString());
+ do_deopt = true;
+ }
+ if (FLAG_stacktrace_filter != NULL &&
+ strstr(function_name, FLAG_stacktrace_filter) != NULL) {
+ OS::PrintErr("*** Computing stacktrace (%s)\n",
+ function.ToFullyQualifiedCString());
+ do_stacktrace = true;
+ }
+ }
+ if (do_deopt) {
+ // TODO(turnidge): Consider using DeoptimizeAt instead.
+ DeoptimizeAll();
+ }
+ if (do_stacktrace) {
+ String& var_name = String::Handle();
+ Instance& var_value = Instance::Handle();
+ DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
+ intptr_t num_frames = stack->Length();
+ for (intptr_t i = 0; i < num_frames; i++) {
+ ActivationFrame* frame = stack->FrameAt(i);
+ const int num_vars = frame->NumLocalVariables();
+ intptr_t unused;
+ for (intptr_t v = 0; v < num_vars; v++) {
+ frame->VariableAt(v, &var_name, &unused, &unused, &var_value);
}
}
}
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 2cffb65..308a279 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -299,6 +299,16 @@
SUBI = AddSubImmFixed | B30,
};
+// C3.4.4
+enum LogicalImmOp {
+ LogicalImmMask = 0x1f800000,
+ LogicalImmFixed = DPImmediateFixed | B25,
+ ANDI = LogicalImmFixed,
+ ORRI = LogicalImmFixed | B29,
+ EORI = LogicalImmFixed | B30,
+ ANDIS = LogicalImmFixed | B30 | B29,
+};
+
// C3.4.5
enum MoveWideOp {
MoveWideMask = 0x1f800000,
@@ -308,7 +318,6 @@
MOVK = MoveWideFixed | B30 | B29,
};
-
// C3.5.1
enum AddSubShiftExtOp {
AddSubShiftExtMask = 0x1f000000,
@@ -317,6 +326,19 @@
SUB = AddSubShiftExtFixed | B30,
};
+enum LogicalShiftOp {
+ LogicalShiftMask = 0x1f000000,
+ LogicalShiftFixed = DPRegisterFixed,
+ AND = LogicalShiftFixed,
+ BIC = LogicalShiftFixed | B21,
+ ORR = LogicalShiftFixed | B29,
+ ORN = LogicalShiftFixed | B29 | B21,
+ EOR = LogicalShiftFixed | B30,
+ EON = LogicalShiftFixed | B30 | B21,
+ ANDS = LogicalShiftFixed | B30 | B29,
+ BICS = LogicalShiftFixed | B30 | B29 | B21,
+};
+
#define APPLY_OP_LIST(_V) \
_V(DPImmediate) \
_V(CompareBranch) \
@@ -329,8 +351,10 @@
_V(LoadStoreReg) \
_V(UnconditionalBranchReg) \
_V(AddSubImm) \
+_V(LogicalImm) \
_V(MoveWide) \
_V(AddSubShiftExt) \
+_V(LogicalShift) \
enum Shift {
@@ -402,12 +426,20 @@
kImm16Shift = 5,
kImm16Bits = 16,
+ // Bitfield immediates.
+ kNShift = 22,
+ kNBits = 1,
+ kImmRShift = 16,
+ kImmRBits = 6,
+ kImmSShift = 10,
+ kImmSBits = 6,
+
kHWShift = 21,
kHWBits = 2,
// Shift and Extend.
- kShiftExtendShift = 21,
- kShiftExtendBits = 1,
+ kAddShiftExtendShift = 21,
+ kAddShiftExtendBits = 1,
kShiftTypeShift = 22,
kShiftTypeBits = 2,
kExtendTypeShift = 13,
@@ -426,6 +458,27 @@
const uint32_t kImmExceptionIsPrintf = 0xdeb1;
const uint32_t kImmExceptionIsDebug = 0xdeb0;
+// Helper functions for decoding logical immediates.
+static inline uint64_t RotateRight(
+ uint64_t value, uint8_t rotate, uint8_t width) {
+ ASSERT(width <= 64);
+ rotate &= 63;
+ return ((value & ((1UL << rotate) - 1UL)) << (width - rotate)) |
+ (value >> rotate);
+}
+
+static inline uint64_t RepeatBitsAcrossReg(
+ uint8_t reg_size, uint64_t value, uint8_t width) {
+ ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) ||
+ (width == 32));
+ ASSERT((reg_size == kWRegSizeInBits) || (reg_size == kXRegSizeInBits));
+ uint64_t result = value & ((1UL << width) - 1UL);
+ for (unsigned i = width; i < reg_size; i *= 2) {
+ result |= (result << i);
+ }
+ return result;
+}
+
// The class Instr enables access to individual fields defined in the ARM
// architecture instruction set encoding as described in figure A3-1.
//
@@ -470,7 +523,7 @@
return (InstructionBits() >> shift) & ((1 << count) - 1);
}
-
+ inline int NField() const { return Bit(22); }
inline int SField() const { return Bit(kSShift); }
inline int SFField() const { return Bit(kSFShift); }
inline int SzField() const { return Bits(kSzShift, kSzBits); }
@@ -488,20 +541,29 @@
// Immediates
inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); }
inline int Imm6Field() const { return Bits(kImm6Shift, kImm6Bits); }
+
inline int Imm9Field() const { return Bits(kImm9Shift, kImm9Bits); }
// Sign-extended Imm9Field()
inline int64_t SImm9Field() const {
return (static_cast<int32_t>(Imm9Field()) << 23) >> 23; }
- inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); }
- inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
+ inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); }
inline int Imm12ShiftField() const {
return Bits(kImm12ShiftShift, kImm12ShiftBits); }
+
+ inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
inline int HWField() const { return Bits(kHWShift, kHWBits); }
+ inline int ImmRField() const { return Bits(kImmRShift, kImmRBits); }
+ inline int ImmSField() const { return Bits(kImmSShift, kImmSBits); }
+
// Shift and Extend.
- inline bool IsShift() const { return (Bit(kShiftExtendShift) == 0); }
- inline bool IsExtend() const { return (Bit(kShiftExtendShift) == 1); }
+ inline bool IsShift() const {
+ return IsLogicalShiftOp() || (Bit(kAddShiftExtendShift) == 0);
+ }
+ inline bool IsExtend() const {
+ return !IsLogicalShiftOp() && (Bit(kAddShiftExtendShift) == 1);
+ }
inline Shift ShiftTypeField() const {
return static_cast<Shift>(Bits(kShiftTypeShift, kShiftTypeBits)); }
inline Extend ExtendTypeField() const {
@@ -553,6 +615,59 @@
return R31IsZR;
}
+ // Logical immediates can't encode zero, so a return value of zero is used to
+ // indicate a failure case. Specifically, where the constraints on imm_s are
+ // not met.
+ uint64_t ImmLogical() {
+ const uint8_t reg_size =
+ SFField() == 1 ? kXRegSizeInBits : kWRegSizeInBits;
+ const int64_t n = NField();
+ const int64_t imm_s = ImmSField();
+ const int64_t imm_r = ImmRField();
+
+ // An integer is constructed from the n, imm_s and imm_r bits according to
+ // the following table:
+ //
+ // N imms immr size S R
+ // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr)
+ // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr)
+ // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr)
+ // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr)
+ // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr)
+ // 0 11110s xxxxxr 2 UInt(s) UInt(r)
+ // (s bits must not be all set)
+ //
+ // A pattern is constructed of size bits, where the least significant S+1
+ // bits are set. The pattern is rotated right by R, and repeated across a
+ // 32 or 64-bit value, depending on destination register width.
+
+ if (n == 1) {
+ if (imm_s == 0x3F) {
+ return 0;
+ }
+ uint64_t bits = (1UL << (imm_s + 1)) - 1;
+ return RotateRight(bits, imm_r, 64);
+ } else {
+ if ((imm_s >> 1) == 0x1F) {
+ return 0;
+ }
+ for (int width = 0x20; width >= 0x2; width >>= 1) {
+ if ((imm_s & width) == 0) {
+ int mask = width - 1;
+ if ((imm_s & mask) == mask) {
+ return 0;
+ }
+ uint64_t bits = (1UL << ((imm_s & mask) + 1)) - 1;
+ return RepeatBitsAcrossReg(reg_size,
+ RotateRight(bits, imm_r & mask, width),
+ width);
+ }
+ }
+ }
+ UNREACHABLE();
+ return 0;
+ }
+
// Instructions are read out of a code stream. The only way to get a
// reference to an instruction is to convert a pointer. There is no way
// to allocate or create instances of class Instr.
diff --git a/runtime/vm/disassembler_arm64.cc b/runtime/vm/disassembler_arm64.cc
index 4859b69..2e453d1 100644
--- a/runtime/vm/disassembler_arm64.cc
+++ b/runtime/vm/disassembler_arm64.cc
@@ -347,6 +347,15 @@
PrintMemOperand(instr);
return 5;
}
+ case 'b': {
+ ASSERT(STRING_STARTS_WITH(format, "bitimm"));
+ const uint64_t imm = instr->ImmLogical();
+ buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+ remaining_size_in_buffer(),
+ "0x%"Px64,
+ imm);
+ return 6;
+ }
default: {
UNREACHABLE();
break;
@@ -414,11 +423,43 @@
void ARM64Decoder::DecodeAddSubImm(Instr* instr) {
switch (instr->Bit(30)) {
+ case 0: {
+ if ((instr->RdField() == R31) && (instr->SFField())) {
+ Format(instr, "cmni'sf 'rn, 'imm12s");
+ } else {
+ Format(instr, "addi'sf's 'rd, 'rn, 'imm12s");
+ }
+ break;
+ }
+ case 1: {
+ if ((instr->RdField() == R31) && (instr->SFField())) {
+ Format(instr, "cmpi'sf 'rn, 'imm12s");
+ } else {
+ Format(instr, "subi'sf's 'rd, 'rn, 'imm12s");
+ }
+ break;
+ }
+ default:
+ Unknown(instr);
+ break;
+ }
+}
+
+
+void ARM64Decoder::DecodeLogicalImm(Instr* instr) {
+ int op = instr->Bits(29, 2);
+ switch (op) {
case 0:
- Format(instr, "addi'sf's 'rd, 'rn, 'imm12s");
+ Format(instr, "andi'sf 'rd, 'rn, 'bitimm");
break;
case 1:
- Format(instr, "subi'sf's 'rd, 'rn, 'imm12s");
+ Format(instr, "orri'sf 'rd, 'rn, 'bitimm");
+ break;
+ case 2:
+ Format(instr, "eori'sf 'rd, 'rn, 'bitimm");
+ break;
+ case 3:
+ Format(instr, "andi'sfs 'rd, 'rn, 'bitimm");
break;
default:
Unknown(instr);
@@ -426,11 +467,14 @@
}
}
+
void ARM64Decoder::DecodeDPImmediate(Instr* instr) {
if (instr->IsMoveWideOp()) {
DecodeMoveWide(instr);
} else if (instr->IsAddSubImmOp()) {
DecodeAddSubImm(instr);
+ } else if (instr->IsLogicalImmOp()) {
+ DecodeLogicalImm(instr);
} else {
Unknown(instr);
}
@@ -511,11 +555,55 @@
void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) {
switch (instr->Bit(30)) {
+ case 0: {
+ if ((instr->RdField() == R31) && (instr->SFField())) {
+ Format(instr, "cmn'sf 'rn, 'shift_op");
+ } else {
+ Format(instr, "add'sf's 'rd, 'rn, 'shift_op");
+ }
+ break;
+ }
+ case 1: {
+ if ((instr->RdField() == R31) && (instr->SFField())) {
+ Format(instr, "cmp'sf 'rn, 'shift_op");
+ } else {
+ Format(instr, "sub'sf's 'rd, 'rn, 'shift_op");
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+
+void ARM64Decoder::DecodeLogicalShift(Instr* instr) {
+ const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21);
+ switch (op) {
case 0:
- Format(instr, "add'sf's 'rd, 'rn, 'shift_op");
+ Format(instr, "and'sf 'rd, 'rn, 'shift_op");
break;
case 1:
- Format(instr, "sub'sf's 'rd, 'rn, 'shift_op");
+ Format(instr, "bic'sf 'rd, 'rn, 'shift_op");
+ break;
+ case 2:
+ Format(instr, "orr'sf 'rd, 'rn, 'shift_op");
+ break;
+ case 3:
+ Format(instr, "orn'sf 'rd, 'rn, 'shift_op");
+ break;
+ case 4:
+ Format(instr, "eor'sf 'rd, 'rn, 'shift_op");
+ break;
+ case 5:
+ Format(instr, "eon'sf 'rd, 'rn, 'shift_op");
+ break;
+ case 6:
+ Format(instr, "and'sfs 'rd, 'rn, 'shift_op");
+ break;
+ case 7:
+ Format(instr, "bic'sfs 'rd, 'rn, 'shift_op");
break;
default:
UNREACHABLE();
@@ -527,6 +615,8 @@
void ARM64Decoder::DecodeDPRegister(Instr* instr) {
if (instr->IsAddSubShiftExtOp()) {
DecodeAddSubShiftExt(instr);
+ } else if (instr->IsLogicalShiftOp()) {
+ DecodeLogicalShift(instr);
} else {
Unknown(instr);
}
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 5ba1ab7..845c7ff 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -33,10 +33,13 @@
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(bool, use_cha);
DECLARE_FLAG(bool, use_osr);
+DECLARE_FLAG(int, stacktrace_every);
+DECLARE_FLAG(charp, stacktrace_filter);
+DECLARE_FLAG(int, deoptimize_every);
+DECLARE_FLAG(charp, deoptimize_filter);
+
DEFINE_FLAG(bool, enable_simd_inline, true,
"Enable inlining of SIMD related method calls.");
-DEFINE_FLAG(charp, deoptimize_filter, NULL,
- "Force deoptimization in named function");
// Assign locations to incoming arguments, i.e., values pushed above spill slots
// with PushArgument. Recursively allocates from outermost to innermost
@@ -171,11 +174,22 @@
}
-bool FlowGraphCompiler::ShouldDeoptimizeFunction() const {
- return (is_optimizing() &&
- (FLAG_deoptimize_filter != NULL) &&
- (strstr(parsed_function().function().ToFullyQualifiedCString(),
- FLAG_deoptimize_filter) != NULL));
+bool FlowGraphCompiler::ForceSlowPathForStackOverflow() const {
+ if (FLAG_stacktrace_every > 0 || FLAG_deoptimize_every > 0) {
+ return true;
+ }
+ if (FLAG_stacktrace_filter != NULL &&
+ strstr(parsed_function().function().ToFullyQualifiedCString(),
+ FLAG_stacktrace_filter) != NULL) {
+ return true;
+ }
+ if (is_optimizing() &&
+ FLAG_deoptimize_filter != NULL &&
+ strstr(parsed_function().function().ToFullyQualifiedCString(),
+ FLAG_deoptimize_filter) != NULL) {
+ return true;
+ }
+ return false;
}
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index e9a1476..6940af2 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -269,7 +269,7 @@
bool CanOSRFunction() const;
bool is_optimizing() const { return is_optimizing_; }
- bool ShouldDeoptimizeFunction() const;
+ bool ForceSlowPathForStackOverflow() const;
const GrowableArray<BlockInfo*>& block_info() const { return block_info_; }
ParallelMoveResolver* parallel_move_resolver() {
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 1ae7daa..b40b3b3 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -2573,6 +2573,15 @@
: instruction_(instruction) { }
virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (FLAG_use_osr) {
+ uword flags_address = Isolate::Current()->stack_overflow_flags_address();
+ Register value = instruction_->locs()->temp(0).reg();
+ __ Comment("CheckStackOverflowSlowPathOsr");
+ __ Bind(osr_entry_label());
+ __ LoadImmediate(IP, flags_address);
+ __ LoadImmediate(value, Isolate::kOsrRequest);
+ __ str(value, Address(IP));
+ }
__ Comment("CheckStackOverflowSlowPath");
__ Bind(entry_label());
compiler->SaveLiveRegisters(instruction_->locs());
@@ -2598,8 +2607,14 @@
__ b(exit_label());
}
+ Label* osr_entry_label() {
+ ASSERT(FLAG_use_osr);
+ return &osr_entry_label_;
+ }
+
private:
CheckStackOverflowInstr* instruction_;
+ Label osr_entry_label_;
};
@@ -2621,7 +2636,10 @@
FLAG_optimization_counter_threshold * (loop_depth() + 1);
__ ldr(temp, FieldAddress(temp, Function::usage_counter_offset()));
__ CompareImmediate(temp, threshold);
- __ b(slow_path->entry_label(), GE);
+ __ b(slow_path->osr_entry_label(), GE);
+ }
+ if (compiler->ForceSlowPathForStackOverflow()) {
+ __ b(slow_path->entry_label());
}
__ Bind(slow_path->exit_label());
}
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 74a7587..d6a5573 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -2536,6 +2536,13 @@
: instruction_(instruction) { }
virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (FLAG_use_osr) {
+ uword flags_address = Isolate::Current()->stack_overflow_flags_address();
+ __ Comment("CheckStackOverflowSlowPathOsr");
+ __ Bind(osr_entry_label());
+ __ movl(Address::Absolute(flags_address),
+ Immediate(Isolate::kOsrRequest));
+ }
__ Comment("CheckStackOverflowSlowPath");
__ Bind(entry_label());
compiler->SaveLiveRegisters(instruction_->locs());
@@ -2561,8 +2568,14 @@
__ jmp(exit_label());
}
+ Label* osr_entry_label() {
+ ASSERT(FLAG_use_osr);
+ return &osr_entry_label_;
+ }
+
private:
CheckStackOverflowInstr* instruction_;
+ Label osr_entry_label_;
};
@@ -2570,9 +2583,6 @@
CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
compiler->AddSlowPathCode(slow_path);
- if (compiler->ShouldDeoptimizeFunction()) {
- __ jmp(slow_path->entry_label());
- }
__ cmpl(ESP,
Address::Absolute(Isolate::Current()->stack_limit_address()));
__ j(BELOW_EQUAL, slow_path->entry_label());
@@ -2585,7 +2595,12 @@
FLAG_optimization_counter_threshold * (loop_depth() + 1);
__ cmpl(FieldAddress(EDI, Function::usage_counter_offset()),
Immediate(threshold));
- __ j(GREATER_EQUAL, slow_path->entry_label());
+ __ j(GREATER_EQUAL, slow_path->osr_entry_label());
+ }
+ if (compiler->ForceSlowPathForStackOverflow()) {
+ // TODO(turnidge): Implement stack overflow count in assembly to
+ // make --stacktrace-every and --deoptimize-every faster.
+ __ jmp(slow_path->entry_label());
}
__ Bind(slow_path->exit_label());
}
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index fe94ba22..ad6a564 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -2312,6 +2312,16 @@
: instruction_(instruction) { }
virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (FLAG_use_osr) {
+ uword flags_address = Isolate::Current()->stack_overflow_flags_address();
+ Register value = instruction_->locs()->temp(0).reg();
+ __ TraceSimMsg("CheckStackOverflowSlowPathOsr");
+ __ Comment("CheckStackOverflowSlowPathOsr");
+ __ Bind(osr_entry_label());
+ __ LoadImmediate(TMP, flags_address);
+ __ LoadImmediate(value, Isolate::kOsrRequest);
+ __ sw(value, Address(TMP));
+ }
__ TraceSimMsg("CheckStackOverflowSlowPath");
__ Comment("CheckStackOverflowSlowPath");
__ Bind(entry_label());
@@ -2338,8 +2348,14 @@
__ b(exit_label());
}
+ Label* osr_entry_label() {
+ ASSERT(FLAG_use_osr);
+ return &osr_entry_label_;
+ }
+
private:
CheckStackOverflowInstr* instruction_;
+ Label osr_entry_label_;
};
@@ -2349,7 +2365,6 @@
compiler->AddSlowPathCode(slow_path);
__ LoadImmediate(TMP, Isolate::Current()->stack_limit_address());
-
__ lw(CMPRES1, Address(TMP));
__ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label());
if (compiler->CanOSRFunction() && in_loop()) {
@@ -2361,7 +2376,10 @@
intptr_t threshold =
FLAG_optimization_counter_threshold * (loop_depth() + 1);
__ lw(temp, FieldAddress(temp, Function::usage_counter_offset()));
- __ BranchSignedGreaterEqual(temp, threshold, slow_path->entry_label());
+ __ BranchSignedGreaterEqual(temp, threshold, slow_path->osr_entry_label());
+ }
+ if (compiler->ForceSlowPathForStackOverflow()) {
+ __ b(slow_path->entry_label());
}
__ Bind(slow_path->exit_label());
}
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index f5d8fc8..bbdd1fc 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -2317,6 +2317,14 @@
: instruction_(instruction) { }
virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (FLAG_use_osr) {
+ uword flags_address = Isolate::Current()->stack_overflow_flags_address();
+ Register temp = instruction_->locs()->temp(0).reg();
+ __ Comment("CheckStackOverflowSlowPathOsr");
+ __ Bind(osr_entry_label());
+ __ LoadImmediate(temp, Immediate(flags_address), PP);
+ __ movq(Address(temp, 0), Immediate(Isolate::kOsrRequest));
+ }
__ Comment("CheckStackOverflowSlowPath");
__ Bind(entry_label());
compiler->SaveLiveRegisters(instruction_->locs());
@@ -2342,8 +2350,15 @@
__ jmp(exit_label());
}
+
+ Label* osr_entry_label() {
+ ASSERT(FLAG_use_osr);
+ return &osr_entry_label_;
+ }
+
private:
CheckStackOverflowInstr* instruction_;
+ Label osr_entry_label_;
};
@@ -2366,7 +2381,10 @@
FLAG_optimization_counter_threshold * (loop_depth() + 1);
__ CompareImmediate(FieldAddress(temp, Function::usage_counter_offset()),
Immediate(threshold), PP);
- __ j(GREATER_EQUAL, slow_path->entry_label());
+ __ j(GREATER_EQUAL, slow_path->osr_entry_label());
+ }
+ if (compiler->ForceSlowPathForStackOverflow()) {
+ __ jmp(slow_path->entry_label());
}
__ Bind(slow_path->exit_label());
}
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d10bef9..aa8f2a7 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -321,6 +321,8 @@
mutex_(new Mutex()),
stack_limit_(0),
saved_stack_limit_(0),
+ stack_overflow_flags_(0),
+ stack_overflow_count_(0),
message_handler_(NULL),
spawn_state_(NULL),
is_runnable_(false),
@@ -662,6 +664,13 @@
}
+uword Isolate::GetAndClearStackOverflowFlags() {
+ uword stack_overflow_flags = stack_overflow_flags_;
+ stack_overflow_flags_ = 0;
+ return stack_overflow_flags;
+}
+
+
static int MostUsedFunctionFirst(const Function* const* a,
const Function* const* b) {
if ((*a)->usage_counter() > (*b)->usage_counter()) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 7bb26a5..2998fd8 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -226,6 +226,24 @@
// The true stack limit for this isolate.
uword saved_stack_limit() const { return saved_stack_limit_; }
+ // Stack overflow flags
+ enum {
+ kOsrRequest = 0x1, // Current stack overflow caused by OSR request.
+ };
+
+ uword stack_overflow_flags_address() const {
+ return reinterpret_cast<uword>(&stack_overflow_flags_);
+ }
+
+ int32_t IncrementAndGetStackOverflowCount() {
+ return ++stack_overflow_count_;
+ }
+
+ // Retrieves and clears the stack overflow flags. These are set by
+ // the generated code before the slow path runtime routine for a
+ // stack overflow is called.
+ uword GetAndClearStackOverflowFlags();
+
// Retrieve the stack address bounds.
bool GetStackBounds(uword* lower, uword* upper);
@@ -233,6 +251,7 @@
static const intptr_t kStackSizeBuffer = (4 * KB * kWordSize);
+ // Interrupt bits.
enum {
kApiInterrupt = 0x1, // An interrupt from Dart_InterruptIsolate.
kMessageInterrupt = 0x2, // An interrupt to process an out of band message.
@@ -510,6 +529,8 @@
Mutex* mutex_; // protects stack_limit_ and saved_stack_limit_.
uword stack_limit_;
uword saved_stack_limit_;
+ uword stack_overflow_flags_;
+ int32_t stack_overflow_count_;
MessageHandler* message_handler_;
IsolateSpawnState* spawn_state_;
bool is_runnable_;
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 1b34b63..d3cab91 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -13,7 +13,7 @@
namespace dart {
-DEFINE_FLAG(int, heap_growth_space_ratio, 10,
+DEFINE_FLAG(int, heap_growth_space_ratio, 20,
"The desired maximum percentage of free space after GC");
DEFINE_FLAG(int, heap_growth_time_ratio, 3,
"The desired maximum percentage of time spent in GC");
@@ -692,15 +692,16 @@
if (enough_free_space && enough_free_time) {
grow_heap_ = 0;
} else {
- intptr_t growth_target = static_cast<intptr_t>(
+ intptr_t used_target = static_cast<intptr_t>(
after_total_in_words / desired_utilization_);
- intptr_t growth_in_words = Utils::RoundUp(
- growth_target - after_total_in_words,
- PageSpace::kPageSizeInWords);
- int growth_in_pages =
- growth_in_words / PageSpace::kPageSizeInWords;
- grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_);
- heap->RecordData(PageSpace::kPageGrowth, growth_in_pages);
+ intptr_t capacity_growth_in_words =
+ Utils::RoundUp(Utils::Maximum(static_cast<intptr_t>(0),
+ used_target - after.capacity_in_words),
+ PageSpace::kPageSizeInWords);
+ int capacity_growth_in_pages =
+ capacity_growth_in_words / PageSpace::kPageSizeInWords;
+ grow_heap_ = Utils::Maximum(capacity_growth_in_pages, heap_growth_rate_);
+ heap->RecordData(PageSpace::kPageGrowth, capacity_growth_in_pages);
}
heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio);
heap->RecordData(PageSpace::kGCTimeFraction,
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index b549c6a..6645901 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -10323,7 +10323,9 @@
} else {
ASSERT(CurrentToken() == Token::kINTERPOL_START);
ConsumeToken();
+ const bool saved_mode = SetAllowFunctionLiterals(true);
expr = ParseExpr(kAllowConst, kConsumeCascades);
+ SetAllowFunctionLiterals(saved_mode);
ExpectToken(Token::kINTERPOL_END);
}
// Check if this interpolated string is still considered a compile time
@@ -10741,7 +10743,9 @@
ConsumeToken();
} else if (CurrentToken() == Token::kINTERPOL_START) {
ConsumeToken();
+ const bool saved_mode = SetAllowFunctionLiterals(true);
SkipExpr();
+ SetAllowFunctionLiterals(saved_mode);
ExpectToken(Token::kINTERPOL_END);
} else {
break;
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index d15b8e3..5a462cf 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -477,11 +477,64 @@
}
}
+
+void Simulator::DecodeLogicalImm(Instr* instr) {
+ const int op = instr->Bits(29, 2);
+ const bool set_flags = op == 3;
+ const int out_size = ((instr->SFField() == 0) && (instr->NField() == 0))
+ ? kWRegSizeInBits : kXRegSizeInBits;
+ const Register rn = instr->RnField();
+ const Register rd = instr->RdField();
+ const int64_t rn_val = get_register(rn, instr->RnMode());
+ const uint64_t imm = instr->ImmLogical();
+ if (imm == 0) {
+ UnimplementedInstruction(instr);
+ }
+
+ int64_t alu_out = 0;
+ switch (op) {
+ case 0:
+ alu_out = rn_val & imm;
+ break;
+ case 1:
+ alu_out = rn_val | imm;
+ break;
+ case 2:
+ alu_out = rn_val ^ imm;
+ break;
+ case 3:
+ alu_out = rn_val & imm;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (set_flags) {
+ if (out_size == kXRegSizeInBits) {
+ SetNZFlagsX(alu_out);
+ } else {
+ SetNZFlagsW(alu_out);
+ }
+ SetCFlag(false);
+ SetVFlag(false);
+ }
+
+ if (out_size == kXRegSizeInBits) {
+ set_register(rd, alu_out, instr->RdMode());
+ } else {
+ set_wregister(rd, alu_out, instr->RdMode());
+ }
+}
+
+
void Simulator::DecodeDPImmediate(Instr* instr) {
if (instr->IsMoveWideOp()) {
DecodeMoveWide(instr);
} else if (instr->IsAddSubImmOp()) {
DecodeAddSubImm(instr);
+ } else if (instr->IsLogicalImmOp()) {
+ DecodeLogicalImm(instr);
} else {
UnimplementedInstruction(instr);
}
@@ -821,9 +874,75 @@
}
+void Simulator::DecodeLogicalShift(Instr* instr) {
+ const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21);
+ const Register rd = instr->RdField();
+ const Register rn = instr->RnField();
+ const int64_t rn_val = get_register(rn, instr->RnMode());
+ const int64_t rm_val = DecodeShiftExtendOperand(instr);
+ int64_t alu_out = 0;
+ switch (op) {
+ case 0:
+ // Format(instr, "and'sf 'rd, 'rn, 'shift_op");
+ alu_out = rn_val & rm_val;
+ break;
+ case 1:
+ // Format(instr, "bic'sf 'rd, 'rn, 'shift_op");
+ alu_out = rn_val & (~rm_val);
+ break;
+ case 2:
+ // Format(instr, "orr'sf 'rd, 'rn, 'shift_op");
+ alu_out = rn_val | rm_val;
+ break;
+ case 3:
+ // Format(instr, "orn'sf 'rd, 'rn, 'shift_op");
+ alu_out = rn_val | (~rm_val);
+ break;
+ case 4:
+ // Format(instr, "eor'sf 'rd, 'rn, 'shift_op");
+ alu_out = rn_val ^ rm_val;
+ break;
+ case 5:
+ // Format(instr, "eon'sf 'rd, 'rn, 'shift_op");
+ alu_out = rn_val ^ (~rm_val);
+ break;
+ case 6:
+ // Format(instr, "and'sfs 'rd, 'rn, 'shift_op");
+ alu_out = rn_val & rm_val;
+ break;
+ case 7:
+ // Format(instr, "bic'sfs 'rd, 'rn, 'shift_op");
+ alu_out = rn_val & (~rm_val);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ // Set flags if ands or bics.
+ if ((op == 6) || (op == 7)) {
+ if (instr->SFField() == 1) {
+ SetNZFlagsX(alu_out);
+ } else {
+ SetNZFlagsW(alu_out);
+ }
+ SetCFlag(false);
+ SetVFlag(false);
+ }
+
+ if (instr->SFField() == 1) {
+ set_register(rd, alu_out, instr->RdMode());
+ } else {
+ set_wregister(rd, alu_out & kWRegMask, instr->RdMode());
+ }
+}
+
+
void Simulator::DecodeDPRegister(Instr* instr) {
if (instr->IsAddSubShiftExtOp()) {
DecodeAddSubShiftExt(instr);
+ } else if (instr->IsLogicalShiftOp()) {
+ DecodeLogicalShift(instr);
} else {
UnimplementedInstruction(instr);
}
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 1e417ab..bdfd4b4 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -10,7 +10,6 @@
import 'dart2jslib.dart' as leg;
import 'tree/tree.dart' as tree;
import 'elements/elements.dart' as elements;
-import 'ssa/tracer.dart' as ssa;
import '../../libraries.dart';
import 'source_file.dart';
@@ -35,8 +34,6 @@
: this.options = options,
this.allowedLibraryCategories = getAllowedLibraryCategories(options),
super(
- tracer: new ssa.HTracer(
- ssa.GENERATE_SSA_TRACE ? outputProvider('dart', 'cfg') : null),
outputProvider: outputProvider,
enableTypeAssertions: hasOption(options, '--enable-checked-mode'),
enableUserAssertions: hasOption(options, '--enable-checked-mode'),
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index cc0eac6..2dfbb57 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -774,8 +774,8 @@
assert(invariant(node, constructor.isImplementation));
List<Constant> arguments = getArguments(constructor);
- ConstructorEvaluator evaluator =
- new ConstructorEvaluator(constructor, handler, compiler);
+ ConstructorEvaluator evaluator = new ConstructorEvaluator(
+ constructedType, constructor, handler, compiler);
evaluator.evaluateConstructorFieldValues(arguments);
List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
@@ -807,6 +807,7 @@
}
class ConstructorEvaluator extends CompileTimeConstantEvaluator {
+ final InterfaceType constructedType;
final FunctionElement constructor;
final Map<Element, Constant> definitions;
final Map<Element, Constant> fieldValues;
@@ -816,7 +817,8 @@
*
* Invariant: [constructor] must be an implementation element.
*/
- ConstructorEvaluator(FunctionElement constructor,
+ ConstructorEvaluator(InterfaceType this.constructedType,
+ FunctionElement constructor,
ConstantCompiler handler,
Compiler compiler)
: this.constructor = constructor,
@@ -845,16 +847,12 @@
TypedElement element,
Constant constant) {
if (compiler.enableTypeAssertions) {
- DartType elementType = element.type;
+ DartType elementType = element.type.substByContext(constructedType);
DartType constantType = constant.computeType(compiler);
- // TODO(ngeoffray): Handle type parameters.
- if (elementType.element.isTypeVariable()) return;
if (!constantSystem.isSubtype(compiler, constantType, elementType)) {
- // TODO(johnniwinther): Provide better [node] values that point to the
- // origin of the constant and not (just) the assignment.
compiler.reportFatalError(
node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': elementType, 'toType': constantType});
+ {'fromType': constantType, 'toType': elementType});
}
}
}
@@ -871,9 +869,9 @@
*/
void assignArgumentsToParameters(List<Constant> arguments) {
// Assign arguments to parameters.
- FunctionSignature parameters = constructor.functionSignature;
+ FunctionSignature signature = constructor.functionSignature;
int index = 0;
- parameters.orderedForEachParameter((Element parameter) {
+ signature.orderedForEachParameter((Element parameter) {
Constant argument = arguments[index++];
Node node = parameter.parseNode(compiler);
potentiallyCheckType(node, parameter, argument);
@@ -888,6 +886,7 @@
void evaluateSuperOrRedirectSend(List<Constant> compiledArguments,
FunctionElement targetConstructor) {
ConstructorEvaluator evaluator = new ConstructorEvaluator(
+ constructedType.asInstanceOf(targetConstructor.getEnclosingClass()),
targetConstructor, handler, compiler);
evaluator.evaluateConstructorFieldValues(compiledArguments);
// Copy over the fieldValues from the super/redirect-constructor.
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 824f203..4899ec7 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -437,7 +437,7 @@
List<Uri> librariesToAnalyzeWhenRun;
- final Tracer tracer;
+ Tracer tracer;
CompilerTask measuredTask;
Element _currentElement;
@@ -638,8 +638,7 @@
/// Set by the backend if real reflection is detected in use of dart:mirrors.
bool disableTypeInferenceForMirrors = false;
- Compiler({this.tracer: const Tracer(),
- this.enableTypeAssertions: false,
+ Compiler({this.enableTypeAssertions: false,
this.enableUserAssertions: false,
this.trustTypeAnnotations: false,
this.enableConcreteTypeInference: false,
@@ -671,6 +670,7 @@
? NullSink.outputProvider
: outputProvider {
world = new World(this);
+ tracer = new Tracer(this.outputProvider);
closureMapping.ClosureNamer closureNamer;
if (emitJavaScript) {
@@ -1721,23 +1721,6 @@
}
}
-class Tracer {
- final bool enabled = false;
-
- const Tracer();
-
- void traceCompilation(String methodName,
- ItemCompilationContext context,
- Compiler compiler) {
- }
-
- void traceGraph(String name, var graph) {
- }
-
- void close() {
- }
-}
-
class SourceSpan implements Spannable {
final Uri uri;
final int begin;
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index 008096f..c6ba9b6 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -40,6 +40,7 @@
import 'mirrors_used.dart' show MirrorUsageAnalyzerTask;
import 'dump_info.dart';
import 'helpers/helpers.dart';
+import 'tracer.dart' show Tracer;
export 'resolution/resolution.dart' show TreeElements, TreeElementMapping;
export 'scanner/scannerlib.dart' show isUserDefinableOperator,
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index 94bdc2d..2d66728 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -236,9 +236,11 @@
ir.Function function = compiler.irBuilder.getIr(element);
tree.Builder builder = new tree.Builder(compiler);
tree.Expression expr = function.accept(builder);
+ compiler.tracer.traceGraph('Tree builder', expr);
treeElements = new TreeElementMapping(element);
tree.Unnamer unnamer = new tree.Unnamer();
expr = unnamer.unname(expr);
+ compiler.tracer.traceGraph('Unnamer', expr);
tree.Emitter emitter = new tree.Emitter();
node = emitter.emit(element, treeElements, expr);
}
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/tree_tracer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_tracer.dart
new file mode 100644
index 0000000..e50ca26
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_tracer.dart
@@ -0,0 +1,157 @@
+library dart_backend.tracer;
+
+import 'dart:async' show EventSink;
+import '../tracer.dart';
+import 'dart_tree.dart';
+
+class TreeTracer extends TracerUtil implements Visitor {
+
+ final EventSink<String> output;
+
+ TreeTracer(this.output);
+
+ Names names;
+ int stmtCounter;
+
+ void traceGraph(String name, Expression exp) {
+ names = new Names();
+ stmtCounter = 0;
+ tag("cfg", () {
+ printProperty("name", name);
+ printBlock(exp);
+ });
+ names = null;
+ }
+
+ void printBlock(Expression e) {
+ tag("block", () {
+ printProperty("name", "B0"); // Update when proper blocks exist
+ printProperty("from_bci", -1);
+ printProperty("to_bci", -1);
+ printProperty("predecessors", ""); // Update when proper blocks exist
+ printProperty("successors", ""); // Update when proper blocks exist
+ printEmptyProperty("xhandlers");
+ printEmptyProperty("flags");
+ tag("states", () {
+ tag("locals", () {
+ printProperty("size", 0);
+ printProperty("method", "None");
+ });
+ });
+ tag("HIR", () {
+ e.accept(this);
+ });
+ });
+ }
+
+ void printStmt(String def, String contents) {
+ int bci = 0;
+ int uses = 0;
+ if (def == null) {
+ def = 'x${stmtCounter++}';
+ }
+ addIndent();
+ add("$bci $uses $def $contents <|@\n");
+ }
+
+ visitVariable(Variable node) {
+ printStmt(null, "dead-use ${names.varName(node)}");
+ }
+
+ visitSequence(Sequence node) {
+ for (Expression e in node.expressions) {
+ e.accept(this);
+ }
+ }
+
+ visitLetVal(LetVal node) {
+ String name = names.varName(node.variable);
+ String rhs = expr(node.definition);
+ printStmt(name, "let $name = $rhs");
+ node.body.accept(this);
+ }
+
+ visitInvokeStatic(InvokeStatic node) {
+ printStmt(null, expr(node));
+ }
+
+ visitReturn(Return node) {
+ printStmt(null, "return ${expr(node.value)}");
+ }
+
+ visitConstant(Constant node) {
+ printStmt(null, "dead-use ${node.value}");
+ }
+
+ visitNode(Node node) {}
+ visitExpression(Expression node) {}
+
+ String expr(Expression e) {
+ return e.accept(new SubExprVisitor(names));
+ }
+
+}
+
+class SubExprVisitor implements Visitor<String> {
+ Names names;
+
+ SubExprVisitor(this.names);
+
+ String visitVariable(Variable node) {
+ return names.varName(node);
+ }
+ String visitSequence(Sequence node) {
+ String exps = node.expressions.map((e) => e.accept(this)).join('; ');
+ return "{ $exps }";
+ }
+ String visitLetVal(LetVal node) {
+ String name = names.varName(node.variable);
+ String def = node.definition.accept(this);
+ String body = node.body.accept(this);
+ return "(let $name = $def in $body)";
+ }
+ String visitInvokeStatic(InvokeStatic node) {
+ String head = node.target.name;
+ String args = node.arguments.map((e) => e.accept(this)).join(', ');
+ return "$head($args)";
+ }
+ String visitReturn(Return node) {
+ return "return ${node.value.accept(this)}";
+ }
+ String visitConstant(Constant node) {
+ return "${node.value}";
+ }
+
+ visitNode(Node node) {}
+ visitExpression(Expression node) {}
+}
+
+/**
+ * Invents (and remembers) names for Variables that do not have an associated
+ * identifier.
+ *
+ * In case a variable is named v0, v1, etc, it may be assigned a different
+ * name to avoid clashing with a previously synthesized variable name.
+ */
+class Names {
+
+ final Map<Variable, String> _names = {};
+ final Set<String> _usedNames = new Set();
+ int _counter = 0;
+
+ String varName(Variable v) {
+ String name = _names[v];
+ if (name == null) {
+ if (v.identifier != null) {
+ name = v.identifier.token.value;
+ }
+ while (name == null || _usedNames.contains(name)) {
+ name = "v${_counter++}";
+ }
+ _names[v] = name;
+ _usedNames.add(name);
+ }
+ return name;
+ }
+
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
index 294fb34..81fba7f 100644
--- a/sdk/lib/_internal/compiler/implementation/deferred_load.dart
+++ b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
@@ -120,10 +120,15 @@
/// Will be `true` if the program contains deferred libraries.
bool splitProgram = false;
- /// A mapping from the name of a [DeferredLibrary] annotation to all dependent
- /// output units.
- final Map<String, Set<OutputUnit>> hunksToLoad =
- new Map<String, Set<OutputUnit>>();
+ /// A mapping from the name of a defer import to all the output units it
+ /// depends on in a list of lists to be loaded in the order they appear.
+ ///
+ /// For example {"lib1": [[lib1_lib2_lib3], [lib1_lib2, lib1_lib3],
+ /// [lib1]]} would mean that in order to load "lib1" first the hunk
+ /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3
+ /// can be loaded in parallel. And finally lib1 can be loaded.
+ final Map<String, List<List<OutputUnit>>> hunksToLoad =
+ new Map<String, List<List<OutputUnit>>>();
final Map<Import, String> importDeferName = new Map<Import, String>();
/// A mapping from elements and constants to their output unit. Query this via
@@ -458,8 +463,7 @@
void mapDependenciesIfResolved(Element element) {
// If there is a target for this class, but no use of mirrors the
// class will not be resolved. We just skip it.
- if (element is ClassElement &&
- !(element as ClassElement).isResolved) {
+ if (element is ClassElement &&!element.isResolved) {
return;
}
_mapDependencies(element, deferredImport);
@@ -639,15 +643,36 @@
for (OutputUnit outputUnit in allOutputUnits) {
computeOutputUnitName(outputUnit);
}
+ List sortedOutputUnits = new List.from(allOutputUnits);
+ // Sort the output units in descending order of the number of imports they
+ // include.
+
+ // The loading of the output units mut be ordered because a superclass needs
+ // to be initialized before its subclass.
+ // But a class can only depend on another class in an output unit shared by
+ // a strict superset of the imports:
+ // By contradiction: Assume a class C in output unit shared by imports in
+ // the set S1 = (lib1,.., lib_n) depends on a class D in an output unit
+ // shared by S2 such that S2 not a superset of S1. Let lib_s be a library in
+ // S1 not in S2. lib_s must depend on C, and then in turn on D therefore D
+ // is not in the right output unit.
+ sortedOutputUnits.sort((a, b) => b.imports.length - a.imports.length);
// For each deferred import we find out which outputUnits to load.
for (Import import in _allDeferredImports.keys) {
if (import == _fakeMainImport) continue;
- hunksToLoad[importDeferName[import]] = new Set<OutputUnit>();
- for (OutputUnit outputUnit in allOutputUnits) {
+ hunksToLoad[importDeferName[import]] = new List<List<OutputUnit>>();
+ int lastNumberOfImports = 0;
+ List<OutputUnit> currentLastList;
+ for (OutputUnit outputUnit in sortedOutputUnits) {
if (outputUnit == mainOutputUnit) continue;
if (outputUnit.imports.contains(import)) {
- hunksToLoad[importDeferName[import]].add(outputUnit);
+ if (outputUnit.imports.length != lastNumberOfImports) {
+ lastNumberOfImports = outputUnit.imports.length;
+ currentLastList = new List<OutputUnit>();
+ hunksToLoad[importDeferName[import]].add(currentLastList);
+ }
+ currentLastList.add(outputUnit);
}
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
index fe1da9a..1bcc733 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
@@ -81,6 +81,8 @@
return true;
});
nodes[element] = function;
+ compiler.tracer.traceCompilation(element.name, null, compiler);
+ compiler.tracer.traceGraph("IR Builder", function);
}
}
});
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_tracer.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_tracer.dart
new file mode 100644
index 0000000..643d46a2
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_tracer.dart
@@ -0,0 +1,238 @@
+library dart2js.ir_tracer;
+
+import 'dart:async' show EventSink;
+
+import 'ir_nodes.dart' as ir;
+import 'ir_nodes.dart' hide Function;
+import '../tracer.dart';
+
+/**
+ * If true, show LetCont expressions in output.
+ */
+const bool IR_TRACE_LET_CONT = false;
+
+class IRTracer extends TracerUtil implements Visitor {
+ int indent = 0;
+ EventSink<String> output;
+
+ IRTracer(this.output);
+
+ void traceGraph(String name, ir.Function graph) {
+ tag("cfg", () {
+ printProperty("name", name);
+ visitFunction(graph);
+ });
+ }
+
+ // Temporary field used during tree walk
+ Names names;
+
+ visitFunction(ir.Function f) {
+ names = new Names();
+ BlockCollector builder = new BlockCollector(names);
+ f.accept(builder);
+
+ printNode(builder.entry);
+ for (Block block in builder.cont2block.values) {
+ printNode(block);
+ }
+ names = null;
+ }
+
+ printNode(Block block) {
+ tag("block", () {
+ printProperty("name", block.name);
+ printProperty("from_bci", -1);
+ printProperty("to_bci", -1);
+ printProperty("predecessors", block.pred.map((n) => n.name));
+ printProperty("successors", block.succ.map((n) => n.name));
+ printEmptyProperty("xhandlers");
+ printEmptyProperty("flags");
+ tag("states", () {
+ tag("locals", () {
+ printProperty("size", 0);
+ printProperty("method", "None");
+ // We could print parameters here,
+ // but does the hydra tool actually use this info??
+ });
+ });
+ tag("HIR", () {
+ block.body.accept(this);
+ });
+ });
+ }
+
+ void printStmt(String resultVar, String contents) {
+ int bci = 0;
+ int uses = 0;
+ addIndent();
+ add("$bci $uses $resultVar $contents <|@\n");
+ }
+
+ visitLetPrim(LetPrim node) {
+ String id = names.name(node.primitive);
+ printStmt(id, "LetPrim $id = ${formatPrimitive(node.primitive)}");
+ node.body.accept(this);
+ }
+
+ visitLetCont(LetCont node) {
+ if (IR_TRACE_LET_CONT) {
+ String dummy = names.name(node);
+ String id = names.name(node.continuation);
+ printStmt(dummy, "LetCont $id = <$id>");
+ }
+ node.body.accept(this);
+ }
+
+ visitInvokeStatic(InvokeStatic node) {
+ String dummy = names.name(node);
+ String callName = node.selector.name;
+ String args = node.arguments.map(formatReference).join(', ');
+ String kont = formatReference(node.continuation);
+ printStmt(dummy, "InvokeStatic $callName ($args) $kont");
+ }
+
+ visitInvokeContinuation(InvokeContinuation node) {
+ String dummy = names.name(node);
+ String kont = formatReference(node.continuation);
+ String arg = formatReference(node.argument);
+ printStmt(dummy, "InvokeContinuation $kont ($arg)");
+ }
+
+ String formatReference(Reference ref) {
+ Definition target = ref.definition;
+ if (target is Continuation && target.body == null) {
+ return "return"; // Do not generate a name for the return continuation
+ } else {
+ return names.name(ref.definition);
+ }
+ }
+
+ String formatPrimitive(Primitive p) {
+ return p.accept(this);
+ }
+
+ visitConstant(ir.Constant node) {
+ return "Constant ${node.value}";
+ }
+
+ visitParameter(Parameter node) {
+ return "Parameter ${names.name(node)}";
+ }
+
+ visitContinuation(Continuation node) {
+ return "Continuation ${names.name(node)}";
+ }
+
+ visitExpression(Expression e) {}
+ visitPrimitive(Primitive p) {}
+ visitDefinition(Definition d) {}
+ visitNode(Node n) {}
+}
+
+/**
+ * Invents (and remembers) names for Continuations, Parameters, etc.
+ * The names must match the conventions used by IR Hydra, e.g.
+ * Continuations and Functions must have names of form B### since they
+ * are visualized as basic blocks.
+ */
+class Names {
+ final Map<Object, String> names = {};
+ final Map<String, int> counters = {
+ 'r': 0,
+ 'B': 0,
+ 'v': 0,
+ 'x': 0
+ };
+
+ String prefix(x) {
+ if (x is Parameter) return 'r';
+ if (x is Continuation || x is ir.Function) return 'B';
+ if (x is Primitive) return 'v';
+ return 'x';
+ }
+
+ String name(x) {
+ String nam = names[x];
+ if (nam == null) {
+ String pref = prefix(x);
+ int id = counters[pref]++;
+ nam = names[x] = '${pref}${id}';
+ }
+ return nam;
+ }
+}
+
+/**
+ * A vertex in the graph visualization, used in place of basic blocks.
+ */
+class Block {
+ String name;
+ final List<Parameter> parameters;
+ final Expression body;
+ final List<Block> succ = <Block>[];
+ final List<Block> pred = <Block>[];
+
+ Block(this.name, this.parameters, this.body);
+
+ void addEdgeTo(Block successor) {
+ succ.add(successor);
+ successor.pred.add(this);
+ }
+}
+
+class BlockCollector implements Visitor {
+ Block entry;
+ final Map<Continuation, Block> cont2block = <Continuation, Block> {};
+ Block current_block;
+
+ Names names;
+ BlockCollector(this.names);
+
+ Block getBlock(Continuation c) {
+ Block block = cont2block[c];
+ if (block == null) {
+ block = new Block(names.name(c), [c.parameter], c.body);
+ cont2block[c] = block;
+ }
+ return block;
+ }
+
+ visitFunction(ir.Function f) {
+ entry = current_block = new Block(names.name(f), [], f.body);
+ f.body.accept(this);
+ }
+ visitLetPrim(LetPrim exp) {
+ exp.body.accept(this);
+ }
+ visitLetCont(LetCont exp) {
+ exp.continuation.accept(this);
+ exp.body.accept(this);
+ }
+ visitInvokeStatic(InvokeStatic exp) {
+ Definition target = exp.continuation.definition;
+ if (target is Continuation && target.body != null) {
+ current_block.addEdgeTo(getBlock(target));
+ }
+ }
+
+ visitInvokeContinuation(InvokeContinuation exp) {
+ Definition target = exp.continuation.definition;
+ if (target is Continuation && target.body != null) {
+ current_block.addEdgeTo(getBlock(target));
+ }
+ }
+ visitConstant(ir.Constant constant) {}
+ visitParameter(Parameter p) {}
+ visitContinuation(Continuation c) {
+ var old_node = current_block;
+ current_block = getBlock(c);
+ c.body.accept(this);
+ current_block = old_node;
+ }
+
+ visitPrimitive(Primitive p) {}
+ visitDefinition(Definition d) {}
+ visitExpression(Expression e) {}
+ visitNode(Node n) {}
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index a419a7b..cfd3a2f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -1439,17 +1439,22 @@
// [emitOneShotInterceptors] have been called.
emitCompileTimeConstants(mainBuffer, mainOutputUnit);
- // We write a javascript mapping from DeferredLibrary elements
- // (really their String argument) to the js hunk to load.
+ // Write a javascript mapping from Deferred import load ids (derrived from
+ // the import prefix.) to a list of lists of js hunks to load.
// TODO(sigurdm): Create a syntax tree for this.
// TODO(sigurdm): Also find out where to place it.
mainBuffer.write("\$.libraries_to_load = {");
- for (String constant in compiler.deferredLoadTask.hunksToLoad.keys) {
+ for (String loadId in compiler.deferredLoadTask.hunksToLoad.keys) {
// TODO(sigurdm): Escape these strings.
- mainBuffer.write('"$constant":[');
- for (OutputUnit outputUnit in
- compiler.deferredLoadTask.hunksToLoad[constant]) {
- mainBuffer.write('"${outputUnit.partFileName(compiler)}.part.js", ');
+ mainBuffer.write('"$loadId":[');
+ for (List<OutputUnit> outputUnits in
+ compiler.deferredLoadTask.hunksToLoad[loadId]) {
+ mainBuffer.write("[");
+ for (OutputUnit outputUnit in outputUnits) {
+ mainBuffer
+ .write('"${outputUnit.partFileName(compiler)}.part.js", ');
+ }
+ mainBuffer.write("],");
}
mainBuffer.write("],\n");
}
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index 96dcd2a..0f6d7a0 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -1977,19 +1977,22 @@
VariableDefinitions parseNode(Element element, DiagnosticListener listener) {
if (definitions != null) return definitions;
- definitions = parse(listener,
- element.getCompilationUnit(),
- (p) => p.parseVariablesDeclaration(beginToken));
- if (!definitions.modifiers.isVar() &&
- !definitions.modifiers.isFinal() &&
- !definitions.modifiers.isConst() &&
- definitions.type == null) {
- listener.reportError(
- definitions,
- MessageKind.GENERIC,
- { 'text': 'A field declaration must start with var, final, '
- 'const, or a type annotation.' });
- }
+ listener.withCurrentElement(element, () {
+ definitions = parse(listener,
+ element.getCompilationUnit(),
+ (p) => p.parseVariablesDeclaration(beginToken));
+
+ if (!definitions.modifiers.isVar() &&
+ !definitions.modifiers.isFinal() &&
+ !definitions.modifiers.isConst() &&
+ definitions.type == null) {
+ listener.reportError(
+ definitions,
+ MessageKind.GENERIC,
+ { 'text': 'A field declaration must start with var, final, '
+ 'const, or a type annotation.' });
+ }
+ });
return definitions;
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa_tracer.dart
similarity index 91%
rename from sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
rename to sdk/lib/_internal/compiler/implementation/ssa/ssa_tracer.dart
index 13056a6..5bd7e46 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa_tracer.dart
@@ -2,49 +2,28 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library tracer;
+library ssa.tracer;
import 'dart:async' show EventSink;
import 'ssa.dart';
import '../js_backend/js_backend.dart';
import '../dart2jslib.dart';
+import '../tracer.dart';
-const bool GENERATE_SSA_TRACE = false;
-const String SSA_TRACE_FILTER = null;
-
-class HTracer extends HGraphVisitor implements Tracer {
+/**
+ * Outputs SSA code in a format readable by Hydra IR.
+ * Tracing is disabled by default, see ../tracer.dart for how
+ * to enable it.
+ */
+class HTracer extends HGraphVisitor with TracerUtil {
Compiler compiler;
JavaScriptItemCompilationContext context;
- int indent = 0;
final EventSink<String> output;
- final bool enabled = GENERATE_SSA_TRACE;
- bool traceActive = false;
- HTracer(this.output);
-
- void close() {
- if (enabled) output.close();
- }
-
- void traceCompilation(String methodName,
- JavaScriptItemCompilationContext compilationContext,
- Compiler compiler) {
- if (!enabled) return;
- this.context = compilationContext;
- this.compiler = compiler;
- traceActive =
- SSA_TRACE_FILTER == null || methodName.contains(SSA_TRACE_FILTER);
- if (!traceActive) return;
- tag("compilation", () {
- printProperty("name", methodName);
- printProperty("method", methodName);
- printProperty("date", new DateTime.now().millisecondsSinceEpoch);
- });
- }
+ HTracer(this.output, this.compiler, this.context);
void traceGraph(String name, HGraph graph) {
- if (!traceActive) return;
tag("cfg", () {
printProperty("name", name);
visitDominatorTree(graph);
@@ -129,42 +108,6 @@
});
});
}
-
- void tag(String tagName, Function f) {
- println("begin_$tagName");
- indent++;
- f();
- indent--;
- println("end_$tagName");
- }
-
- void println(String string) {
- addIndent();
- add(string);
- add("\n");
- }
-
- void printEmptyProperty(String propertyName) {
- println(propertyName);
- }
-
- void printProperty(String propertyName, var value) {
- if (value is num) {
- println("$propertyName $value");
- } else {
- println('$propertyName "$value"');
- }
- }
-
- void add(String string) {
- output.add(string);
- }
-
- void addIndent() {
- for (int i = 0; i < indent; i++) {
- add(" ");
- }
- }
}
class HInstructionStringifier implements HVisitor<String> {
diff --git a/sdk/lib/_internal/compiler/implementation/tracer.dart b/sdk/lib/_internal/compiler/implementation/tracer.dart
new file mode 100644
index 0000000..0ffc3d6
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/tracer.dart
@@ -0,0 +1,122 @@
+library tracer;
+
+import '../compiler.dart' as api;
+import 'dart:async' show EventSink;
+import 'ssa/ssa.dart' as ssa;
+import 'ssa/ssa_tracer.dart' show HTracer;
+import 'ir/ir_nodes.dart' as ir;
+import 'ir/ir_tracer.dart' show IRTracer;
+import 'dart_backend/dart_tree.dart' as tree;
+import 'dart_backend/tree_tracer.dart' show TreeTracer;
+import 'dart2jslib.dart';
+
+/**
+ * Set to true to enable tracing.
+ */
+const bool GENERATE_TRACE = false;
+
+/**
+ * If non-null, we only trace methods whose name contains the given substring.
+ */
+const String TRACE_FILTER = null;
+
+/**
+ * Dumps the intermediate representation after each phase in a format
+ * readable by Hydra IR.
+ */
+class Tracer extends TracerUtil {
+ Compiler compiler;
+ ItemCompilationContext context;
+ bool traceActive = false;
+ final EventSink<String> output;
+ final bool enabled = GENERATE_TRACE;
+
+ Tracer(api.CompilerOutputProvider outputProvider) :
+ output = GENERATE_TRACE ? outputProvider('dart', 'cfg') : null;
+
+ void traceCompilation(String methodName,
+ ItemCompilationContext compilationContext,
+ Compiler compiler) {
+ if (!enabled) return;
+ this.context = compilationContext;
+ this.compiler = compiler;
+ traceActive =
+ TRACE_FILTER == null || methodName.contains(TRACE_FILTER);
+ if (!traceActive) return;
+ tag("compilation", () {
+ printProperty("name", methodName);
+ printProperty("method", methodName);
+ printProperty("date", new DateTime.now().millisecondsSinceEpoch);
+ });
+ }
+
+ void traceGraph(String name, var irObject) {
+ if (!traceActive) return;
+ if (irObject is ssa.HGraph) {
+ new HTracer(output, compiler, context).traceGraph(name, irObject);
+ }
+ else if (irObject is ir.Function) {
+ new IRTracer(output).traceGraph(name, irObject);
+ }
+ else if (irObject is tree.Expression) {
+ new TreeTracer(output).traceGraph(name, irObject);
+ }
+ }
+
+ void close() {
+ if (output != null) {
+ output.close();
+ }
+ }
+}
+
+
+abstract class TracerUtil {
+ int indent = 0;
+ EventSink<String> get output;
+
+
+ void tag(String tagName, Function f) {
+ println("begin_$tagName");
+ indent++;
+ f();
+ indent--;
+ println("end_$tagName");
+ }
+
+ void println(String string) {
+ addIndent();
+ add(string);
+ add("\n");
+ }
+
+ void printEmptyProperty(String propertyName) {
+ println(propertyName);
+ }
+
+ String formatPrty(x) {
+ if (x is num) {
+ return '${x}';
+ } else if (x is String) {
+ return '"${x}"';
+ } else if (x is Iterable) {
+ return x.map((s) => formatPrty(s)).join(' ');
+ } else {
+ throw "invalid property type: ${x}";
+ }
+ }
+
+ void printProperty(String propertyName, value) {
+ println("$propertyName ${formatPrty(value)}");
+ }
+
+ void add(String string) {
+ output.add(string);
+ }
+
+ void addIndent() {
+ for (int i = 0; i < indent; i++) {
+ add(" ");
+ }
+ }
+}
diff --git a/sdk/lib/_internal/lib/async_patch.dart b/sdk/lib/_internal/lib/async_patch.dart
index 06bd2a5..aa1c342 100644
--- a/sdk/lib/_internal/lib/async_patch.dart
+++ b/sdk/lib/_internal/lib/async_patch.dart
@@ -33,7 +33,7 @@
}
patch class DeferredLibrary {
- patch Future<bool> load() {
+ patch Future<Null> load() {
return loadDeferredLibrary(libraryName, uri);
}
}
diff --git a/sdk/lib/_internal/lib/collection_patch.dart b/sdk/lib/_internal/lib/collection_patch.dart
index a7e7ee2..463fab9 100644
--- a/sdk/lib/_internal/lib/collection_patch.dart
+++ b/sdk/lib/_internal/lib/collection_patch.dart
@@ -83,13 +83,17 @@
var nums = _nums;
return (nums == null) ? false : _hasTableEntry(nums, key);
} else {
- var rest = _rest;
- if (rest == null) return false;
- var bucket = _getBucket(rest, key);
- return _findBucketIndex(bucket, key) >= 0;
+ return _containsKey(key);
}
}
+ bool _containsKey(Object key) {
+ var rest = _rest;
+ if (rest == null) return false;
+ var bucket = _getBucket(rest, key);
+ return _findBucketIndex(bucket, key) >= 0;
+ }
+
bool containsValue(Object value) {
return _computeKeys().any((each) => this[each] == value);
}
@@ -108,14 +112,18 @@
var nums = _nums;
return (nums == null) ? null : _getTableEntry(nums, key);
} else {
- var rest = _rest;
- if (rest == null) return null;
- var bucket = _getBucket(rest, key);
- int index = _findBucketIndex(bucket, key);
- return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1);
+ return _get(key);
}
}
+ V _get(Object key) {
+ var rest = _rest;
+ if (rest == null) return null;
+ var bucket = _getBucket(rest, key);
+ int index = _findBucketIndex(bucket, key);
+ return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1);
+ }
+
void operator[]=(K key, V value) {
if (_isStringKey(key)) {
var strings = _strings;
@@ -126,23 +134,27 @@
if (nums == null) _nums = nums = _newHashTable();
_addHashTableEntry(nums, key, value);
} else {
- var rest = _rest;
- if (rest == null) _rest = rest = _newHashTable();
- var hash = _computeHashCode(key);
- var bucket = JS('var', '#[#]', rest, hash);
- if (bucket == null) {
- _setTableEntry(rest, hash, JS('var', '[#, #]', key, value));
+ _set(key, value);
+ }
+ }
+
+ void _set(K key, V value) {
+ var rest = _rest;
+ if (rest == null) _rest = rest = _newHashTable();
+ var hash = _computeHashCode(key);
+ var bucket = JS('var', '#[#]', rest, hash);
+ if (bucket == null) {
+ _setTableEntry(rest, hash, JS('var', '[#, #]', key, value));
+ _length++;
+ _keys = null;
+ } else {
+ int index = _findBucketIndex(bucket, key);
+ if (index >= 0) {
+ JS('void', '#[#] = #', bucket, index + 1, value);
+ } else {
+ JS('void', '#.push(#, #)', bucket, key, value);
_length++;
_keys = null;
- } else {
- int index = _findBucketIndex(bucket, key);
- if (index >= 0) {
- JS('void', '#[#] = #', bucket, index + 1, value);
- } else {
- JS('void', '#.push(#, #)', bucket, key, value);
- _length++;
- _keys = null;
- }
}
}
}
@@ -160,21 +172,25 @@
} else if (_isNumericKey(key)) {
return _removeHashTableEntry(_nums, key);
} else {
- var rest = _rest;
- if (rest == null) return null;
- var bucket = _getBucket(rest, key);
- int index = _findBucketIndex(bucket, key);
- if (index < 0) return null;
- // TODO(kasperl): Consider getting rid of the bucket list when
- // the length reaches zero.
- _length--;
- _keys = null;
- // Use splice to remove the two [key, value] elements at the
- // index and return the value.
- return JS('var', '#.splice(#, 2)[1]', bucket, index);
+ return _remove(key);
}
}
+ V _remove(Object key) {
+ var rest = _rest;
+ if (rest == null) return null;
+ var bucket = _getBucket(rest, key);
+ int index = _findBucketIndex(bucket, key);
+ if (index < 0) return null;
+ // TODO(kasperl): Consider getting rid of the bucket list when
+ // the length reaches zero.
+ _length--;
+ _keys = null;
+ // Use splice to remove the two [key, value] elements at the
+ // index and return the value.
+ return JS('var', '#.splice(#, 2)[1]', bucket, index);
+ }
+
void clear() {
if (_length > 0) {
_strings = _nums = _rest = _keys = null;
@@ -370,17 +386,21 @@
V operator[](Object key) {
if (!_validKey(key)) return null;
- return super[key];
+ return super._get(key);
+ }
+
+ void operator[]=(K key, V value) {
+ super._set(key, value);
}
bool containsKey(Object key) {
if (!_validKey(key)) return false;
- return super.containsKey(key);
+ return super._containsKey(key);
}
V remove(Object key) {
if (!_validKey(key)) return null;
- return super.remove(key);
+ return super._remove(key);
}
int _computeHashCode(var key) {
@@ -555,13 +575,17 @@
LinkedHashMapCell cell = _getTableEntry(nums, key);
return cell != null;
} else {
- var rest = _rest;
- if (rest == null) return false;
- var bucket = _getBucket(rest, key);
- return _findBucketIndex(bucket, key) >= 0;
+ return _containsKey(key);
}
}
+ bool _containsKey(Object key) {
+ var rest = _rest;
+ if (rest == null) return false;
+ var bucket = _getBucket(rest, key);
+ return _findBucketIndex(bucket, key) >= 0;
+ }
+
bool containsValue(Object value) {
return keys.any((each) => this[each] == value);
}
@@ -584,16 +608,20 @@
LinkedHashMapCell cell = _getTableEntry(nums, key);
return (cell == null) ? null : cell._value;
} else {
- var rest = _rest;
- if (rest == null) return null;
- var bucket = _getBucket(rest, key);
- int index = _findBucketIndex(bucket, key);
- if (index < 0) return null;
- LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
- return cell._value;
+ return _get(key);
}
}
+ V _get(Object key) {
+ var rest = _rest;
+ if (rest == null) return null;
+ var bucket = _getBucket(rest, key);
+ int index = _findBucketIndex(bucket, key);
+ if (index < 0) return null;
+ LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
+ return cell._value;
+ }
+
void operator[]=(K key, V value) {
if (_isStringKey(key)) {
var strings = _strings;
@@ -604,22 +632,26 @@
if (nums == null) _nums = nums = _newHashTable();
_addHashTableEntry(nums, key, value);
} else {
- var rest = _rest;
- if (rest == null) _rest = rest = _newHashTable();
- var hash = _computeHashCode(key);
- var bucket = JS('var', '#[#]', rest, hash);
- if (bucket == null) {
- LinkedHashMapCell cell = _newLinkedCell(key, value);
- _setTableEntry(rest, hash, JS('var', '[#]', cell));
+ _set(key, value);
+ }
+ }
+
+ void _set(K key, V value) {
+ var rest = _rest;
+ if (rest == null) _rest = rest = _newHashTable();
+ var hash = _computeHashCode(key);
+ var bucket = JS('var', '#[#]', rest, hash);
+ if (bucket == null) {
+ LinkedHashMapCell cell = _newLinkedCell(key, value);
+ _setTableEntry(rest, hash, JS('var', '[#]', cell));
+ } else {
+ int index = _findBucketIndex(bucket, key);
+ if (index >= 0) {
+ LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
+ cell._value = value;
} else {
- int index = _findBucketIndex(bucket, key);
- if (index >= 0) {
- LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
- cell._value = value;
- } else {
- LinkedHashMapCell cell = _newLinkedCell(key, value);
- JS('void', '#.push(#)', bucket, cell);
- }
+ LinkedHashMapCell cell = _newLinkedCell(key, value);
+ JS('void', '#.push(#)', bucket, cell);
}
}
}
@@ -637,21 +669,25 @@
} else if (_isNumericKey(key)) {
return _removeHashTableEntry(_nums, key);
} else {
- var rest = _rest;
- if (rest == null) return null;
- var bucket = _getBucket(rest, key);
- int index = _findBucketIndex(bucket, key);
- if (index < 0) return null;
- // Use splice to remove the [cell] element at the index and
- // unlink the cell before returning its value.
- LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
- _unlinkCell(cell);
- // TODO(kasperl): Consider getting rid of the bucket list when
- // the length reaches zero.
- return cell._value;
+ return _remove(key);
}
}
+ V _remove(Object key) {
+ var rest = _rest;
+ if (rest == null) return null;
+ var bucket = _getBucket(rest, key);
+ int index = _findBucketIndex(bucket, key);
+ if (index < 0) return null;
+ // Use splice to remove the [cell] element at the index and
+ // unlink the cell before returning its value.
+ LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
+ _unlinkCell(cell);
+ // TODO(kasperl): Consider getting rid of the bucket list when
+ // the length reaches zero.
+ return cell._value;
+ }
+
void clear() {
if (_length > 0) {
_strings = _nums = _rest = _first = _last = null;
@@ -823,17 +859,21 @@
V operator[](Object key) {
if (!_validKey(key)) return null;
- return super[key];
+ return super._get(key);
+ }
+
+ void operator[]=(K key, V value) {
+ super._set(key, value);
}
bool containsKey(Object key) {
if (!_validKey(key)) return false;
- return super.containsKey(key);
+ return super._containsKey(key);
}
V remove(Object key) {
if (!_validKey(key)) return null;
- return super.remove(key);
+ return super._remove(key);
}
int _computeHashCode(var key) {
@@ -995,17 +1035,25 @@
var nums = _nums;
return (nums == null) ? false : _hasTableEntry(nums, object);
} else {
- var rest = _rest;
- if (rest == null) return false;
- var bucket = _getBucket(rest, object);
- return _findBucketIndex(bucket, object) >= 0;
+ return _contains(object);
}
}
+ bool _contains(Object object) {
+ var rest = _rest;
+ if (rest == null) return false;
+ var bucket = _getBucket(rest, object);
+ return _findBucketIndex(bucket, object) >= 0;
+ }
+
E lookup(Object object) {
if (_isStringElement(object) || _isNumericElement(object)) {
return this.contains(object) ? object : null;
}
+ return _lookup(object);
+ }
+
+ E _lookup(Object object) {
var rest = _rest;
if (rest == null) return null;
var bucket = _getBucket(rest, object);
@@ -1025,23 +1073,27 @@
if (nums == null) _nums = nums = _newHashTable();
return _addHashTableEntry(nums, element);
} else {
- var rest = _rest;
- if (rest == null) _rest = rest = _newHashTable();
- var hash = _computeHashCode(element);
- var bucket = JS('var', '#[#]', rest, hash);
- if (bucket == null) {
- _setTableEntry(rest, hash, JS('var', '[#]', element));
- } else {
- int index = _findBucketIndex(bucket, element);
- if (index >= 0) return false;
- JS('void', '#.push(#)', bucket, element);
- }
- _length++;
- _elements = null;
- return true;
+ return _add(element);
}
}
+ bool _add(E element) {
+ var rest = _rest;
+ if (rest == null) _rest = rest = _newHashTable();
+ var hash = _computeHashCode(element);
+ var bucket = JS('var', '#[#]', rest, hash);
+ if (bucket == null) {
+ _setTableEntry(rest, hash, JS('var', '[#]', element));
+ } else {
+ int index = _findBucketIndex(bucket, element);
+ if (index >= 0) return false;
+ JS('void', '#.push(#)', bucket, element);
+ }
+ _length++;
+ _elements = null;
+ return true;
+ }
+
void addAll(Iterable<E> objects) {
for (E each in objects) {
add(each);
@@ -1054,22 +1106,26 @@
} else if (_isNumericElement(object)) {
return _removeHashTableEntry(_nums, object);
} else {
- var rest = _rest;
- if (rest == null) return false;
- var bucket = _getBucket(rest, object);
- int index = _findBucketIndex(bucket, object);
- if (index < 0) return false;
- // TODO(kasperl): Consider getting rid of the bucket list when
- // the length reaches zero.
- _length--;
- _elements = null;
- // TODO(kasperl): It would probably be faster to move the
- // element to the end and reduce the length of the bucket list.
- JS('void', '#.splice(#, 1)', bucket, index);
- return true;
+ return _remove(object);
}
}
+ bool _remove(Object object) {
+ var rest = _rest;
+ if (rest == null) return false;
+ var bucket = _getBucket(rest, object);
+ int index = _findBucketIndex(bucket, object);
+ if (index < 0) return false;
+ // TODO(kasperl): Consider getting rid of the bucket list when
+ // the length reaches zero.
+ _length--;
+ _elements = null;
+ // TODO(kasperl): It would probably be faster to move the
+ // element to the end and reduce the length of the bucket list.
+ JS('void', '#.splice(#, 1)', bucket, index);
+ return true;
+ }
+
void removeAll(Iterable<Object> objectsToRemove) {
for (var each in objectsToRemove) {
remove(each);
@@ -1275,19 +1331,21 @@
return JS('int', '# & 0x3ffffff', _hasher(element));
}
+ bool add(E object) => super._add(object);
+
bool contains(Object object) {
if (!_validKey(object)) return false;
- return super.contains(object);
+ return super._contains(object);
}
E lookup(Object object) {
if (!_validKey(object)) return null;
- return super.lookup(object);
+ return super._lookup(object);
}
bool remove(Object object) {
if (!_validKey(object)) return false;
- return super.remove(object);
+ return super._remove(object);
}
bool containsAll(Iterable<Object> elements) {
@@ -1300,7 +1358,7 @@
void removeAll(Iterable<Object> elements) {
for (Object element in elements) {
if (_validKey(element)) {
- super.remove(element);
+ super._remove(element);
}
}
}
@@ -1428,26 +1486,34 @@
LinkedHashSetCell cell = _getTableEntry(nums, object);
return cell != null;
} else {
- var rest = _rest;
- if (rest == null) return false;
- var bucket = _getBucket(rest, object);
- return _findBucketIndex(bucket, object) >= 0;
+ return _contains(object);
}
}
+ bool _contains(Object object) {
+ var rest = _rest;
+ if (rest == null) return false;
+ var bucket = _getBucket(rest, object);
+ return _findBucketIndex(bucket, object) >= 0;
+ }
+
E lookup(Object object) {
if (_isStringElement(object) || _isNumericElement(object)) {
return this.contains(object) ? object : null;
} else {
- var rest = _rest;
- if (rest == null) return null;
- var bucket = _getBucket(rest, object);
- var index = _findBucketIndex(bucket, object);
- if (index < 0) return null;
- return bucket[index]._element;
+ return _lookup(object);
}
}
+ E _lookup(Object object) {
+ var rest = _rest;
+ if (rest == null) return null;
+ var bucket = _getBucket(rest, object);
+ var index = _findBucketIndex(bucket, object);
+ if (index < 0) return null;
+ return bucket[index]._element;
+ }
+
void forEach(void action(E element)) {
LinkedHashSetCell cell = _first;
int modifications = _modifications;
@@ -1481,23 +1547,27 @@
if (nums == null) _nums = nums = _newHashTable();
return _addHashTableEntry(nums, element);
} else {
- var rest = _rest;
- if (rest == null) _rest = rest = _newHashTable();
- var hash = _computeHashCode(element);
- var bucket = JS('var', '#[#]', rest, hash);
- if (bucket == null) {
- LinkedHashSetCell cell = _newLinkedCell(element);
- _setTableEntry(rest, hash, JS('var', '[#]', cell));
- } else {
- int index = _findBucketIndex(bucket, element);
- if (index >= 0) return false;
- LinkedHashSetCell cell = _newLinkedCell(element);
- JS('void', '#.push(#)', bucket, cell);
- }
- return true;
+ return _add(element);
}
}
+ bool _add(E element) {
+ var rest = _rest;
+ if (rest == null) _rest = rest = _newHashTable();
+ var hash = _computeHashCode(element);
+ var bucket = JS('var', '#[#]', rest, hash);
+ if (bucket == null) {
+ LinkedHashSetCell cell = _newLinkedCell(element);
+ _setTableEntry(rest, hash, JS('var', '[#]', cell));
+ } else {
+ int index = _findBucketIndex(bucket, element);
+ if (index >= 0) return false;
+ LinkedHashSetCell cell = _newLinkedCell(element);
+ JS('void', '#.push(#)', bucket, cell);
+ }
+ return true;
+ }
+
void addAll(Iterable<E> objects) {
for (E object in objects) {
add(object);
@@ -1510,19 +1580,23 @@
} else if (_isNumericElement(object)) {
return _removeHashTableEntry(_nums, object);
} else {
- var rest = _rest;
- if (rest == null) return false;
- var bucket = _getBucket(rest, object);
- int index = _findBucketIndex(bucket, object);
- if (index < 0) return false;
- // Use splice to remove the [cell] element at the index and
- // unlink it.
- LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
- _unlinkCell(cell);
- return true;
+ return _remove(object);
}
}
+ bool _remove(Object object) {
+ var rest = _rest;
+ if (rest == null) return false;
+ var bucket = _getBucket(rest, object);
+ int index = _findBucketIndex(bucket, object);
+ if (index < 0) return false;
+ // Use splice to remove the [cell] element at the index and
+ // unlink it.
+ LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
+ _unlinkCell(cell);
+ return true;
+ }
+
void removeAll(Iterable objectsToRemove) {
for (var each in objectsToRemove) {
remove(each);
@@ -1734,19 +1808,21 @@
return JS('int', '# & 0x3ffffff', _hasher(element));
}
+ bool add(E element) => super._add(element);
+
bool contains(Object object) {
if (!_validKey(object)) return false;
- return super.contains(object);
+ return super._contains(object);
}
E lookup(Object object) {
if (!_validKey(object)) return null;
- return super.lookup(object);
+ return super._lookup(object);
}
bool remove(Object object) {
if (!_validKey(object)) return false;
- return super.remove(object);
+ return super._remove(object);
}
bool containsAll(Iterable<Object> elements) {
@@ -1759,7 +1835,7 @@
void removeAll(Iterable<Object> elements) {
for (Object element in elements) {
if (_validKey(element)) {
- super.remove(element);
+ super._remove(element);
}
}
}
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index 58ab7a9..e054097 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -3222,39 +3222,34 @@
return JS('String', 'init.getIsolateTag(#)', name);
}
-typedef Future<bool> LoadLibraryFunctionType();
+typedef Future<Null> LoadLibraryFunctionType();
LoadLibraryFunctionType _loadLibraryWrapper(String loadId) {
return () => loadDeferredLibrary(loadId);
}
-final Map<String, Future<bool>> _loadedLibraries = <String, Future<bool>>{};
+final Map<String, Future<Null>> _loadedLibraries = <String, Future<Null>>{};
Future<bool> loadDeferredLibrary(String loadId, [String uri]) {
- List hunkNames = new List();
- if (JS('bool', '\$.libraries_to_load[#] === undefined', loadId)) {
- return new Future(() => false);
- }
- for (int index = 0;
- index < JS('int', '\$.libraries_to_load[#].length', loadId);
- ++index) {
- hunkNames.add(JS('String', '\$.libraries_to_load[#][#]',
- loadId, index));
- }
- Iterable<Future<bool>> allLoads =
- hunkNames.map((hunkName) => _loadHunk(hunkName, uri));
- return Future.wait(allLoads).then((results) {
- return results.any((x) => x);
+
+ List<List<String>> hunkLists = JS('JSExtendableArray|Null',
+ '\$.libraries_to_load[#]', loadId);
+ if (hunkLists == null) return new Future.value(null);
+
+ return Future.forEach(hunkLists, (hunkNames) {
+ Iterable<Future<Null>> allLoads =
+ hunkNames.map((hunkName) => _loadHunk(hunkName, uri));
+ return Future.wait(allLoads).then((_) => null);
});
}
-Future<bool> _loadHunk(String hunkName, String uri) {
+Future<Null> _loadHunk(String hunkName, String uri) {
// TODO(ahe): Validate libraryName. Kasper points out that you want
// to be able to experiment with the effect of toggling @DeferLoad,
// so perhaps we should silently ignore "bad" library names.
- Future<bool> future = _loadedLibraries[hunkName];
+ Future<Null> future = _loadedLibraries[hunkName];
if (future != null) {
- return future.then((_) => false);
+ return future.then((_) => null);
}
if (uri == null) {
@@ -3266,7 +3261,7 @@
if (Primitives.isJsshell || Primitives.isD8) {
// TODO(ahe): Move this code to a JavaScript command helper script that is
// not included in generated output.
- return _loadedLibraries[hunkName] = new Future<bool>(() {
+ return _loadedLibraries[hunkName] = new Future<Null>(() {
try {
// Create a new function to avoid getting access to current function
// context.
@@ -3274,14 +3269,14 @@
} catch (error, stackTrace) {
throw new DeferredLoadException("Loading $uri failed.");
}
- return true;
+ return null;
});
} else if (isWorker()) {
// We are in a web worker. Load the code with an XMLHttpRequest.
- return _loadedLibraries[hunkName] = new Future<bool>(() {
- Completer completer = new Completer<bool>();
+ return _loadedLibraries[hunkName] = new Future<Null>(() {
+ Completer completer = new Completer<Null>();
enterJsAsync();
- Future<bool> leavingFuture = completer.future.whenComplete(() {
+ Future<Null> leavingFuture = completer.future.whenComplete(() {
leaveJsAsync();
});
@@ -3306,7 +3301,7 @@
new DeferredLoadException("Evaluating $uri failed."));
return;
}
- completer.complete(true);
+ completer.complete(null);
}, 1));
var fail = convertDartClosureToJS((event) {
@@ -3320,15 +3315,15 @@
});
}
// We are in a dom-context.
- return _loadedLibraries[hunkName] = new Future<bool>(() {
- Completer completer = new Completer<bool>();
+ return _loadedLibraries[hunkName] = new Future<Null>(() {
+ Completer completer = new Completer<Null>();
// Inject a script tag.
var script = JS('', 'document.createElement("script")');
JS('', '#.type = "text/javascript"', script);
JS('', '#.src = #', script, uri);
JS('', '#.addEventListener("load", #, false)',
script, convertDartClosureToJS((event) {
- completer.complete(true);
+ completer.complete(null);
}, 1));
JS('', '#.addEventListener("error", #, false)',
script, convertDartClosureToJS((event) {
diff --git a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
index 71944d9..ca71b15 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
@@ -43,6 +43,9 @@
final BuildEnvironment _environment;
final BarbackSettings _settings;
+ /// Whether source maps should be generated for the compiled JS.
+ bool get _generateSourceMaps => _settings.mode != BarbackMode.RELEASE;
+
Dart2JSTransformer.withSettings(this._environment, this._settings) {
var invalidOptions = _settings.configuration.keys.toSet()
.difference(_validOptions);
@@ -88,8 +91,10 @@
Future declareOutputs(DeclaringTransform transform) {
var primaryId = transform.primaryId;
transform.declareOutput(primaryId.addExtension(".js"));
- transform.declareOutput(primaryId.addExtension(".js.map"));
transform.declareOutput(primaryId.addExtension(".precompiled.js"));
+ if (_generateSourceMaps) {
+ transform.declareOutput(primaryId.addExtension(".js.map"));
+ }
return new Future.value();
}
@@ -115,7 +120,7 @@
/// Run the dart2js compiler.
Future _doCompilation(Transform transform) {
var provider = new _BarbackCompilerProvider(_environment, transform,
- generateSourceMaps: _settings.mode != BarbackMode.RELEASE);
+ generateSourceMaps: _generateSourceMaps);
// Create a "path" to the entrypoint script. The entrypoint may not actually
// be on disk, but this gives dart2js a root to resolve relative paths
diff --git a/sdk/lib/async/deferred_load.dart b/sdk/lib/async/deferred_load.dart
index 43982ce..a770071 100644
--- a/sdk/lib/async/deferred_load.dart
+++ b/sdk/lib/async/deferred_load.dart
@@ -34,13 +34,10 @@
/**
* Ensure that [libraryName] has been loaded.
*
- * The value of the returned future is true if this invocation of
- * [load] caused the library to be loaded.
- *
* If the library fails to load, the Future will complete with a
* DeferredLoadException.
*/
- external Future<bool> load();
+ external Future<Null> load();
}
/**
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 05c33f6..a262c21 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -461,21 +461,24 @@
List<int> readAsBytesSync() {
var opened = openSync();
- var data;
- var length = opened.lengthSync();
- if (length == 0) {
- // May be character device, try to read it in chunks.
- var builder = new BytesBuilder(copy: false);
- do {
- data = opened.readSync(_BLOCK_SIZE);
- if (data.length > 0) builder.add(data);
- } while (data.length == _BLOCK_SIZE);
- data = builder.takeBytes();
- } else {
- data = opened.readSync(length);
+ try {
+ var data;
+ var length = opened.lengthSync();
+ if (length == 0) {
+ // May be character device, try to read it in chunks.
+ var builder = new BytesBuilder(copy: false);
+ do {
+ data = opened.readSync(_BLOCK_SIZE);
+ if (data.length > 0) builder.add(data);
+ } while (data.length == _BLOCK_SIZE);
+ data = builder.takeBytes();
+ } else {
+ data = opened.readSync(length);
+ }
+ return data;
+ } finally {
+ opened.closeSync();
}
- opened.closeSync();
- return data;
}
String _tryDecode(List<int> bytes, Encoding encoding) {
@@ -539,9 +542,12 @@
{FileMode mode: FileMode.WRITE,
bool flush: false}) {
RandomAccessFile opened = openSync(mode: mode);
- opened.writeFromSync(bytes, 0, bytes.length);
- if (flush) opened.flushSync();
- opened.closeSync();
+ try {
+ opened.writeFromSync(bytes, 0, bytes.length);
+ if (flush) opened.flushSync();
+ } finally {
+ opened.closeSync();
+ }
}
Future<File> writeAsString(String contents,
diff --git a/tests/_chrome/sample_test.dart b/tests/_chrome/sample_test.dart
index eb51d5c..85448ff 100644
--- a/tests/_chrome/sample_test.dart
+++ b/tests/_chrome/sample_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library sample_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:_chrome' as _chrome;
main() {
diff --git a/tests/benchmark_smoke/benchmark_smoke_test.dart b/tests/benchmark_smoke/benchmark_smoke_test.dart
index c79275a..70647c8 100644
--- a/tests/benchmark_smoke/benchmark_smoke_test.dart
+++ b/tests/benchmark_smoke/benchmark_smoke_test.dart
@@ -8,9 +8,9 @@
import 'benchmark_lib.dart';
import 'dart:async';
import 'dart:html';
-import '../../pkg/expect/lib/expect.dart';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:expect/expect.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
void main() {
useHtmlConfiguration();
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 7020203a..a0c96a0 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -69,8 +69,8 @@
LibTest/isolate/ReceivePort/toSendPort_A01_t01: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/ReceivePort/toSendPort_A01_t03: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/SendPort/call_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t03: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/SendPort/send_A02_t04: Fail # co19-roll r706: Please triage this failure.
+LibTest/isolate/SendPort/send_A02_t03: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/SendPort/send_A02_t05: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/SendPort/send_A02_t06: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/SendPort/send_A03_t01: Fail # co19-roll r706: Please triage this failure.
@@ -131,9 +131,9 @@
LibTest/typed_data/Float32x4/lessThan_A01_t01: Skip # co19 issue 656
LibTest/typed_data/Float32x4/lessThanOrEqual_A01_t01: Skip # co19 issue 656
-#co19 issue 677
WebPlatformTest1/shadow-dom/*: CompileTimeError # co19 issue 677
WebPlatformTest1/html-templates/*: CompileTimeError # co19 issue 677
+WebPlatformTest1/custom-elements/*: Pass, StaticWarning # Issue 18095.
# co19 roll to r706: Please triage all these issues.
Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t03: StaticWarning # co19-roll r706: Please triage this failure.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 03414b4..3e8938e 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -70,6 +70,8 @@
LibTest/isolate/SendPort/send_A01_t02: CompileTimeError # co19-roll r706: Please triage this failure
LibTest/isolate/SendPort/send_A01_t03: CompileTimeError # co19-roll r706: Please triage this failure
LibTest/isolate/Isolate/spawnUri_A02_t01: RuntimeError, Pass # Dart issue 15617
+LibTest/math/Rectangle/boundingBox_A01_t01: RuntimeError, Pass # co19-roll 706: Please triage this failure.
+LibTest/math/MutableRectangle/boundingBox_A01_t01: RuntimeError, Pass # co19-roll 706: Please triage this failure.
[ $compiler == dart2js && $runtime != ie9 ]
LibTest/typed_data/ByteData/ByteData_A02_t01: fail # co19-roll r576: Please triage this failure
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index 20a663c..88a5680 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -67,24 +67,36 @@
.contains(inputElement));
var hunksToLoad = compiler.deferredLoadTask.hunksToLoad;
- var hunksLib1 = new Set.from(hunksToLoad["lib1"].map((o) => o.name));
- var hunksLib2 = new Set.from(hunksToLoad["lib2"].map((o) => o.name));
- var hunksLib4_1 = new Set.from(hunksToLoad["lib4_1"].map((o) => o.name));
- var hunksLib4_2 = new Set.from(hunksToLoad["lib4_2"].map((o) => o.name));
- Expect.equals(hunksLib1.length, 2);
- Expect.isTrue(hunksLib1.contains("lib1"));
- Expect.isTrue(hunksLib1.contains("lib1_lib2") ||
- hunksLib1.contains("lib2_lib1"));
- Expect.isTrue(hunksLib2.contains("lib2"));
- Expect.equals(hunksLib2.length, 2);
- Expect.isTrue(hunksLib2.contains("lib1_lib2") ||
- hunksLib1.contains("lib2_lib1"));
- Expect.isTrue(hunksLib4_1.contains("lib4_1"));
- Expect.equals(hunksLib4_1.length, 1);
- Expect.isTrue(hunksLib4_2.contains("lib4_2"));
- Expect.equals(hunksLib4_2.length, 1);
- Expect.equals(hunksToLoad["main"], null);
+ mapToNames(id) {
+ return hunksToLoad[id].map((l) {
+ return new Set.from(l.map((o) => o.name));
+ }).toList();
+ }
+
+ var hunksLib1 = mapToNames("lib1");
+ var hunksLib2 = mapToNames("lib2");
+ var hunksLib4_1 = mapToNames("lib4_1");
+ var hunksLib4_2 = mapToNames("lib4_2");
+ Expect.equals(hunksLib1.length, 2);
+ Expect.equals(hunksLib1[0].length, 1);
+ Expect.equals(hunksLib1[1].length, 1);
+ Expect.isTrue(hunksLib1[0].contains("lib1_lib2") ||
+ hunksLib1[0].contains("lib2_lib1"));
+ Expect.isTrue(hunksLib1[1].contains("lib1"));
+ Expect.equals(hunksLib2.length, 2);
+ Expect.equals(hunksLib2[0].length, 1);
+ Expect.equals(hunksLib2[1].length, 1);
+ Expect.isTrue(hunksLib2[0].contains("lib1_lib2") ||
+ hunksLib2[0].contains("lib2_lib1"));
+ Expect.isTrue(hunksLib2[1].contains("lib2"));
+ Expect.equals(hunksLib4_1.length, 1);
+ Expect.equals(hunksLib4_1[0].length, 1);
+ Expect.isTrue(hunksLib4_1[0].contains("lib4_1"));
+ Expect.equals(hunksLib4_2.length, 1);
+ Expect.equals(hunksLib4_2[0].length, 1);
+ Expect.isTrue(hunksLib4_2[0].contains("lib4_2"));
+ Expect.equals(hunksToLoad["main"], null);
}));
}
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 20e16cf..e050421 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -58,7 +58,7 @@
// 2. Some code was refactored, and there are more methods.
// Either situation could be problematic, but in situation 2, it is often
// acceptable to increase [expectedMethodCount] a little.
- int expectedMethodCount = 376;
+ int expectedMethodCount = 377;
Expect.isTrue(
generatedCode.length <= expectedMethodCount,
'Too many compiled methods: '
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
index ae4964a..5df6c73 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
@@ -19,8 +19,7 @@
Expect.isNull(x);
int counter = 0;
asyncStart();
- lazy.load().then((bool didLoad) {
- Expect.isTrue(didLoad);
+ lazy.load().then((_) {
Expect.equals(1, ++counter);
print('deferred_class_library was loaded');
x = new lib.MyClass();
@@ -30,8 +29,7 @@
Expect.equals(0, counter);
Expect.isNull(x);
asyncStart();
- lazy.load().then((bool didLoad) {
- Expect.isFalse(didLoad);
+ lazy.load().then((_) {
Expect.equals(2, ++counter);
print('deferred_class_library was loaded');
x = new lib.MyClass();
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
index cb67911..21c4a7d 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
@@ -13,8 +13,7 @@
main() {
asyncStart();
- lazy.load().then((bool didLoad) {
- Expect.isTrue(didLoad);
+ lazy.load().then((_) {
Expect.equals(499, lib.C1.value);
asyncEnd();
});
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
index 876dfa3..afc2b24 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
@@ -13,8 +13,7 @@
main() {
asyncStart();
- lazy.load().then((bool didLoad) {
- Expect.isTrue(didLoad);
+ lazy.load().then((_) {
Expect.equals(499, lib.C1.value);
Expect.equals(99, lib.C2[0].value);
Expect.equals(42, lib.foo().value);
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
index e22d11b..ee4b0d6 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
@@ -13,8 +13,7 @@
main() {
asyncStart();
- lazy.load().then((bool didLoad) {
- Expect.isTrue(didLoad);
+ lazy.load().then((_) {
// Only Gee2.n888 to make sure no other constant pulls in its super.
Expect.equals(888, new lib.Gee2.n888().value);
asyncEnd();
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
index 09b27f0..aad0c57 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
@@ -28,8 +28,7 @@
Expect.throws(readFoo, isNoSuchMethodError);
int counter = 0;
asyncStart();
- lazy.load().then((bool didLoad) {
- Expect.isTrue(didLoad);
+ lazy.load().then((_) {
Expect.equals(1, ++counter);
print('lazy was loaded');
Expect.equals(42, lib.foo('b'));
@@ -38,8 +37,7 @@
});
Expect.equals(0, counter);
asyncStart();
- lazy.load().then((bool didLoad) {
- Expect.isFalse(didLoad);
+ lazy.load().then((_) {
Expect.equals(2, ++counter);
print('lazy was loaded');
Expect.equals(42, lib.foo('b'));
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib1.dart b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib1.dart
new file mode 100644
index 0000000..3f72583
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib1.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "deferred_overlapping_lib3.dart";
+
+class C1 extends C3 {}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib2.dart b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib2.dart
new file mode 100644
index 0000000..fdd2af1
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "deferred_overlapping_lib3.dart";
+
+class C2 extends C3 {}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib3.dart b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib3.dart
new file mode 100644
index 0000000..80d5c9e
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib3.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C3 {}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_overlapping_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_test.dart
new file mode 100644
index 0000000..0e5ee2b
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "deferred_overlapping_lib1.dart" deferred as lib1;
+import "deferred_overlapping_lib2.dart" deferred as lib2;
+
+// lib1.C1 and lib2.C2 has a shared base class It will go in its own hunk.
+// If lib1 or lib2s hunks are loaded before the common hunk, the program
+// will fail because the base class does not exist.
+void main() {
+ lib1.loadLibrary().then((_) {
+ var a = new lib1.C1();
+ lib2.loadLibrary().then((_) {
+ var b = new lib2.C2();
+ });
+ });
+}
\ No newline at end of file
diff --git a/tests/html/async_test.dart b/tests/html/async_test.dart
index a0d99fb..4144098 100644
--- a/tests/html/async_test.dart
+++ b/tests/html/async_test.dart
@@ -1,7 +1,7 @@
library async_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:async';
import 'dart:isolate';
diff --git a/tests/html/audiobuffersourcenode_test.dart b/tests/html/audiobuffersourcenode_test.dart
index 15bba1e..c55c08c 100644
--- a/tests/html/audiobuffersourcenode_test.dart
+++ b/tests/html/audiobuffersourcenode_test.dart
@@ -1,6 +1,6 @@
library AudioBufferSourceNodeTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:web_audio';
main() {
diff --git a/tests/html/audiocontext_test.dart b/tests/html/audiocontext_test.dart
index dda3d25..81e4e5f 100644
--- a/tests/html/audiocontext_test.dart
+++ b/tests/html/audiocontext_test.dart
@@ -1,6 +1,6 @@
library AudioContextTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
import 'dart:web_audio';
diff --git a/tests/html/audioelement_test.dart b/tests/html/audioelement_test.dart
index 0b518e0..2828596 100644
--- a/tests/html/audioelement_test.dart
+++ b/tests/html/audioelement_test.dart
@@ -1,6 +1,6 @@
library AudioElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/b_element_test.dart b/tests/html/b_element_test.dart
index 1cd71b6..f208e6d 100644
--- a/tests/html/b_element_test.dart
+++ b/tests/html/b_element_test.dart
@@ -1,6 +1,6 @@
library BElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/blob_constructor_test.dart b/tests/html/blob_constructor_test.dart
index ea3ec66..41461f5 100644
--- a/tests/html/blob_constructor_test.dart
+++ b/tests/html/blob_constructor_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library blob_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/cache_test.dart b/tests/html/cache_test.dart
index 5f110b2..d81770f 100644
--- a/tests/html/cache_test.dart
+++ b/tests/html/cache_test.dart
@@ -1,6 +1,6 @@
library CacheTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/callbacks_test.dart b/tests/html/callbacks_test.dart
index e1aa779..c6e9498 100644
--- a/tests/html/callbacks_test.dart
+++ b/tests/html/callbacks_test.dart
@@ -1,6 +1,6 @@
library CallbacksTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/canvas_pixel_array_type_alias_test.dart b/tests/html/canvas_pixel_array_type_alias_test.dart
index 7cdbb24..f346850 100644
--- a/tests/html/canvas_pixel_array_type_alias_test.dart
+++ b/tests/html/canvas_pixel_array_type_alias_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file
library CanvasTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/canvas_test.dart b/tests/html/canvas_test.dart
index 307be78..d83c1d9 100644
--- a/tests/html/canvas_test.dart
+++ b/tests/html/canvas_test.dart
@@ -1,6 +1,6 @@
library CanvasTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/canvasrenderingcontext2d_test.dart b/tests/html/canvasrenderingcontext2d_test.dart
index fa4402f..73eeeb7a 100644
--- a/tests/html/canvasrenderingcontext2d_test.dart
+++ b/tests/html/canvasrenderingcontext2d_test.dart
@@ -2,11 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library canvas_rendering_context_2d_test; import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+library canvas_rendering_context_2d_test;
+
import 'dart:html';
import 'dart:math';
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+
// Some rounding errors in the browsers.
checkPixel(List<int> pixel, List<int> expected) {
expect(pixel[0], closeTo(expected[0], 2));
diff --git a/tests/html/cdata_test.dart b/tests/html/cdata_test.dart
index b23a397..424d52f 100644
--- a/tests/html/cdata_test.dart
+++ b/tests/html/cdata_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file
library cdata_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
diff --git a/tests/html/client_rect_test.dart b/tests/html/client_rect_test.dart
index 9bc233f..b9c9bb54 100644
--- a/tests/html/client_rect_test.dart
+++ b/tests/html/client_rect_test.dart
@@ -1,6 +1,6 @@
library ClientRectTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/cross_frame_test.dart b/tests/html/cross_frame_test.dart
index cc852f8..b5a37f6 100644
--- a/tests/html/cross_frame_test.dart
+++ b/tests/html/cross_frame_test.dart
@@ -1,6 +1,6 @@
library CrossFrameTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/crypto_test.dart b/tests/html/crypto_test.dart
index b4992a3..41666a5 100644
--- a/tests/html/crypto_test.dart
+++ b/tests/html/crypto_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library crypto_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/css_rule_list_test.dart b/tests/html/css_rule_list_test.dart
index 21224df..ade3833 100644
--- a/tests/html/css_rule_list_test.dart
+++ b/tests/html/css_rule_list_test.dart
@@ -1,6 +1,6 @@
library CssRuleListTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/css_test.dart b/tests/html/css_test.dart
index 01a05d0..deda6c5 100644
--- a/tests/html/css_test.dart
+++ b/tests/html/css_test.dart
@@ -1,6 +1,6 @@
library CssTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/cssstyledeclaration_test.dart b/tests/html/cssstyledeclaration_test.dart
index 12a5f15..38bdbf3 100644
--- a/tests/html/cssstyledeclaration_test.dart
+++ b/tests/html/cssstyledeclaration_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library CssStyleDeclarationTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:async';
import 'utils.dart';
diff --git a/tests/html/custom_tags_test.dart b/tests/html/custom_tags_test.dart
index 6295af5..5f5457b 100644
--- a/tests/html/custom_tags_test.dart
+++ b/tests/html/custom_tags_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library custom_tags_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'utils.dart';
diff --git a/tests/html/dart_object_local_storage_test.dart b/tests/html/dart_object_local_storage_test.dart
index 32050d3..22add6a 100644
--- a/tests/html/dart_object_local_storage_test.dart
+++ b/tests/html/dart_object_local_storage_test.dart
@@ -1,6 +1,6 @@
library DartObjectLocalStorageTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
// TODO(vsm): Rename this to wrapper_caching_test or similar. It's
diff --git a/tests/html/datalistelement_test.dart b/tests/html/datalistelement_test.dart
index 8af53c1..2fd9fa8 100644
--- a/tests/html/datalistelement_test.dart
+++ b/tests/html/datalistelement_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library datalistelement_dataview_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/document_test.dart b/tests/html/document_test.dart
index 355a126..7e69c1f 100644
--- a/tests/html/document_test.dart
+++ b/tests/html/document_test.dart
@@ -1,6 +1,6 @@
library DocumentTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/documentfragment_test.dart b/tests/html/documentfragment_test.dart
index 62d4b73..b09c04d 100644
--- a/tests/html/documentfragment_test.dart
+++ b/tests/html/documentfragment_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library DocumentFragmentTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'util.dart';
import 'dart:html';
diff --git a/tests/html/dom_constructors_test.dart b/tests/html/dom_constructors_test.dart
index c2f8ad0..a2bcf55 100644
--- a/tests/html/dom_constructors_test.dart
+++ b/tests/html/dom_constructors_test.dart
@@ -1,6 +1,6 @@
library DOMConstructorsTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/domparser_test.dart b/tests/html/domparser_test.dart
index a6f6246..61ecf86 100644
--- a/tests/html/domparser_test.dart
+++ b/tests/html/domparser_test.dart
@@ -1,6 +1,6 @@
library DOMParserTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart b/tests/html/dromaeo_noop/dromaeo_smoke.dart
index 68c5dc4..0a1e13e 100644
--- a/tests/html/dromaeo_noop/dromaeo_smoke.dart
+++ b/tests/html/dromaeo_noop/dromaeo_smoke.dart
@@ -3,13 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
library dromaeo;
+
import 'dart:async';
-import 'dart:html';
import "dart:convert";
-import '../../../samples/third_party/dromaeo/common/common.dart';
+import 'dart:html';
import 'dart:math' as Math;
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import '../../../samples/third_party/dromaeo/common/common.dart';
+
part '../../../samples/third_party/dromaeo/tests/Common.dart';
part '../../../samples/third_party/dromaeo/tests/RunnerSuite.dart';
diff --git a/tests/html/dromaeo_smoke_test.dart b/tests/html/dromaeo_smoke_test.dart
index 51ebf35..2f71f9b6 100644
--- a/tests/html/dromaeo_smoke_test.dart
+++ b/tests/html/dromaeo_smoke_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library dromaeo;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import '../../samples/third_party/dromaeo/web/Dromaeo.dart' as originalTest;
import 'dart:html';
import 'dart:async';
diff --git a/tests/html/element_add_test.dart b/tests/html/element_add_test.dart
index 2ec51db..0f9cc2e 100644
--- a/tests/html/element_add_test.dart
+++ b/tests/html/element_add_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file
library ElementAddTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'util.dart';
import 'dart:html';
diff --git a/tests/html/element_classes_test.dart b/tests/html/element_classes_test.dart
index 9ef9860..cf6a35c 100644
--- a/tests/html/element_classes_test.dart
+++ b/tests/html/element_classes_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library ElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:collection';
import 'dart:html';
diff --git a/tests/html/element_constructor_1_test.dart b/tests/html/element_constructor_1_test.dart
index 74a40fa..b53e366 100644
--- a/tests/html/element_constructor_1_test.dart
+++ b/tests/html/element_constructor_1_test.dart
@@ -7,8 +7,8 @@
// element_constructor_foo_test.dart file.
library ElementConstructorTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/element_offset_test.dart b/tests/html/element_offset_test.dart
index f402642..10102d3 100644
--- a/tests/html/element_offset_test.dart
+++ b/tests/html/element_offset_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library element_offset_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:async';
import 'dart:html';
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 936eb68..6f75758 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library ElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:async';
import 'dart:html';
import 'dart:svg' as svg;
diff --git a/tests/html/element_types_test.dart b/tests/html/element_types_test.dart
index 960bb16..df0c488 100644
--- a/tests/html/element_types_test.dart
+++ b/tests/html/element_types_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library element_types;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/event_customevent_test.dart b/tests/html/event_customevent_test.dart
index f9168a9..cbda1a7 100644
--- a/tests/html/event_customevent_test.dart
+++ b/tests/html/event_customevent_test.dart
@@ -4,8 +4,8 @@
library EventCustomEventTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:js' as js;
diff --git a/tests/html/event_test.dart b/tests/html/event_test.dart
index e8f743b..9b7893a 100644
--- a/tests/html/event_test.dart
+++ b/tests/html/event_test.dart
@@ -4,8 +4,8 @@
library EventTest;
import "package:expect/expect.dart";
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
// TODO(nweiz): Make this private to testEvents when Frog supports closures with
diff --git a/tests/html/exceptions_test.dart b/tests/html/exceptions_test.dart
index b8f26ab..d7603b9 100644
--- a/tests/html/exceptions_test.dart
+++ b/tests/html/exceptions_test.dart
@@ -1,6 +1,6 @@
library ExceptionsTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/fileapi_test.dart b/tests/html/fileapi_test.dart
index b276e76..edc6fa2 100644
--- a/tests/html/fileapi_test.dart
+++ b/tests/html/fileapi_test.dart
@@ -1,6 +1,6 @@
library fileapi;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:async';
diff --git a/tests/html/form_data_test.dart b/tests/html/form_data_test.dart
index 0435f86..6132c16 100644
--- a/tests/html/form_data_test.dart
+++ b/tests/html/form_data_test.dart
@@ -4,8 +4,8 @@
library FormDataTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
void main() {
diff --git a/tests/html/form_element_test.dart b/tests/html/form_element_test.dart
index b7d030c..b3b06c3 100644
--- a/tests/html/form_element_test.dart
+++ b/tests/html/form_element_test.dart
@@ -4,8 +4,8 @@
library FormElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
void main() {
diff --git a/tests/html/geolocation_test.dart b/tests/html/geolocation_test.dart
index e6dd1b3..c49e531 100644
--- a/tests/html/geolocation_test.dart
+++ b/tests/html/geolocation_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library geolocation_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/hidden_dom_1_test.dart b/tests/html/hidden_dom_1_test.dart
index b2a51bd..120136b5 100644
--- a/tests/html/hidden_dom_1_test.dart
+++ b/tests/html/hidden_dom_1_test.dart
@@ -1,6 +1,6 @@
library HiddenDom1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
// Test that the dart:html API does not leak native jsdom methods:
diff --git a/tests/html/hidden_dom_2_test.dart b/tests/html/hidden_dom_2_test.dart
index 1c1bad5..e8abc4e 100644
--- a/tests/html/hidden_dom_2_test.dart
+++ b/tests/html/hidden_dom_2_test.dart
@@ -1,6 +1,6 @@
library HiddenDom2Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
// Test that the dart:html API does not leak native jsdom methods:
diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart
index f8fd547..893fb77 100644
--- a/tests/html/history_test.dart
+++ b/tests/html/history_test.dart
@@ -1,6 +1,6 @@
library HistoryTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:async';
diff --git a/tests/html/htmlcollection_test.dart b/tests/html/htmlcollection_test.dart
index 296f30b..9781c3c9 100644
--- a/tests/html/htmlcollection_test.dart
+++ b/tests/html/htmlcollection_test.dart
@@ -1,6 +1,6 @@
library ElementListTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
// Test that List<Element> implements List<T>
diff --git a/tests/html/htmlelement_test.dart b/tests/html/htmlelement_test.dart
index f4157ed..fd22c13 100644
--- a/tests/html/htmlelement_test.dart
+++ b/tests/html/htmlelement_test.dart
@@ -1,6 +1,6 @@
library ElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'utils.dart';
diff --git a/tests/html/htmloptionscollection_test.dart b/tests/html/htmloptionscollection_test.dart
index 9a633ab..cc5166a 100644
--- a/tests/html/htmloptionscollection_test.dart
+++ b/tests/html/htmloptionscollection_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library HTMLOptionsCollectionTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/indexeddb_1_test.dart b/tests/html/indexeddb_1_test.dart
index a099bf0..f4422de 100644
--- a/tests/html/indexeddb_1_test.dart
+++ b/tests/html/indexeddb_1_test.dart
@@ -1,6 +1,6 @@
library IndexedDB1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dart:math' as math;
diff --git a/tests/html/indexeddb_2_test.dart b/tests/html/indexeddb_2_test.dart
index efd4d80..7350559 100644
--- a/tests/html/indexeddb_2_test.dart
+++ b/tests/html/indexeddb_2_test.dart
@@ -1,6 +1,6 @@
library IndexedDB1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dart:indexed_db' as idb;
diff --git a/tests/html/indexeddb_3_test.dart b/tests/html/indexeddb_3_test.dart
index d3030dc..c5034c4 100644
--- a/tests/html/indexeddb_3_test.dart
+++ b/tests/html/indexeddb_3_test.dart
@@ -1,6 +1,6 @@
library IndexedDB3Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dart:indexed_db';
diff --git a/tests/html/indexeddb_4_test.dart b/tests/html/indexeddb_4_test.dart
index 76e264e..3761301 100644
--- a/tests/html/indexeddb_4_test.dart
+++ b/tests/html/indexeddb_4_test.dart
@@ -1,6 +1,6 @@
library IndexedDB4Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dart:indexed_db';
diff --git a/tests/html/indexeddb_5_test.dart b/tests/html/indexeddb_5_test.dart
index 786cb0b..cbf77d1 100644
--- a/tests/html/indexeddb_5_test.dart
+++ b/tests/html/indexeddb_5_test.dart
@@ -1,6 +1,6 @@
library IndexedDB1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dart:indexed_db' as idb;
diff --git a/tests/html/input_element_test.dart b/tests/html/input_element_test.dart
index 43f245c..02fb062 100644
--- a/tests/html/input_element_test.dart
+++ b/tests/html/input_element_test.dart
@@ -1,6 +1,6 @@
library input_element_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
void check(InputElement element, String type, [bool supported = true]) {
diff --git a/tests/html/instance_of_test.dart b/tests/html/instance_of_test.dart
index 6e70809..da664db 100644
--- a/tests/html/instance_of_test.dart
+++ b/tests/html/instance_of_test.dart
@@ -1,6 +1,6 @@
library InstanceOfTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/interactive_test.dart b/tests/html/interactive_test.dart
index e8d70ff..82a879b 100644
--- a/tests/html/interactive_test.dart
+++ b/tests/html/interactive_test.dart
@@ -6,8 +6,8 @@
import 'dart:async';
import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'utils.dart';
diff --git a/tests/html/isolates_test.dart b/tests/html/isolates_test.dart
index fa703d2..9c07ed0 100644
--- a/tests/html/isolates_test.dart
+++ b/tests/html/isolates_test.dart
@@ -1,6 +1,6 @@
library IsolatesTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:async';
import 'dart:html';
import 'dart:convert';
diff --git a/tests/html/js_interop_1_test.dart b/tests/html/js_interop_1_test.dart
index 7ba954d..c7165c4 100644
--- a/tests/html/js_interop_1_test.dart
+++ b/tests/html/js_interop_1_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file
library JsInterop1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
injectSource(code) {
diff --git a/tests/html/js_test.dart b/tests/html/js_test.dart
index ba5d007..081ab02 100644
--- a/tests/html/js_test.dart
+++ b/tests/html/js_test.dart
@@ -10,8 +10,8 @@
import 'dart:indexed_db' show IdbFactory, KeyRange;
import 'dart:js';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
_injectJs() {
final script = new ScriptElement();
diff --git a/tests/html/keyboard_event_test.dart b/tests/html/keyboard_event_test.dart
index a29f02f..8fca793 100644
--- a/tests/html/keyboard_event_test.dart
+++ b/tests/html/keyboard_event_test.dart
@@ -1,6 +1,6 @@
library KeyboardEventTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
// Test that we are correctly determining keyCode and charCode uniformly across
diff --git a/tests/html/localstorage_test.dart b/tests/html/localstorage_test.dart
index f2823a2..3e92b10 100644
--- a/tests/html/localstorage_test.dart
+++ b/tests/html/localstorage_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library LocalStorageTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/location_test.dart b/tests/html/location_test.dart
index d5c8e5e..e274a2a0 100644
--- a/tests/html/location_test.dart
+++ b/tests/html/location_test.dart
@@ -1,6 +1,6 @@
library LocationTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/media_stream_test.dart b/tests/html/media_stream_test.dart
index 2c6635a..602c199 100644
--- a/tests/html/media_stream_test.dart
+++ b/tests/html/media_stream_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library media_stream_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/messageevent_test.dart b/tests/html/messageevent_test.dart
index c2c832a..a436189 100644
--- a/tests/html/messageevent_test.dart
+++ b/tests/html/messageevent_test.dart
@@ -1,6 +1,6 @@
library SerializedScriptValueTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/mouse_event_test.dart b/tests/html/mouse_event_test.dart
index 4be967b..dcd442f 100644
--- a/tests/html/mouse_event_test.dart
+++ b/tests/html/mouse_event_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library mouse_event_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/mutationobserver_test.dart b/tests/html/mutationobserver_test.dart
index 8804ab6..e2de7e0 100644
--- a/tests/html/mutationobserver_test.dart
+++ b/tests/html/mutationobserver_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library mutationobserver_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
// Due to https://code.google.com/p/chromium/issues/detail?id=329103
diff --git a/tests/html/native_gc_test.dart b/tests/html/native_gc_test.dart
index 9aaf72e..5931cc8 100644
--- a/tests/html/native_gc_test.dart
+++ b/tests/html/native_gc_test.dart
@@ -1,6 +1,6 @@
library NativeGCTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
var testEvent = new EventStreamProvider<Event>('test');
diff --git a/tests/html/navigator_test.dart b/tests/html/navigator_test.dart
index abbcc4e..2bc5cc8 100644
--- a/tests/html/navigator_test.dart
+++ b/tests/html/navigator_test.dart
@@ -1,6 +1,6 @@
library NavigatorTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/node_test.dart b/tests/html/node_test.dart
index d142c60..3dd5679 100644
--- a/tests/html/node_test.dart
+++ b/tests/html/node_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library NodeTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:svg' as svg;
diff --git a/tests/html/non_instantiated_is_test.dart b/tests/html/non_instantiated_is_test.dart
index bf1ece1..b226ea7 100644
--- a/tests/html/non_instantiated_is_test.dart
+++ b/tests/html/non_instantiated_is_test.dart
@@ -6,8 +6,8 @@
// checks of native classes that are not instantiated.
import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
var a = [new Object()];
diff --git a/tests/html/performance_api_test.dart b/tests/html/performance_api_test.dart
index 7ba9d9c..f4f1d28 100644
--- a/tests/html/performance_api_test.dart
+++ b/tests/html/performance_api_test.dart
@@ -1,6 +1,6 @@
library PerformanceApiTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/postmessage_structured_test.dart b/tests/html/postmessage_structured_test.dart
index c586fd9..9ceeebc 100644
--- a/tests/html/postmessage_structured_test.dart
+++ b/tests/html/postmessage_structured_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file
library postmessage_js_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:collection'; // SplayTreeMap
import 'dart:typed_data';
diff --git a/tests/html/query_test.dart b/tests/html/query_test.dart
index 33fabc5..bffe0d9 100644
--- a/tests/html/query_test.dart
+++ b/tests/html/query_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library QueryTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/queryall_test.dart b/tests/html/queryall_test.dart
index 7b910c5..be4e67b 100644
--- a/tests/html/queryall_test.dart
+++ b/tests/html/queryall_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file
library NodeListTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/range_test.dart b/tests/html/range_test.dart
index 3792afd..5c2028d 100644
--- a/tests/html/range_test.dart
+++ b/tests/html/range_test.dart
@@ -1,8 +1,8 @@
library range_test;
import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
main() {
useHtmlIndividualConfiguration();
diff --git a/tests/html/request_animation_frame_test.dart b/tests/html/request_animation_frame_test.dart
index f240b70..32e22c8 100644
--- a/tests/html/request_animation_frame_test.dart
+++ b/tests/html/request_animation_frame_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library RequestAnimationFrameTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/rtc_test.dart b/tests/html/rtc_test.dart
index df096ab0..e55e79f 100644
--- a/tests/html/rtc_test.dart
+++ b/tests/html/rtc_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library RealTimeCommunicationTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/selectelement_test.dart b/tests/html/selectelement_test.dart
index 81eb13d..b56912c 100644
--- a/tests/html/selectelement_test.dart
+++ b/tests/html/selectelement_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library selectelement_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/serialized_script_value_test.dart b/tests/html/serialized_script_value_test.dart
index af673b6..16c8b43 100644
--- a/tests/html/serialized_script_value_test.dart
+++ b/tests/html/serialized_script_value_test.dart
@@ -1,6 +1,6 @@
library SerializedScriptValueTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'utils.dart';
diff --git a/tests/html/shadow_dom_test.dart b/tests/html/shadow_dom_test.dart
index d9ec86a..323d0e2 100644
--- a/tests/html/shadow_dom_test.dart
+++ b/tests/html/shadow_dom_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library ShadowDOMTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/shadowroot_test.dart b/tests/html/shadowroot_test.dart
index 04e0b5e..c3ac8d9 100644
--- a/tests/html/shadowroot_test.dart
+++ b/tests/html/shadowroot_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library ShadowRootTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/speechrecognition_test.dart b/tests/html/speechrecognition_test.dart
index cf3a4fa..16fd9de 100644
--- a/tests/html/speechrecognition_test.dart
+++ b/tests/html/speechrecognition_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library speech_recognition_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/storage_test.dart b/tests/html/storage_test.dart
index 5f09e20..b68e9d4 100644
--- a/tests/html/storage_test.dart
+++ b/tests/html/storage_test.dart
@@ -1,6 +1,6 @@
library StorageTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/streams_test.dart b/tests/html/streams_test.dart
index 7a3b2ff..edd77e7 100644
--- a/tests/html/streams_test.dart
+++ b/tests/html/streams_test.dart
@@ -1,6 +1,6 @@
library streams_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:async';
import 'dart:html';
diff --git a/tests/html/table_test.dart b/tests/html/table_test.dart
index 5c1144f..7432e5d 100644
--- a/tests/html/table_test.dart
+++ b/tests/html/table_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library TableTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/touchevent_test.dart b/tests/html/touchevent_test.dart
index 8d90e5b..fba6e61 100644
--- a/tests/html/touchevent_test.dart
+++ b/tests/html/touchevent_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library touch_event_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/transferables_test.dart b/tests/html/transferables_test.dart
index d2ad13f..f2aa905 100644
--- a/tests/html/transferables_test.dart
+++ b/tests/html/transferables_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library TransferableTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/transition_event_test.dart b/tests/html/transition_event_test.dart
index 646061f..399e2ec 100644
--- a/tests/html/transition_event_test.dart
+++ b/tests/html/transition_event_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file
library transition_event_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:async';
diff --git a/tests/html/typed_arrays_1_test.dart b/tests/html/typed_arrays_1_test.dart
index a2de291..c3eb811 100644
--- a/tests/html/typed_arrays_1_test.dart
+++ b/tests/html/typed_arrays_1_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library TypedArrays1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typed_arrays_2_test.dart b/tests/html/typed_arrays_2_test.dart
index e223ea7..5a0d83a 100644
--- a/tests/html/typed_arrays_2_test.dart
+++ b/tests/html/typed_arrays_2_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library TypedArrays2Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typed_arrays_3_test.dart b/tests/html/typed_arrays_3_test.dart
index 53f0b8d..efa4e17 100644
--- a/tests/html/typed_arrays_3_test.dart
+++ b/tests/html/typed_arrays_3_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library TypedArrays3Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typed_arrays_4_test.dart b/tests/html/typed_arrays_4_test.dart
index 11a39e8..9f00357 100644
--- a/tests/html/typed_arrays_4_test.dart
+++ b/tests/html/typed_arrays_4_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library TypedArrays4Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typed_arrays_5_test.dart b/tests/html/typed_arrays_5_test.dart
index 3c6948d..db149f6 100644
--- a/tests/html/typed_arrays_5_test.dart
+++ b/tests/html/typed_arrays_5_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library typed_arrays_5_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typed_arrays_arraybuffer_test.dart b/tests/html/typed_arrays_arraybuffer_test.dart
index af75ab9..07541c8 100644
--- a/tests/html/typed_arrays_arraybuffer_test.dart
+++ b/tests/html/typed_arrays_arraybuffer_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library typed_arrays_arraybuffer_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typed_arrays_dataview_test.dart b/tests/html/typed_arrays_dataview_test.dart
index 83b076f..a56aecd 100644
--- a/tests/html/typed_arrays_dataview_test.dart
+++ b/tests/html/typed_arrays_dataview_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library typed_arrays_dataview_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typed_arrays_range_checks_test.dart b/tests/html/typed_arrays_range_checks_test.dart
index 2338ac1..1eb2222 100644
--- a/tests/html/typed_arrays_range_checks_test.dart
+++ b/tests/html/typed_arrays_range_checks_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library TypedArraysRangeCheckTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typed_arrays_simd_test.dart b/tests/html/typed_arrays_simd_test.dart
index b0e3176..0e3d780 100644
--- a/tests/html/typed_arrays_simd_test.dart
+++ b/tests/html/typed_arrays_simd_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library TypedArraysSimdTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/typing_test.dart b/tests/html/typing_test.dart
index c0a8389..68ba294 100644
--- a/tests/html/typing_test.dart
+++ b/tests/html/typing_test.dart
@@ -1,6 +1,6 @@
library TypingTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/unknownelement_test.dart b/tests/html/unknownelement_test.dart
index 6632974..21ba1ef 100644
--- a/tests/html/unknownelement_test.dart
+++ b/tests/html/unknownelement_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file
library UnknownElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/uri_test.dart b/tests/html/uri_test.dart
index af2ae82..90798849 100644
--- a/tests/html/uri_test.dart
+++ b/tests/html/uri_test.dart
@@ -2,8 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/url_test.dart b/tests/html/url_test.dart
index 6852fc6..69f55ad 100644
--- a/tests/html/url_test.dart
+++ b/tests/html/url_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library url_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
diff --git a/tests/html/util.dart b/tests/html/util.dart
index 25bb502..52735f2 100644
--- a/tests/html/util.dart
+++ b/tests/html/util.dart
@@ -5,7 +5,7 @@
library test.html.util;
import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
void expectUnsupported(f) => expect(f, throwsUnsupportedError);
diff --git a/tests/html/webgl_1_test.dart b/tests/html/webgl_1_test.dart
index ae276eb..d6e6f1f 100644
--- a/tests/html/webgl_1_test.dart
+++ b/tests/html/webgl_1_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library web_gl_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
import 'dart:web_gl';
diff --git a/tests/html/websocket_test.dart b/tests/html/websocket_test.dart
index 2e02761..f8ba1ba 100644
--- a/tests/html/websocket_test.dart
+++ b/tests/html/websocket_test.dart
@@ -1,6 +1,6 @@
library WebSocketTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart
index b67d0aa..a2c3905 100644
--- a/tests/html/websql_test.dart
+++ b/tests/html/websql_test.dart
@@ -2,8 +2,8 @@
import 'dart:async';
import 'dart:html';
import 'dart:web_sql';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
Future<SqlTransaction> transaction(SqlDatabase db) {
final completer = new Completer<SqlTransaction>.sync();
diff --git a/tests/html/wheelevent_test.dart b/tests/html/wheelevent_test.dart
index d733a94..8223573 100644
--- a/tests/html/wheelevent_test.dart
+++ b/tests/html/wheelevent_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library wheel_event_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
diff --git a/tests/html/window_eq_test.dart b/tests/html/window_eq_test.dart
index 718011c..6995a90 100644
--- a/tests/html/window_eq_test.dart
+++ b/tests/html/window_eq_test.dart
@@ -1,6 +1,6 @@
library WindowEqualityTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/window_mangling_test.dart b/tests/html/window_mangling_test.dart
index 33704b3..f1a8b38 100644
--- a/tests/html/window_mangling_test.dart
+++ b/tests/html/window_mangling_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library WindowManglingTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html' as dom;
// Defined in dom.Window.
diff --git a/tests/html/window_nosuchmethod_test.dart b/tests/html/window_nosuchmethod_test.dart
index 0027d1e..93cb592 100644
--- a/tests/html/window_nosuchmethod_test.dart
+++ b/tests/html/window_nosuchmethod_test.dart
@@ -4,8 +4,8 @@
library WindowNSMETest;
import "package:expect/expect.dart";
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html' as dom;
// Not defined in dom.Window.
diff --git a/tests/html/window_test.dart b/tests/html/window_test.dart
index edf822d..51ccdfd 100644
--- a/tests/html/window_test.dart
+++ b/tests/html/window_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library WindowTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/worker_test.dart b/tests/html/worker_test.dart
index 018d7fc..896781f 100644
--- a/tests/html/worker_test.dart
+++ b/tests/html/worker_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library worker_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/html/xhr_cross_origin_test.dart b/tests/html/xhr_cross_origin_test.dart
index 16e35cd..4a5935c 100644
--- a/tests/html/xhr_cross_origin_test.dart
+++ b/tests/html/xhr_cross_origin_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library XHRCrossOriginTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import "dart:convert";
diff --git a/tests/html/xsltprocessor_test.dart b/tests/html/xsltprocessor_test.dart
index 48d7b10..b645d81 100644
--- a/tests/html/xsltprocessor_test.dart
+++ b/tests/html/xsltprocessor_test.dart
@@ -1,6 +1,6 @@
library XSLTProcessorTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
import 'dart:html';
main() {
diff --git a/tests/isolate/spawn_uri_nested_vm_test.dart b/tests/isolate/spawn_uri_nested_vm_test.dart
index c1b084d..91b413c 100644
--- a/tests/isolate/spawn_uri_nested_vm_test.dart
+++ b/tests/isolate/spawn_uri_nested_vm_test.dart
@@ -8,7 +8,7 @@
// OtherScripts=spawn_uri_nested_child1_vm_isolate.dart spawn_uri_nested_child2_vm_isolate.dart
library NestedSpawnUriLibrary;
import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
main() {
test('isolate fromUri - nested send and reply', () {
diff --git a/tests/isolate/spawn_uri_test.dart b/tests/isolate/spawn_uri_test.dart
index 340170e5..5f64d7d 100644
--- a/tests/isolate/spawn_uri_test.dart
+++ b/tests/isolate/spawn_uri_test.dart
@@ -8,7 +8,7 @@
// OtherScripts=spawn_uri_child_isolate.dart
library spawn_tests;
import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
main() {
test('isolate fromUri - send and reply', () {
diff --git a/tests/isolate/spawn_uri_vm_test.dart b/tests/isolate/spawn_uri_vm_test.dart
index 7fbb20c..e5510a5 100644
--- a/tests/isolate/spawn_uri_vm_test.dart
+++ b/tests/isolate/spawn_uri_vm_test.dart
@@ -8,7 +8,7 @@
// OtherScripts=spawn_uri_child_isolate.dart
library spawn_tests;
import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
main() {
test('isolate fromUri - send and reply', () {
diff --git a/tests/language/const_constructor2_test.dart b/tests/language/const_constructor2_test.dart
new file mode 100644
index 0000000..2ebb00f
--- /dev/null
+++ b/tests/language/const_constructor2_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 14348.
+
+class A<T> {
+ const A();
+}
+
+class B<S> extends A<S> {
+ const B();
+}
+
+class C<U> {
+ final A<U> a;
+
+ const C(A<U> this.a);
+ const C.optional([A<U> this.a]);
+ const C.named({A<U> this.a});
+ const C.untyped(this.a);
+ const C.subtyped(B<U> this.a);
+ const factory C.redirecting(B<U> a) = D;
+}
+
+class D extends C {
+ const D(B b) : super(b);
+}
+
+class E {
+ const factory E.redirecting1(var a) = F<int>;
+ const factory E.redirecting2(var a) = F<int>.redirecting;
+ const factory E.redirecting3(var a) = F<double>.redirecting;
+}
+
+class F<V> implements E {
+ final V field;
+
+ const F(this.field);
+ const factory F.redirecting(V field) = G<int>;
+}
+
+class G<W> implements F {
+ final field;
+ const G(W this.field);
+}
+
+main() {
+ const A<int> a = const B<int>();
+
+ const C c1 = const C(a); /// 01: ok
+ const C c2 = const C.optional(a); /// 02: ok
+ const C c3 = const C.named(a: a); /// 03: ok
+ const C c4 = const C.untyped(a); /// 04: ok
+ const C c5 = const C.subtyped(a); /// 05: ok
+ const C c5m = const C.redirecting(a); /// 06: ok
+
+ const C c6 = const C<int>(a); /// 07: ok
+ const C c7 = const C<int>.optional(a); /// 08: ok
+ const C c8 = const C<int>.named(a: a); /// 09: ok
+ const C c9 = const C<int>.untyped(a); /// 10: ok
+ const C c10 = const C<int>.subtyped(a); /// 11: ok
+ const C c10m = const C<int>.redirecting(a); /// 12: ok
+
+ const C c11 = const C<double>(a); /// 13: static type warning, checked mode compile-time error
+ const C c12 = const C<double>.optional(a); /// 14: static type warning, checked mode compile-time error
+ const C c13 = const C<double>.named(a: a); /// 15: static type warning, checked mode compile-time error
+ const C c14 = const C<double>.untyped(a); /// 16: static type warning, checked mode compile-time error
+ const C c15 = const C<double>.subtyped(a); /// 17: static type warning, checked mode compile-time error
+ const C c15m = const C<double>.redirecting(a); /// 18: static type warning
+
+ const E e1 = const E.redirecting1(0); /// 19: ok
+ const E e2 = const E.redirecting1(''); /// 20: checked mode compile-time error
+ const E e3 = const E.redirecting2(0); /// 21: ok
+ const E e4 = const E.redirecting2(''); /// 22: checked mode compile-time error
+ const E e5 = const E.redirecting3(0); /// 23: ok
+ const E e6 = const E.redirecting3(''); /// 24: checked mode compile-time error
+}
\ No newline at end of file
diff --git a/tests/language/disasssemble_test.dart b/tests/language/disassemble_test.dart
similarity index 100%
rename from tests/language/disasssemble_test.dart
rename to tests/language/disassemble_test.dart
diff --git a/tests/language/function_literals2_test.dart b/tests/language/function_literals2_test.dart
index 3572cbe..15be383 100644
--- a/tests/language/function_literals2_test.dart
+++ b/tests/language/function_literals2_test.dart
@@ -46,6 +46,9 @@
Expect.equals(10, b.n);
Expect.equals(101, (b.f)(10));
+ var c = new C(5);
+ Expect.equals("2*x is 10", c.s);
+
int x = 0;
int y = 1;
// make sure this isn't parsed as a generic type
@@ -73,6 +76,10 @@
B.withZ(z) : f = ((x) { return x * x + 1; }) { n = z; }
}
+class C {
+ String s;
+ C(x) : s = "2*x is ${() { return 2*x; }()}";
+}
main() {
FunctionLiteralsTest.testMain();
}
diff --git a/tests/language/language.status b/tests/language/language.status
index c57acaa..7069ee1 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -39,6 +39,8 @@
deferred_constraints_constants_test/*: Fail, Pass
deferred_shadow_load_library_test: Fail
deferred_closurize_load_library_test: Fail
+override_inheritance_mixed_test/08: Fail # Issue 18124
+override_inheritance_mixed_test/09: Fail # Issue 18124
[ $compiler == none || $compiler == dart2dart]
# These test use the old syntax, and will be phased out.
@@ -69,8 +71,6 @@
[ $compiler == none && $runtime == vm ]
class_keyword_test/02: MissingCompileTimeError # Issue 13627
-override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 16137
-override_inheritance_mixed_test/09: MissingCompileTimeError # Issue 16137
unicode_bom_test: Fail # Issue 16067
@@ -112,8 +112,9 @@
[ $compiler == none && ( $runtime == dartium || $runtime == drt ) ]
typed_message_test: Crash, Fail # Issue 13921, 14400
vm/optimized_guarded_field_isolates_test: Fail # Issue 13921.
-override_inheritance_mixed_test/08: Fail # Issue 16137
-override_inheritance_mixed_test/09: Fail # Issue 16137
+
+[ $compiler == none && $runtime == drt ]
+disassemble_test: Pass, Fail # Issue 18122
[ $compiler == none && $runtime == vm && $arch == mips && $checked ]
generic_instanceof3_test: Pass, Crash # Issue 17440.
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 6f90409..67d84da 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -29,6 +29,8 @@
call_closurization_test: StaticWarning # Issue 17476
+function_literals2_test: Fail # Issue 18137
+
# Please add new failing tests before this line.
# Section below is for invalid tests.
#
@@ -199,10 +201,6 @@
override_inheritance_generic_test/07: MissingStaticWarning # Issue 16135
override_inheritance_generic_test/09: MissingStaticWarning # Issue 16135
-# missing compile-time error for getter/member override
-override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 16136
-override_inheritance_mixed_test/09: MissingCompileTimeError # Issue 16136
-
# flaky override tests
override_inheritance_field_test/33: MissingStaticWarning, Pass # Issue 16498
override_inheritance_field_test/33a: MissingStaticWarning, Pass # Issue 16498
@@ -466,11 +464,6 @@
vm/type_vm_test: StaticWarning
void_type_test: StaticWarning
-# Issue 16392.
-const_constructor2_test/20: MissingStaticWarning # Issue 16392.
-const_constructor2_test/22: MissingStaticWarning # Issue 16392.
-const_constructor2_test/24: MissingStaticWarning # Issue 16392.
-
# Issue 16391. The analyzer handle compile-time error in checked only in these
# cases:
compile_time_constant_checked2_test/01: CompileTimeError # Issue 16391
@@ -490,4 +483,3 @@
deferred_load_library_wrong_args_test/01: Fail
deferred_load_library_wrong_args_test/none: Fail
deferred_load_inval_code_test: Fail
-
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 2cd04c7..6af40b1 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -187,9 +187,11 @@
override_inheritance_no_such_method_test/04: StaticWarning # Issue 16132
override_inheritance_no_such_method_test/05: StaticWarning # Issue 16132
-# unexpected warning for override
-override_inheritance_abstract_test/27: StaticWarning # Issue 16134
-override_inheritance_generic_test/03: StaticWarning # Issue 16134
+# analyzer issue 17983
+override_inheritance_generic_test/08: MissingStaticWarning # Issue 17983
+override_inheritance_field_test/32: MissingStaticWarning # Issue 17983
+override_inheritance_field_test/09: MissingStaticWarning # Issue 17983
+override_inheritance_abstract_test/27: StaticWarning # Issue 17983
# missing warning for override
override_inheritance_generic_test/04: MissingStaticWarning # Issue 16135
@@ -197,10 +199,6 @@
override_inheritance_generic_test/07: MissingStaticWarning # Issue 16135
override_inheritance_generic_test/09: MissingStaticWarning # Issue 16135
-# missing compile-time error for getter/member override
-override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 16136
-override_inheritance_mixed_test/09: MissingCompileTimeError # Issue 16136
-
# flaky override tests
override_inheritance_field_test/33: MissingStaticWarning, Pass # Issue 16498
override_inheritance_field_test/33a: MissingStaticWarning, Pass # Issue 16498
@@ -464,11 +462,6 @@
vm/type_vm_test: StaticWarning
void_type_test: StaticWarning
-# Issue 16392.
-const_constructor2_test/20: MissingStaticWarning # Issue 16392.
-const_constructor2_test/22: MissingStaticWarning # Issue 16392.
-const_constructor2_test/24: MissingStaticWarning # Issue 16392.
-
# Issue 16391. The analyzer handle compile-time error in checked only in these
# cases:
compile_time_constant_checked2_test/01: CompileTimeError # Issue 16391
@@ -488,4 +481,3 @@
deferred_load_library_wrong_args_test/01: Fail
deferred_load_library_wrong_args_test/none: Fail
deferred_load_inval_code_test: Fail
-
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 4b30660..c97ea0b 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,6 +3,9 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2js || $compiler == dart2dart ]
+function_literals2_test: Fail # Issue 18102
+override_inheritance_mixed_test/08: Fail # Issue 18124
+override_inheritance_mixed_test/09: Fail # Issue 18124
bad_constructor_test/05: CompileTimeError # Issue 13669
malformed_test/05: MissingCompileTimeError # Issue 12695
malformed_test/06: MissingCompileTimeError # Issue 12695
diff --git a/tests/language/override_inheritance_mixed_test.dart b/tests/language/override_inheritance_mixed_test.dart
index 08f8f34..199b466 100644
--- a/tests/language/override_inheritance_mixed_test.dart
+++ b/tests/language/override_inheritance_mixed_test.dart
@@ -13,8 +13,8 @@
var member5; /// 05: ok
var member6; /// 06: static type warning
get member7; /// 07: static type warning
- get member8; /// 08: compile-time error
- get member9; /// 09: compile-time error
+ get member8; /// 08: static type warning
+ get member9; /// 09: static type warning
}
abstract class J {
diff --git a/tests/language/regress_14348_test.dart b/tests/language/regress_14348_test.dart
new file mode 100644
index 0000000..75c5308
--- /dev/null
+++ b/tests/language/regress_14348_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 14348.
+
+import "package:collection/equality.dart";
+
+main() {
+ const Equality<Iterable> eq = const UnorderedIterableEquality();
+ const Equality<Map<dynamic,Iterable>> mapeq =
+ const MapEquality<dynamic, dynamic>(values: eq);
+}
\ No newline at end of file
diff --git a/tests/lib/async/deferred/deferred_api_test.dart b/tests/lib/async/deferred/deferred_api_test.dart
deleted file mode 100644
index f138935..0000000
--- a/tests/lib/async/deferred/deferred_api_test.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that that the basic API for deferred/lazy loading works. This
-// test deliberately does not test that the deferred elements throw a
-// NoSuchMethodError before the deferred library is loaded. This
-// makes it possible to pass this test without having implemented
-// deferred loading correctly.
-
-import "package:expect/expect.dart";
-import 'dart:async';
-
-@lazy
-import 'deferred_api_library.dart' as lib;
-
-const lazy = const DeferredLibrary('deferred_api_library');
-
-main() {
- print('unittest-suite-wait-for-done');
-
- int counter = 0;
- lazy.load().then((bool didLoad) {
- Expect.isTrue(didLoad);
- Expect.equals(1, ++counter);
- Expect.equals(42, lib.foo('b'));
- print('lazy was loaded');
- });
- Expect.equals(0, counter);
- lazy.load().then((bool didLoad) {
- Expect.isFalse(didLoad);
- Expect.equals(2, ++counter);
- Expect.equals(42, lib.foo('b'));
- print('lazy was loaded');
- print('unittest-suite-success');
- });
- Expect.equals(0, counter);
-}
diff --git a/tests/lib/async/deferred/deferred_fail_to_load_test.dart b/tests/lib/async/deferred/deferred_fail_to_load_test.dart
index 31ecee3..dbecad1 100644
--- a/tests/lib/async/deferred/deferred_fail_to_load_test.dart
+++ b/tests/lib/async/deferred/deferred_fail_to_load_test.dart
@@ -4,7 +4,7 @@
import 'package:unittest/unittest.dart';
@a import 'deferred_in_isolate_lib.dart' as lib1;
-@b import 'deferred_api_library.dart' as lib2;
+@b import 'deferred_library.dart' as lib2;
const a = const DeferredLibrary("lib1");
const b = const DeferredLibrary("NonExistingFile", uri: "wrong/wrong.js");
diff --git a/tests/lib/async/deferred/deferred_in_isolate_test.dart b/tests/lib/async/deferred/deferred_in_isolate_test.dart
index bdd8b06..2ced417 100644
--- a/tests/lib/async/deferred/deferred_in_isolate_test.dart
+++ b/tests/lib/async/deferred/deferred_in_isolate_test.dart
@@ -3,7 +3,7 @@
import 'package:unittest/unittest.dart';
@a import 'deferred_in_isolate_lib.dart' as lib1;
-@b import 'deferred_api_library.dart' as lib2;
+@b import 'deferred_library.dart' as lib2;
const a = const DeferredLibrary("lib1");
const b = const DeferredLibrary("NonExistingFile", uri: "wrong/");
diff --git a/tests/lib/async/deferred/deferred_api_library.dart b/tests/lib/async/deferred/deferred_library.dart
similarity index 87%
rename from tests/lib/async/deferred/deferred_api_library.dart
rename to tests/lib/async/deferred/deferred_library.dart
index b590770..186a11a 100644
--- a/tests/lib/async/deferred/deferred_api_library.dart
+++ b/tests/lib/async/deferred/deferred_library.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// Imported by deferred_api_test.dart.
-
library deferred_api_library;
foo(x) {
diff --git a/tests/lib/collection/hash_map_test.dart b/tests/lib/collection/hash_map_test.dart
new file mode 100644
index 0000000..f0f1d54
--- /dev/null
+++ b/tests/lib/collection/hash_map_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+
+void main() {
+ // Test customized maps.
+ // Regression test for issue http://dartbug.com/18109
+
+ hash(s) => s.toLowerCase().hashCode;
+ equals(a, b) => a.toLowerCase() == b.toLowerCase();
+
+ for (var m in [
+ new HashMap<String,int>(equals: equals, hashCode: hash),
+ new LinkedHashMap<String,int>(equals: equals, hashCode: hash),
+ ]) {
+ m["Abel"] = 42;
+ for (var key in ["Abel", "abel", "ABEL", "Abel"]) {
+ Expect.isTrue(m.containsKey(key), "contains $key in ${m.runtimeType} $m");
+ Expect.equals(42, m[key], "get $key in ${m.runtimeType} $m");
+ Expect.equals(42, m.remove(key), "remove $key in ${m.runtimeType} $m");
+ m[key] = 42;
+ }
+ }
+
+ abshash(n) => n.abs();
+ abseq(a, b) => a.abs() == b.abs();
+ for (var m in [
+ new HashMap<int,int>(equals: abseq, hashCode: abshash),
+ new LinkedHashMap<int,int>(equals: abseq, hashCode: abshash),
+ ]) {
+ m[1] = 42;
+ for (var key in [1, -1, 1]) {
+ Expect.isTrue(m.containsKey(key), "contains $key in ${m.runtimeType} $m");
+ Expect.equals(42, m[key], "get $key in ${m.runtimeType} $m");
+ Expect.equals(42, m.remove(key), "remove $key in ${m.runtimeType} $m");
+ m[key] = 42;
+ }
+ }
+}
diff --git a/tests/lib/collection/hash_set_test.dart b/tests/lib/collection/hash_set_test.dart
new file mode 100644
index 0000000..ab03284
--- /dev/null
+++ b/tests/lib/collection/hash_set_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+
+void main() {
+ // Test customized sets.
+ // Regression test for issue http://dartbug.com/18109
+
+ hash(s) => s.toLowerCase().hashCode;
+ equals(a, b) => a.toLowerCase() == b.toLowerCase();
+
+ for (var m in [
+ new HashSet<String>(equals: equals, hashCode: hash),
+ new LinkedHashSet<String>(equals: equals, hashCode: hash),
+ ]) {
+ m.add("Abel");
+ var prev = "Abel";
+ for (var key in ["Abel", "abel", "ABEL", "Abel"]) {
+ Expect.isTrue(m.contains(key), "contains $key in ${m.runtimeType} $m");
+ Expect.equals(prev, m.lookup(key), "lookup $key in ${m.runtimeType} $m");
+ Expect.isTrue(m.remove(key), "remove $key in ${m.runtimeType} $m");
+ m.add(key);
+ prev = key;
+ }
+ }
+
+ abshash(n) => n.abs();
+ abseq(a, b) => a.abs() == b.abs();
+ for (var m in [
+ new HashSet<int>(equals: abseq, hashCode: abshash),
+ new LinkedHashSet<int>(equals: abseq, hashCode: abshash),
+ ]) {
+ m.add(1);
+ var prev = 1;
+ for (var key in [1, -1, 1]) {
+ Expect.isTrue(m.contains(key), "contains $key in ${m.runtimeType} $m");
+ Expect.equals(prev, m.lookup(key), "lookup $key in ${m.runtimeType} $m");
+ Expect.isTrue(m.remove(key), "remove $key in ${m.runtimeType} $m");
+ m.add(key);
+ prev = key;
+ }
+ }
+}
diff --git a/tests/lib/mirrors/library_uri_io_test.dart b/tests/lib/mirrors/library_uri_io_test.dart
index c44ff1b..25b2dc6 100644
--- a/tests/lib/mirrors/library_uri_io_test.dart
+++ b/tests/lib/mirrors/library_uri_io_test.dart
@@ -8,7 +8,7 @@
import 'dart:mirrors';
import 'dart:io';
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
class Class {
}
diff --git a/tests/lib/mirrors/library_uri_package_test.dart b/tests/lib/mirrors/library_uri_package_test.dart
index db1ceea..30fcd96 100644
--- a/tests/lib/mirrors/library_uri_package_test.dart
+++ b/tests/lib/mirrors/library_uri_package_test.dart
@@ -8,7 +8,7 @@
import 'dart:mirrors';
import 'package:args/args.dart';
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
testLibraryUri(var value, Uri expectedUri) {
var valueMirror = reflect(value);
diff --git a/tools/VERSION b/tools/VERSION
index 759bb9d..2a1d14e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 4
PATCH 0
-PRERELEASE 7
-PRERELEASE_PATCH 13
+PRERELEASE 1
+PRERELEASE_PATCH 0
diff --git a/tools/create_debian_packages.py b/tools/create_debian_packages.py
index 4f31dfb..d739dfd 100755
--- a/tools/create_debian_packages.py
+++ b/tools/create_debian_packages.py
@@ -10,11 +10,12 @@
# binary packages.
import optparse
+import platform
import sys
import tarfile
import subprocess
import utils
-
+import os
from os.path import join, exists, abspath
from shutil import copyfile
@@ -30,7 +31,7 @@
result.add_option("--out_dir",
default=None,
help="Where to put the packages.")
-
+
return result
def RunBuildPackage(opt, cwd):
@@ -49,7 +50,7 @@
tarroot = 'dart-%s' % version
origtarname = 'dart_%s.orig.tar.gz' % version
- if not exists(join(out_dir, tarball)):
+ if not exists(tarball):
print 'Source tarball not found'
return -1
@@ -85,6 +86,7 @@
amd64_package = [
'%s-1_amd64.deb' % debbase
]
+
for name in source_package:
copyfile(join(temp_dir, name), join(out_dir, name))
for name in i386_package:
@@ -102,9 +104,13 @@
tar_filename = options.tar_filename
if not options.out_dir:
out_dir = join(DART_DIR, utils.GetBuildDir(HOST_OS, HOST_OS))
- if not options.tar_filename:
- raise Exception('Please specify the input filename.')
- BuildDebianPackage(options.tar_filename, options.out_dir)
+
+ if not tar_filename:
+ tar_filename = join(DART_DIR,
+ utils.GetBuildDir(HOST_OS, HOST_OS),
+ 'dart-%s.tar.gz' % utils.GetVersion())
+
+ BuildDebianPackage(tar_filename, out_dir)
if __name__ == '__main__':
sys.exit(Main())
diff --git a/tools/create_tarball.py b/tools/create_tarball.py
index 58679e0..1604ef7 100755
--- a/tools/create_tarball.py
+++ b/tools/create_tarball.py
@@ -155,10 +155,13 @@
global verbose
verbose = True
- if not options.tar_filename:
- raise Exception('Please specify an output filename')
+ tar_filename = options.tar_filename
+ if not tar_filename:
+ tar_filename = join(DART_DIR,
+ utils.GetBuildDir(HOST_OS, HOST_OS),
+ 'dart-%s.tar.gz' % utils.GetVersion())
- CreateTarball(options.tar_filename)
+ CreateTarball(tar_filename)
if __name__ == '__main__':
sys.exit(Main())
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index ed530cc..a3d59b9 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -670,8 +670,9 @@
}
Command _getUniqueCommand(Command command) {
- // All Command classes have hashCode/operator==, so we check if this command
- // has already been build, if so we return the cached one, otherwise we
+ // All Command classes implement hashCode and operator==.
+ // We check if this command has already been built.
+ // If so, we return the cached one. Otherwise we
// store the one given as [command] argument.
var cachedCommand = _cachedCommands[command];
if (cachedCommand != null) {
@@ -1674,6 +1675,69 @@
/**
+ * An OutputLog records the output from a test, but truncates it if
+ * it is longer than MAX_HEAD characters, and just keeps the head and
+ * the last TAIL_LENGTH characters of the output.
+ */
+class OutputLog {
+ static const int MAX_HEAD = 100 * 1024;
+ static const int TAIL_LENGTH = 10 * 1024;
+ List<int> head = <int>[];
+ List<int> tail;
+ List<int> complete;
+ bool dataDropped = false;
+
+ OutputLog();
+
+ void add(List<int> data) {
+ if (complete != null) {
+ throw new StateError("Cannot add to OutputLog after calling toList");
+ }
+ if (tail == null) {
+ head.addAll(data);
+ if (head.length > MAX_HEAD) {
+ tail = head.sublist(MAX_HEAD);
+ head.length = MAX_HEAD;
+ }
+ } else {
+ tail.addAll(data);
+ }
+ if (tail != null && tail.length > 2 * TAIL_LENGTH) {
+ tail = _truncatedTail();
+ dataDropped = true;
+ }
+ }
+
+ List<int> _truncatedTail() =>
+ tail.length > TAIL_LENGTH ?
+ tail.sublist(tail.length - TAIL_LENGTH) :
+ tail;
+
+ List<int> toList() {
+ if (complete == null) {
+ complete = head;
+ if (dataDropped) {
+ complete.addAll("""
+
+*****************************************************************************
+
+Data removed due to excessive length
+
+*****************************************************************************
+
+""".codeUnits);
+ complete.addAll(_truncatedTail());
+ } else if (tail != null) {
+ complete.addAll(tail);
+ }
+ head = null;
+ tail = null;
+ }
+ return complete;
+ }
+}
+
+/**
* A RunningProcess actually runs a test, getting the command lines from
* its [TestCase], starting the test process (and first, a compilation
* process if the TestCase is a [BrowserTestCase]), creating a timeout
@@ -1690,8 +1754,8 @@
DateTime startTime;
Timer timeoutTimer;
int pid;
- List<int> stdout = <int>[];
- List<int> stderr = <int>[];
+ OutputLog stdout = new OutputLog();
+ OutputLog stderr = new OutputLog();
bool compilationSkipped = false;
Completer<CommandOutput> completer;
@@ -1814,8 +1878,8 @@
command,
exitCode,
timedOut,
- stdout,
- stderr,
+ stdout.toList(),
+ stderr.toList(),
new DateTime.now().difference(startTime),
compilationSkipped,
pid);
@@ -1823,8 +1887,8 @@
}
StreamSubscription _drainStream(Stream<List<int>> source,
- List<int> destination) {
- return source.listen(destination.addAll);
+ OutputLog destination) {
+ return source.listen(destination.add);
}
Map<String, String> _createProcessEnvironment() {
@@ -1875,8 +1939,8 @@
Function _processExitHandler;
bool _currentlyRunning = false;
- List<int> _testStdout;
- List<int> _testStderr;
+ OutputLog _testStdout;
+ OutputLog _testStderr;
String _status;
DateTime _startTime;
Timer _timer;
@@ -1932,8 +1996,8 @@
void doStartTest(Command command, int timeout) {
_startTime = new DateTime.now();
- _testStdout = [];
- _testStderr = [];
+ _testStdout = new OutputLog();
+ _testStderr = new OutputLog();
_status = null;
_stdoutCompleter = new Completer();
_stderrCompleter = new Completer();
@@ -1963,8 +2027,8 @@
var output = createCommandOutput(_command,
exitCode,
(outcome == "TIMEOUT"),
- _testStdout,
- _testStderr,
+ _testStdout.toList(),
+ _testStderr.toList(),
new DateTime.now().difference(_startTime),
false);
assert(_completer != null);
@@ -2020,8 +2084,8 @@
} else if (line.startsWith('>>> ')) {
throw new Exception("Unexpected command from batch runner: '$line'.");
} else {
- _testStdout.addAll(encodeUtf8(line));
- _testStdout.addAll("\n".codeUnits);
+ _testStdout.add(encodeUtf8(line));
+ _testStdout.add("\n".codeUnits);
}
if (_status != null) {
_stdoutSubscription.pause();
@@ -2040,8 +2104,8 @@
_stderrSubscription.pause();
_stderrCompleter.complete(null);
} else {
- _testStderr.addAll(encodeUtf8(line));
- _testStderr.addAll("\n".codeUnits);
+ _testStderr.add(encodeUtf8(line));
+ _testStderr.add("\n".codeUnits);
}
});
_stderrSubscription.pause();