Version 0.7.6.0
svn merge -r 27697:27984 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@27991 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/dart.gyp b/dart.gyp
index 12d8604..5ea8faa 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -198,9 +198,7 @@
{
'target_name': 'samples',
'type': 'none',
- 'dependencies': [
- 'samples/openglui/openglui.gyp:openglui_sample',
- ],
+ 'dependencies': [],
'conditions': [
['OS!="android"', {
'dependencies': [
diff --git a/pkg/analyzer_experimental/bin/analyzer.dart b/pkg/analyzer_experimental/bin/analyzer.dart
index d3c59f3..6c96907 100644
--- a/pkg/analyzer_experimental/bin/analyzer.dart
+++ b/pkg/analyzer_experimental/bin/analyzer.dart
@@ -13,6 +13,7 @@
import 'package:analyzer_experimental/src/generated/engine.dart';
import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/java_core.dart' show JavaSystem;
import 'package:analyzer_experimental/options.dart';
import 'package:analyzer_experimental/src/analyzer_impl.dart';
@@ -27,7 +28,20 @@
return _runAnalyzer(options);
});
} else {
+ int startTime = JavaSystem.currentTimeMillis();
+
ErrorSeverity result = _runAnalyzer(options);
+
+ if (options.perf) {
+ int totalTime = JavaSystem.currentTimeMillis() - startTime;
+ print("scan:${PerformanceStatistics.scan.result}");
+ print("parse:${PerformanceStatistics.parse.result}");
+ print("resolve:${PerformanceStatistics.resolve.result}");
+ print("errors:${PerformanceStatistics.errors.result}");
+ print("hints:${PerformanceStatistics.hints.result}");
+ print("total:$totalTime");
+ }
+
exit(result.ordinal);
}
}
diff --git a/pkg/analyzer_experimental/bin/formatter.dart b/pkg/analyzer_experimental/bin/formatter.dart
index 504646c..02dc8f1 100755
--- a/pkg/analyzer_experimental/bin/formatter.dart
+++ b/pkg/analyzer_experimental/bin/formatter.dart
@@ -4,6 +4,7 @@
// 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:convert';
import 'dart:io';
import 'dart:utf';
@@ -17,7 +18,9 @@
final dartFileRegExp = new RegExp(r'^[^.].*\.dart$', caseSensitive: false);
final argParser = _initArgParser();
+bool machineFormat;
bool overwriteFileContents;
+Selection selection;
const followLinks = false;
main() {
@@ -26,8 +29,9 @@
_printUsage();
return;
}
- overwriteFileContents = options['write'];
+ _readOptions(options);
+
if (options.rest.isEmpty) {
_formatStdin(options);
} else {
@@ -35,6 +39,29 @@
}
}
+_readOptions(options) {
+ machineFormat = options['machine'];
+ overwriteFileContents = options['write'];
+ selection = _parseSelection(options['selection']);
+}
+
+Selection _parseSelection(selectionOption) {
+ if (selectionOption != null) {
+ var units = selectionOption.split(',');
+ if (units.length == 2) {
+ var offset = _toInt(units[0]);
+ var length = _toInt(units[1]);
+ if (offset != null && length != null) {
+ return new Selection(offset, length);
+ }
+ }
+ throw new FormatterException('Selections are specified as integer pairs '
+ '(e.g., "(offset, length)".');
+ }
+}
+
+int _toInt(str) => int.parse(str, onError: (_) => null);
+
_formatPaths(paths) {
paths.forEach((path) {
if (FileSystemEntity.isDirectorySync(path)) {
@@ -90,6 +117,11 @@
parser.addFlag('write', abbr: 'w', negatable: false,
help: 'Write reformatted sources to files (overwriting contents). '
'Do not print reformatted sources to standard output.');
+ parser.addFlag('machine', abbr: 'm', negatable: false,
+ help: 'Produce output in a format suitable for parsing.');
+ parser.addOption('selection', abbr: 's',
+ help: 'Specify selection information as an offset,length pair '
+ '(e.g., -s "0,4").');
parser.addFlag('help', abbr: 'h', negatable: false,
help: 'Print this usage information.');
return parser;
@@ -115,8 +147,19 @@
}
/// Format the given [src] as a compilation unit.
-String _formatCU(src, {options: const FormatterOptions()}) =>
- new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src).source;
+String _formatCU(src, {options: const FormatterOptions()}) {
+ var formatResult = new CodeFormatter(options).format(
+ CodeKind.COMPILATION_UNIT, src, selection: selection);
+ if (machineFormat) {
+ return _toJson(formatResult);
+ }
+ return formatResult.source;
+}
+
+_toJson(formatResult) =>
+ // Actual JSON format TBD
+ JSON.encode({'source': formatResult.source,
+ 'selection': formatResult.selection.toString()});
/// Log the given [msg].
_log(String msg) {
diff --git a/pkg/analyzer_experimental/lib/options.dart b/pkg/analyzer_experimental/lib/options.dart
index 37c6c8d..efa3b5f 100644
--- a/pkg/analyzer_experimental/lib/options.dart
+++ b/pkg/analyzer_experimental/lib/options.dart
@@ -29,6 +29,9 @@
/** Whether to ignore unrecognized flags */
final bool ignoreUnrecognizedFlags;
+ /** Whether to show performance statistics */
+ final bool perf;
+
/** Whether to show package: warnings */
final bool showPackageWarnings;
@@ -55,6 +58,7 @@
machineFormat = args['machine'],
displayVersion = args['version'],
ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'],
+ perf = args['perf'],
showPackageWarnings = args['show-package-warnings'],
showSdkWarnings = args['show-sdk-warnings'],
warningsAreFatal = args['fatal-warnings'],
@@ -106,6 +110,9 @@
..addFlag('show-package-warnings',
help: 'Show warnings from package: imports',
defaultsTo: false, negatable: false)
+ ..addFlag('perf',
+ help: 'Show performance statistics',
+ defaultsTo: false, negatable: false)
..addFlag('show-sdk-warnings', help: 'Show warnings from SDK imports',
defaultsTo: false, negatable: false)
..addFlag('help', abbr: 'h', help: 'Display this help message',
diff --git a/pkg/analyzer_experimental/lib/src/generated/ast.dart b/pkg/analyzer_experimental/lib/src/generated/ast.dart
index 9c25d8a..dea447d 100644
--- a/pkg/analyzer_experimental/lib/src/generated/ast.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/ast.dart
@@ -2795,6 +2795,11 @@
List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
/**
+ * The hints reported when the receiver was analyzed.
+ */
+ List<AnalysisError> _hints = AnalysisError.NO_ERRORS;
+
+ /**
* Initialize a newly created compilation unit to have the given directives and declarations.
*
* @param beginToken the first token in the token stream
@@ -2836,17 +2841,29 @@
List<AnalysisError> get errors {
List<AnalysisError> parserErrors = parsingErrors;
List<AnalysisError> resolverErrors = resolutionErrors;
- if (resolverErrors.length == 0) {
+ List<AnalysisError> hints = this.hints;
+ if (resolverErrors.length == 0 && hints.length == 0) {
return parserErrors;
- } else if (parserErrors.length == 0) {
+ } else if (parserErrors.length == 0 && hints.length == 0) {
return resolverErrors;
+ } else if (parserErrors.length == 0 && resolverErrors.length == 0) {
+ return hints;
} else {
- List<AnalysisError> allErrors = new List<AnalysisError>(parserErrors.length + resolverErrors.length);
+ List<AnalysisError> allErrors = new List<AnalysisError>(parserErrors.length + resolverErrors.length + hints.length);
JavaSystem.arraycopy(parserErrors, 0, allErrors, 0, parserErrors.length);
JavaSystem.arraycopy(resolverErrors, 0, allErrors, parserErrors.length, resolverErrors.length);
+ JavaSystem.arraycopy(hints, 0, allErrors, parserErrors.length + resolverErrors.length, hints.length);
return allErrors;
}
}
+
+ /**
+ * Return an array containing all of the hints associated with the receiver. The array will be
+ * empty if the receiver has not been analyzed.
+ *
+ * @return the hints associated with the receiver
+ */
+ List<AnalysisError> get hints => _hints;
int get length {
Token endToken = this.endToken;
if (endToken == null) {
@@ -2880,6 +2897,15 @@
ScriptTag get scriptTag => _scriptTag;
/**
+ * Set the reported hints associated with this compilation unit.
+ *
+ * @param the hints to be associated with this compilation unit
+ */
+ void set hints(List<AnalysisError> errors) {
+ _hints = errors == null ? AnalysisError.NO_ERRORS : errors;
+ }
+
+ /**
* Set the parse errors associated with this compilation unit to the given errors.
*
* @param the parse errors to be associated with this compilation unit
@@ -3560,13 +3586,6 @@
ConstructorElement _staticElement;
/**
- * The element associated with this constructor name based on propagated type information, or
- * `null` if the AST structure has not been resolved or if this constructor name could not
- * be resolved.
- */
- ConstructorElement _propagatedElement;
-
- /**
* Initialize a newly created constructor name.
*
* @param type the name of the type defining the constructor
@@ -3589,15 +3608,6 @@
ConstructorName({TypeName type, Token period, SimpleIdentifier name}) : this.full(type, period, name);
accept(ASTVisitor visitor) => visitor.visitConstructorName(this);
Token get beginToken => _type.beginToken;
-
- /**
- * Return the element associated with this constructor name based on propagated type information,
- * or `null` if the AST structure has not been resolved or if this constructor name could
- * not be resolved.
- *
- * @return the element associated with this constructor name
- */
- ConstructorElement get element => _propagatedElement;
Token get endToken {
if (_name != null) {
return _name.endToken;
@@ -3630,16 +3640,6 @@
TypeName get type => _type;
/**
- * Set the element associated with this constructor name based on propagated type information to
- * the given element.
- *
- * @param element the element to be associated with this constructor name
- */
- void set element(ConstructorElement element2) {
- _propagatedElement = element2;
- }
-
- /**
* Set the name of the constructor to the given name.
*
* @param name the name of the constructor
@@ -4419,6 +4419,22 @@
Type2 propagatedType;
/**
+ * Return the best parameter element information available for this expression. If type
+ * propagation was able to find a better parameter element than static analysis, that type will be
+ * returned. Otherwise, the result of static analysis will be returned.
+ *
+ * @return the parameter element representing the parameter to which the value of this expression
+ * will be bound
+ */
+ ParameterElement get bestParameterElement {
+ ParameterElement propagatedElement = propagatedParameterElement;
+ if (propagatedElement != null) {
+ return propagatedElement;
+ }
+ return staticParameterElement;
+ }
+
+ /**
* Return the best type information available for this expression. If type propagation was able to
* find a better type than static analysis, that type will be returned. Otherwise, the result of
* static analysis will be returned. If no type analysis has been performed, then the type
@@ -4954,7 +4970,8 @@
*
* <pre>
* forEachStatement ::=
- * 'for' '(' [SimpleFormalParameter] 'in' [Expression] ')' [Block]
+ * 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
+ * | 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
* </pre>
*
* @coverage dart.engine.ast
@@ -4972,11 +4989,17 @@
Token leftParenthesis;
/**
- * The declaration of the loop variable.
+ * The declaration of the loop variable, or `null` if the loop variable is a simple
+ * identifier.
*/
DeclaredIdentifier _loopVariable;
/**
+ * The loop variable, or `null` if the loop variable is declared in the 'for'.
+ */
+ SimpleIdentifier _identifier;
+
+ /**
* The token representing the 'in' keyword.
*/
Token inKeyword;
@@ -5006,7 +5029,7 @@
* @param rightParenthesis the right parenthesis
* @param body the body of the loop
*/
- ForEachStatement.full(Token forKeyword, Token leftParenthesis, DeclaredIdentifier loopVariable, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body) {
+ ForEachStatement.con1_full(Token forKeyword, Token leftParenthesis, DeclaredIdentifier loopVariable, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body) {
this.forKeyword = forKeyword;
this.leftParenthesis = leftParenthesis;
this._loopVariable = becomeParentOf(loopVariable);
@@ -5026,7 +5049,39 @@
* @param rightParenthesis the right parenthesis
* @param body the body of the loop
*/
- ForEachStatement({Token forKeyword, Token leftParenthesis, DeclaredIdentifier loopVariable, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body}) : this.full(forKeyword, leftParenthesis, loopVariable, inKeyword, iterator, rightParenthesis, body);
+ ForEachStatement.con1({Token forKeyword, Token leftParenthesis, DeclaredIdentifier loopVariable, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body}) : this.con1_full(forKeyword, leftParenthesis, loopVariable, inKeyword, iterator, rightParenthesis, body);
+
+ /**
+ * Initialize a newly created for-each statement.
+ *
+ * @param forKeyword the token representing the 'for' keyword
+ * @param leftParenthesis the left parenthesis
+ * @param identifier the loop variable
+ * @param iterator the expression evaluated to produce the iterator
+ * @param rightParenthesis the right parenthesis
+ * @param body the body of the loop
+ */
+ ForEachStatement.con2_full(Token forKeyword, Token leftParenthesis, SimpleIdentifier identifier, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body) {
+ this.forKeyword = forKeyword;
+ this.leftParenthesis = leftParenthesis;
+ this._identifier = becomeParentOf(identifier);
+ this.inKeyword = inKeyword;
+ this._iterator = becomeParentOf(iterator);
+ this.rightParenthesis = rightParenthesis;
+ this._body = becomeParentOf(body);
+ }
+
+ /**
+ * Initialize a newly created for-each statement.
+ *
+ * @param forKeyword the token representing the 'for' keyword
+ * @param leftParenthesis the left parenthesis
+ * @param identifier the loop variable
+ * @param iterator the expression evaluated to produce the iterator
+ * @param rightParenthesis the right parenthesis
+ * @param body the body of the loop
+ */
+ ForEachStatement.con2({Token forKeyword, Token leftParenthesis, SimpleIdentifier identifier, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body}) : this.con2_full(forKeyword, leftParenthesis, identifier, inKeyword, iterator, rightParenthesis, body);
accept(ASTVisitor visitor) => visitor.visitForEachStatement(this);
Token get beginToken => forKeyword;
@@ -5039,6 +5094,13 @@
Token get endToken => _body.endToken;
/**
+ * Return the loop variable, or `null` if the loop variable is declared in the 'for'.
+ *
+ * @return the loop variable
+ */
+ SimpleIdentifier get identifier => _identifier;
+
+ /**
* Return the expression evaluated to produce the iterator.
*
* @return the expression evaluated to produce the iterator
@@ -5046,7 +5108,8 @@
Expression get iterator => _iterator;
/**
- * Return the declaration of the loop variable.
+ * Return the declaration of the loop variable, or `null` if the loop variable is a simple
+ * identifier.
*
* @return the declaration of the loop variable
*/
@@ -5062,6 +5125,15 @@
}
/**
+ * Set the loop variable to the given variable.
+ *
+ * @param identifier the loop variable
+ */
+ void set identifier(SimpleIdentifier identifier2) {
+ this._identifier = becomeParentOf(identifier2);
+ }
+
+ /**
* Set the expression evaluated to produce the iterator to the given expression.
*
* @param expression the expression evaluated to produce the iterator
@@ -5080,6 +5152,7 @@
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_loopVariable, visitor);
+ safelyVisitChild(_identifier, visitor);
safelyVisitChild(_iterator, visitor);
safelyVisitChild(_body, visitor);
}
@@ -6520,6 +6593,85 @@
* @coverage dart.engine.ast
*/
class ImportDirective extends NamespaceDirective {
+ static Comparator<ImportDirective> COMPARATOR = (ImportDirective import1, ImportDirective import2) {
+ StringLiteral uri1 = import1.uri;
+ StringLiteral uri2 = import2.uri;
+ String uriStr1 = uri1.stringValue;
+ String uriStr2 = uri2.stringValue;
+ if (uriStr1 != null || uriStr2 != null) {
+ if (uriStr1 == null) {
+ return -1;
+ } else if (uriStr2 == null) {
+ return 1;
+ } else {
+ int compare = uriStr1.compareTo(uriStr2);
+ if (compare != 0) {
+ return compare;
+ }
+ }
+ }
+ SimpleIdentifier prefix1 = import1.prefix;
+ SimpleIdentifier prefix2 = import2.prefix;
+ String prefixStr1 = prefix1 != null ? prefix1.name : null;
+ String prefixStr2 = prefix2 != null ? prefix2.name : null;
+ if (prefixStr1 != null || prefixStr2 != null) {
+ if (prefixStr1 == null) {
+ return -1;
+ } else if (prefixStr2 == null) {
+ return 1;
+ } else {
+ int compare = prefixStr1.compareTo(prefixStr2);
+ if (compare != 0) {
+ return compare;
+ }
+ }
+ }
+ NodeList<Combinator> combinators1 = import1.combinators;
+ List<String> allHides1 = new List<String>();
+ List<String> allShows1 = new List<String>();
+ for (Combinator combinator in combinators1) {
+ if (combinator is HideCombinator) {
+ NodeList<SimpleIdentifier> hides = ((combinator as HideCombinator)).hiddenNames;
+ for (SimpleIdentifier simpleIdentifier in hides) {
+ allHides1.add(simpleIdentifier.name);
+ }
+ } else {
+ NodeList<SimpleIdentifier> shows = ((combinator as ShowCombinator)).shownNames;
+ for (SimpleIdentifier simpleIdentifier in shows) {
+ allShows1.add(simpleIdentifier.name);
+ }
+ }
+ }
+ NodeList<Combinator> combinators2 = import2.combinators;
+ List<String> allHides2 = new List<String>();
+ List<String> allShows2 = new List<String>();
+ for (Combinator combinator in combinators2) {
+ if (combinator is HideCombinator) {
+ NodeList<SimpleIdentifier> hides = ((combinator as HideCombinator)).hiddenNames;
+ for (SimpleIdentifier simpleIdentifier in hides) {
+ allHides2.add(simpleIdentifier.name);
+ }
+ } else {
+ NodeList<SimpleIdentifier> shows = ((combinator as ShowCombinator)).shownNames;
+ for (SimpleIdentifier simpleIdentifier in shows) {
+ allShows2.add(simpleIdentifier.name);
+ }
+ }
+ }
+ if (allHides1.length != allHides2.length) {
+ return allHides1.length - allHides2.length;
+ }
+ if (allShows1.length != allShows2.length) {
+ return allShows1.length - allShows2.length;
+ }
+ if (!javaCollectionContainsAll(allHides1, allHides2)) {
+ return -1;
+ }
+ if (!javaCollectionContainsAll(allShows1, allShows2)) {
+ return -1;
+ }
+ return 0;
+ };
/**
* The token representing the 'as' token, or `null` if the imported names are not prefixed.
@@ -6989,13 +7141,6 @@
ConstructorElement staticElement;
/**
- * The element associated with the constructor based on propagated type information, or
- * `null` if the AST structure has not been resolved or if the constructor could not be
- * resolved.
- */
- ConstructorElement element;
-
- /**
* Initialize a newly created instance creation expression.
*
* @param keyword the keyword used to indicate how an object should be created
@@ -9669,13 +9814,6 @@
ConstructorElement staticElement;
/**
- * The element associated with the constructor based on propagated type information, or
- * `null` if the AST structure has not been resolved or if the constructor could not be
- * resolved.
- */
- ConstructorElement _propagatedElement;
-
- /**
* Initialize a newly created redirecting invocation to invoke the constructor with the given name
* with the given arguments.
*
@@ -9718,15 +9856,6 @@
* @return the name of the constructor that is being invoked
*/
SimpleIdentifier get constructorName => _constructorName;
-
- /**
- * Return the element associated with the constructor based on propagated type information, or
- * `null` if the AST structure has not been resolved or if the constructor could not be
- * resolved.
- *
- * @return the element associated with the super constructor
- */
- ConstructorElement get element => _propagatedElement;
Token get endToken => _argumentList.endToken;
/**
@@ -9746,16 +9875,6 @@
void set constructorName(SimpleIdentifier identifier) {
_constructorName = becomeParentOf(identifier);
}
-
- /**
- * Set the element associated with the constructor based on propagated type information to the
- * given element.
- *
- * @param element the element to be associated with the constructor
- */
- void set element(ConstructorElement element2) {
- _propagatedElement = element2;
- }
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_constructorName, visitor);
safelyVisitChild(_argumentList, visitor);
@@ -10282,7 +10401,7 @@
} else if (parent is MethodDeclaration && identical(((parent as MethodDeclaration)).name, this)) {
return validateElement(parent, ExecutableElement, element);
} else if (parent is TypeParameter && identical(((parent as TypeParameter)).name, this)) {
- return validateElement(parent, TypeVariableElement, element);
+ return validateElement(parent, TypeParameterElement, element);
} else if (parent is VariableDeclaration && identical(((parent as VariableDeclaration)).name, this)) {
return validateElement(parent, VariableElement, element);
}
@@ -10542,12 +10661,6 @@
ConstructorElement staticElement;
/**
- * The element associated with the constructor based on propagated type information, or `null` if the AST structure has not been
- * resolved or if the constructor could not be resolved.
- */
- ConstructorElement _propagatedElement;
-
- /**
* Initialize a newly created super invocation to invoke the inherited constructor with the given
* name with the given arguments.
*
@@ -10590,15 +10703,6 @@
* @return the name of the constructor that is being invoked
*/
SimpleIdentifier get constructorName => _constructorName;
-
- /**
- * Return the element associated with the constructor based on propagated type information, or
- * `null` if the AST structure has not been resolved or if the constructor could not be
- * resolved.
- *
- * @return the element associated with the super constructor
- */
- ConstructorElement get element => _propagatedElement;
Token get endToken => _argumentList.endToken;
/**
@@ -10618,16 +10722,6 @@
void set constructorName(SimpleIdentifier identifier) {
_constructorName = becomeParentOf(identifier);
}
-
- /**
- * Set the element associated with the constructor based on propagated type information to the
- * given element.
- *
- * @param element the element to be associated with the constructor
- */
- void set element(ConstructorElement element2) {
- _propagatedElement = element2;
- }
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_constructorName, visitor);
safelyVisitChild(_argumentList, visitor);
@@ -11559,7 +11653,7 @@
* @return the name of the upper bound for legal arguments
*/
TypeName get bound => _bound;
- TypeVariableElement get element => _name != null ? (_name.staticElement as TypeVariableElement) : null;
+ TypeParameterElement get element => _name != null ? (_name.staticElement as TypeParameterElement) : null;
Token get endToken {
if (_bound == null) {
return _name.endToken;
@@ -12297,12 +12391,12 @@
return null;
}
BreadthFirstVisitor() {
- this._childVisitor = new GeneralizingASTVisitor_1(this);
+ this._childVisitor = new GeneralizingASTVisitor_2(this);
}
}
-class GeneralizingASTVisitor_1 extends GeneralizingASTVisitor<Object> {
+class GeneralizingASTVisitor_2 extends GeneralizingASTVisitor<Object> {
final BreadthFirstVisitor BreadthFirstVisitor_this;
- GeneralizingASTVisitor_1(this.BreadthFirstVisitor_this) : super();
+ GeneralizingASTVisitor_2(this.BreadthFirstVisitor_this) : super();
Object visitNode(ASTNode node) {
BreadthFirstVisitor_this._queue.add(node);
return null;
@@ -12319,7 +12413,7 @@
* to a numeric, string or boolean value or to `null`.
* * `null`.
* * A reference to a static constant variable.
- * * An identifier expression that denotes a constant variable, a class or a type variable.
+ * * An identifier expression that denotes a constant variable, a class or a type parameter.
* * A constant constructor invocation.
* * A constant list literal.
* * A constant map literal.
@@ -13732,8 +13826,13 @@
return null;
}
Object visitForEachStatement(ForEachStatement node) {
+ DeclaredIdentifier loopVariable = node.loopVariable;
_writer.print("for (");
- visit(node.loopVariable);
+ if (loopVariable == null) {
+ visit(node.identifier);
+ } else {
+ visit(loopVariable);
+ }
_writer.print(" in ");
visit(node.iterator);
_writer.print(") ");
@@ -14365,6 +14464,7 @@
clone.lineInfo = node.lineInfo;
clone.parsingErrors = node.parsingErrors;
clone.resolutionErrors = node.resolutionErrors;
+ clone.hints = node.hints;
return clone;
}
ConditionalExpression visitConditionalExpression(ConditionalExpression node) => new ConditionalExpression.full(clone2(node.condition), node.question, clone2(node.thenExpression), node.colon, clone2(node.elseExpression));
@@ -14384,7 +14484,13 @@
ExtendsClause visitExtendsClause(ExtendsClause node) => new ExtendsClause.full(node.keyword, clone2(node.superclass));
FieldDeclaration visitFieldDeclaration(FieldDeclaration node) => new FieldDeclaration.full(clone2(node.documentationComment), clone3(node.metadata), node.staticKeyword, clone2(node.fields), node.semicolon);
FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) => new FieldFormalParameter.full(clone2(node.documentationComment), clone3(node.metadata), node.keyword, clone2(node.type), node.thisToken, node.period, clone2(node.identifier), clone2(node.parameters));
- ForEachStatement visitForEachStatement(ForEachStatement node) => new ForEachStatement.full(node.forKeyword, node.leftParenthesis, clone2(node.loopVariable), node.inKeyword, clone2(node.iterator), node.rightParenthesis, clone2(node.body));
+ ForEachStatement visitForEachStatement(ForEachStatement node) {
+ DeclaredIdentifier loopVariable = node.loopVariable;
+ if (loopVariable == null) {
+ return new ForEachStatement.con2_full(node.forKeyword, node.leftParenthesis, clone2(node.identifier), node.inKeyword, clone2(node.iterator), node.rightParenthesis, clone2(node.body));
+ }
+ return new ForEachStatement.con1_full(node.forKeyword, node.leftParenthesis, clone2(loopVariable), node.inKeyword, clone2(node.iterator), node.rightParenthesis, clone2(node.body));
+ }
FormalParameterList visitFormalParameterList(FormalParameterList node) => new FormalParameterList.full(node.leftParenthesis, clone3(node.parameters), node.leftDelimiter, node.rightDelimiter, node.rightParenthesis);
ForStatement visitForStatement(ForStatement node) => new ForStatement.full(node.forKeyword, node.leftParenthesis, clone2(node.variables), clone2(node.initialization), node.leftSeparator, clone2(node.condition), node.rightSeparator, clone3(node.updaters), node.rightParenthesis, clone2(node.body));
FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) => new FunctionDeclaration.full(clone2(node.documentationComment), clone3(node.metadata), node.externalKeyword, clone2(node.returnType), node.propertyKeyword, clone2(node.name), clone2(node.functionExpression));
@@ -14512,7 +14618,10 @@
return null;
}
Object visitForEachStatement(ForEachStatement node) {
- addToScope(node.loopVariable.identifier);
+ DeclaredIdentifier loopVariable = node.loopVariable;
+ if (loopVariable != null) {
+ addToScope(loopVariable.identifier);
+ }
return super.visitForEachStatement(node);
}
Object visitForStatement(ForStatement node) {
@@ -14539,13 +14648,13 @@
return super.visitFunctionExpression(node);
}
Object visitMethodDeclaration(MethodDeclaration node) {
+ declaration = node;
if (node.parameters == null) {
return null;
}
if (_immediateChild != node.parameters) {
addParameters(node.parameters.parameters);
}
- declaration = node;
return null;
}
Object visitNode(ASTNode node) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/constant.dart b/pkg/analyzer_experimental/lib/src/generated/constant.dart
index 0901fdd..ac6bf34 100644
--- a/pkg/analyzer_experimental/lib/src/generated/constant.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/constant.dart
@@ -19,7 +19,7 @@
* to a numeric, string or boolean value or to `null`.
* * `null`.
* * A reference to a static constant variable.
- * * An identifier expression that denotes a constant variable, a class or a type variable.
+ * * An identifier expression that denotes a constant variable, a class or a type parameter.
* * A constant constructor invocation.
* * A constant list literal.
* * A constant map literal.
@@ -270,7 +270,7 @@
* to a numeric, string or boolean value or to `null`.
* * `null`.
* * A reference to a static constant variable.
- * * An identifier expression that denotes a constant variable, a class or a type variable.
+ * * An identifier expression that denotes a constant variable, a class or a type parameter.
* * A constant constructor invocation.
* * A constant list literal.
* * A constant map literal.
@@ -358,6 +358,23 @@
return error(node, null);
}
EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ? ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE;
+ EvaluationResultImpl visitConditionalExpression(ConditionalExpression node) {
+ Expression condition = node.condition;
+ EvaluationResultImpl conditionResult = condition.accept(this);
+ conditionResult = conditionResult.applyBooleanConversion(condition);
+ if (conditionResult is ErrorResult) {
+ return conditionResult;
+ }
+ EvaluationResultImpl thenResult = node.thenExpression.accept(this);
+ if (thenResult is ErrorResult) {
+ return thenResult;
+ }
+ EvaluationResultImpl elseResult = node.elseExpression.accept(this);
+ if (elseResult is ErrorResult) {
+ return elseResult;
+ }
+ return (identical(conditionResult, ValidResult.RESULT_TRUE)) ? thenResult : elseResult;
+ }
EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult(node.value);
EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpression node) {
if (!node.isConst) {
@@ -719,6 +736,7 @@
errorData.addAll(secondResult.errorData);
}
EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
+ EvaluationResultImpl applyBooleanConversion(ASTNode node) => this;
EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
EvaluationResultImpl bitNot(Expression node) => this;
EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
@@ -814,6 +832,14 @@
*/
abstract class EvaluationResultImpl {
EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand);
+
+ /**
+ * Return the result of applying boolean conversion to this result.
+ *
+ * @param node the node against which errors should be reported
+ * @return the result of applying boolean conversion to the given value
+ */
+ EvaluationResultImpl applyBooleanConversion(ASTNode node);
EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
EvaluationResultImpl bitNot(Expression node);
EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand);
@@ -993,6 +1019,14 @@
this.value = value;
}
EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(node, this);
+
+ /**
+ * Return the result of applying boolean conversion to this result.
+ *
+ * @param node the node against which errors should be reported
+ * @return the result of applying boolean conversion to the given value
+ */
+ EvaluationResultImpl applyBooleanConversion(ASTNode node) => booleanConversion(node, value);
EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(node, this);
EvaluationResultImpl bitNot(Expression node) {
if (isSomeInt) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/element.dart b/pkg/analyzer_experimental/lib/src/generated/element.dart
index 031dc2a..fa3c4be 100644
--- a/pkg/analyzer_experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/element.dart
@@ -139,11 +139,11 @@
InterfaceType get type;
/**
- * Return an array containing all of the type variables declared for this class.
+ * Return an array containing all of the type parameters declared for this class.
*
- * @return the type variables declared for this class
+ * @return the type parameters declared for this class
*/
- List<TypeVariableElement> get typeVariables;
+ List<TypeParameterElement> get typeParameters;
/**
* Return the unnamed constructor declared in this class, or `null` if this class does not
@@ -594,7 +594,7 @@
static final ElementKind SETTER = new ElementKind('SETTER', 20, "setter");
static final ElementKind TOP_LEVEL_VARIABLE = new ElementKind('TOP_LEVEL_VARIABLE', 21, "top level variable");
static final ElementKind FUNCTION_TYPE_ALIAS = new ElementKind('FUNCTION_TYPE_ALIAS', 22, "function type alias");
- static final ElementKind TYPE_VARIABLE = new ElementKind('TYPE_VARIABLE', 23, "type variable");
+ static final ElementKind TYPE_PARAMETER = new ElementKind('TYPE_PARAMETER', 23, "type parameter");
static final ElementKind UNIVERSE = new ElementKind('UNIVERSE', 24, "<universe>");
static final List<ElementKind> values = [
CLASS,
@@ -620,7 +620,7 @@
SETTER,
TOP_LEVEL_VARIABLE,
FUNCTION_TYPE_ALIAS,
- TYPE_VARIABLE,
+ TYPE_PARAMETER,
UNIVERSE];
/**
@@ -695,7 +695,7 @@
R visitPrefixElement(PrefixElement element);
R visitPropertyAccessorElement(PropertyAccessorElement element);
R visitTopLevelVariableElement(TopLevelVariableElement element);
- R visitTypeVariableElement(TypeVariableElement element);
+ R visitTypeParameterElement(TypeParameterElement element);
}
/**
* The interface `EmbeddedHtmlScriptElement` defines the behavior of elements representing a
@@ -890,11 +890,11 @@
FunctionType get type;
/**
- * Return an array containing all of the type variables defined for this type.
+ * Return an array containing all of the type parameters defined for this type.
*
- * @return the type variables defined for this type
+ * @return the type parameters defined for this type
*/
- List<TypeVariableElement> get typeVariables;
+ List<TypeParameterElement> get typeParameters;
}
/**
* The interface `HideElementCombinator` defines the behavior of combinators that cause some
@@ -1083,6 +1083,13 @@
bool get isDartCore;
/**
+ * Return `true` if this library is the dart:core library.
+ *
+ * @return `true` if this library is the dart:core library
+ */
+ bool get isInSdk;
+
+ /**
* Return `true` if this library is up to date with respect to the given time stamp. If any
* transitively referenced Source is newer than the time stamp, this method returns false.
*
@@ -1380,27 +1387,27 @@
abstract class TopLevelVariableElement implements PropertyInducingElement {
}
/**
- * The interface `TypeVariableElement` defines the behavior of elements representing a type
- * variable.
+ * The interface `TypeParameterElement` defines the behavior of elements representing a type
+ * parameter.
*
* @coverage dart.engine.element
*/
-abstract class TypeVariableElement implements Element {
+abstract class TypeParameterElement implements Element {
/**
- * Return the type representing the bound associated with this variable, or `null` if this
- * variable does not have an explicit bound.
+ * Return the type representing the bound associated with this parameter, or `null` if this
+ * parameter does not have an explicit bound.
*
- * @return the type representing the bound associated with this variable
+ * @return the type representing the bound associated with this parameter
*/
Type2 get bound;
/**
- * Return the type defined by this type variable.
+ * Return the type defined by this type parameter.
*
- * @return the type defined by this type variable
+ * @return the type defined by this type parameter
*/
- TypeVariableType get type;
+ TypeParameterType get type;
}
/**
* The interface `UndefinedElement` defines the behavior of pseudo-elements that represent
@@ -1507,7 +1514,7 @@
* MultiplyDefinedElement
* PrefixElement
* TypeAliasElement
- * TypeVariableElement
+ * TypeParameterElement
* UndefinedElement
* VariableElement
* PropertyInducingElement
@@ -1565,7 +1572,7 @@
R visitPropertyAccessorElement(PropertyAccessorElement element) => visitExecutableElement(element);
R visitPropertyInducingElement(PropertyInducingElement element) => visitVariableElement(element);
R visitTopLevelVariableElement(TopLevelVariableElement element) => visitPropertyInducingElement(element);
- R visitTypeVariableElement(TypeVariableElement element) => visitElement(element);
+ R visitTypeParameterElement(TypeParameterElement element) => visitElement(element);
R visitVariableElement(VariableElement element) => visitElement(element);
}
/**
@@ -1665,7 +1672,7 @@
element.visitChildren(this);
return null;
}
- R visitTypeVariableElement(TypeVariableElement element) {
+ R visitTypeParameterElement(TypeParameterElement element) {
element.visitChildren(this);
return null;
}
@@ -1700,7 +1707,7 @@
R visitPrefixElement(PrefixElement element) => null;
R visitPropertyAccessorElement(PropertyAccessorElement element) => null;
R visitTopLevelVariableElement(TopLevelVariableElement element) => null;
- R visitTypeVariableElement(TypeVariableElement element) => null;
+ R visitTypeParameterElement(TypeParameterElement element) => null;
}
/**
* For AST nodes that could be in both the getter and setter contexts ([IndexExpression]s and
@@ -1783,9 +1790,9 @@
InterfaceType _type;
/**
- * An array containing all of the type variables defined for this class.
+ * An array containing all of the type parameters defined for this class.
*/
- List<TypeVariableElement> _typeVariables = TypeVariableElementImpl.EMPTY_ARRAY;
+ List<TypeParameterElement> _typeParameters = TypeParameterElementImpl.EMPTY_ARRAY;
/**
* An empty array of type elements.
@@ -1826,9 +1833,9 @@
return method as MethodElementImpl;
}
}
- for (TypeVariableElement typeVariable in _typeVariables) {
- if (((typeVariable as TypeVariableElementImpl)).identifier == identifier2) {
- return typeVariable as TypeVariableElementImpl;
+ for (TypeParameterElement typeParameter in _typeParameters) {
+ if (((typeParameter as TypeParameterElementImpl)).identifier == identifier2) {
+ return typeParameter as TypeParameterElementImpl;
}
}
return null;
@@ -1893,7 +1900,7 @@
}
InterfaceType get supertype => _supertype;
InterfaceType get type => _type;
- List<TypeVariableElement> get typeVariables => _typeVariables;
+ List<TypeParameterElement> get typeParameters => _typeParameters;
ConstructorElement get unnamedConstructor {
for (ConstructorElement element in constructors) {
String name = element.displayName;
@@ -2126,15 +2133,15 @@
}
/**
- * Set the type variables defined for this class to the given type variables.
+ * Set the type parameters defined for this class to the given type parameters.
*
- * @param typeVariables the type variables defined for this class
+ * @param typeParameters the type parameters defined for this class
*/
- void set typeVariables(List<TypeVariableElement> typeVariables2) {
- for (TypeVariableElement typeVariable in typeVariables2) {
- ((typeVariable as TypeVariableElementImpl)).enclosingElement = this;
+ void set typeParameters(List<TypeParameterElement> typeParameters2) {
+ for (TypeParameterElement typeParameter in typeParameters2) {
+ ((typeParameter as TypeParameterElementImpl)).enclosingElement = this;
}
- this._typeVariables = typeVariables2;
+ this._typeParameters = typeParameters2;
}
/**
@@ -2151,7 +2158,7 @@
safelyVisitChildren(_constructors, visitor);
safelyVisitChildren(_fields, visitor);
safelyVisitChildren(_methods, visitor);
- safelyVisitChildren(_typeVariables, visitor);
+ safelyVisitChildren(_typeParameters, visitor);
}
void appendTo(JavaStringBuilder builder) {
String name = displayName;
@@ -2160,14 +2167,14 @@
} else {
builder.append(name);
}
- int variableCount = _typeVariables.length;
+ int variableCount = _typeParameters.length;
if (variableCount > 0) {
builder.append("<");
for (int i = 0; i < variableCount; i++) {
if (i > 0) {
builder.append(", ");
}
- ((_typeVariables[i] as TypeVariableElementImpl)).appendTo(builder);
+ ((_typeParameters[i] as TypeParameterElementImpl)).appendTo(builder);
}
builder.append(">");
}
@@ -3541,9 +3548,9 @@
FunctionType _type;
/**
- * An array containing all of the type variables defined for this type.
+ * An array containing all of the type parameters defined for this type.
*/
- List<TypeVariableElement> _typeVariables = TypeVariableElementImpl.EMPTY_ARRAY;
+ List<TypeParameterElement> _typeParameters = TypeParameterElementImpl.EMPTY_ARRAY;
/**
* An empty array of type alias elements.
@@ -3563,9 +3570,9 @@
return parameter as VariableElementImpl;
}
}
- for (TypeVariableElement typeVariable in _typeVariables) {
- if (((typeVariable as TypeVariableElementImpl)).identifier == identifier2) {
- return typeVariable as TypeVariableElementImpl;
+ for (TypeParameterElement typeParameter in _typeParameters) {
+ if (((typeParameter as TypeParameterElementImpl)).identifier == identifier2) {
+ return typeParameter as TypeParameterElementImpl;
}
}
return null;
@@ -3575,7 +3582,7 @@
List<ParameterElement> get parameters => _parameters;
Type2 get returnType => _returnType;
FunctionType get type => _type;
- List<TypeVariableElement> get typeVariables => _typeVariables;
+ List<TypeParameterElement> get typeParameters => _typeParameters;
/**
* Set the parameters defined by this type alias to the given parameters.
@@ -3610,15 +3617,15 @@
}
/**
- * Set the type variables defined for this type to the given variables.
+ * Set the type parameters defined for this type to the given parameters.
*
- * @param typeVariables the type variables defined for this type
+ * @param typeParameters the type parameters defined for this type
*/
- void set typeVariables(List<TypeVariableElement> typeVariables2) {
- for (TypeVariableElement variable in typeVariables2) {
- ((variable as TypeVariableElementImpl)).enclosingElement = this;
+ void set typeParameters(List<TypeParameterElement> typeParameters2) {
+ for (TypeParameterElement typeParameter in typeParameters2) {
+ ((typeParameter as TypeParameterElementImpl)).enclosingElement = this;
}
- this._typeVariables = typeVariables2;
+ this._typeParameters = typeParameters2;
}
/**
@@ -3633,31 +3640,31 @@
}
/**
- * Set the type variables defined for this type to the given variables without becoming the parent
- * of the variables. This should only be used by the [TypeResolverVisitor] when creating a
- * synthetic type alias.
+ * Set the type parameters defined for this type to the given parameters without becoming the
+ * parent of the parameters. This should only be used by the [TypeResolverVisitor] when
+ * creating a synthetic type alias.
*
- * @param typeVariables the type variables defined for this type
+ * @param typeParameters the type parameters defined for this type
*/
- void shareTypeVariables(List<TypeVariableElement> typeVariables2) {
- this._typeVariables = typeVariables2;
+ void shareTypeParameters(List<TypeParameterElement> typeParameters2) {
+ this._typeParameters = typeParameters2;
}
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
safelyVisitChildren(_parameters, visitor);
- safelyVisitChildren(_typeVariables, visitor);
+ safelyVisitChildren(_typeParameters, visitor);
}
void appendTo(JavaStringBuilder builder) {
builder.append("typedef ");
builder.append(displayName);
- int variableCount = _typeVariables.length;
- if (variableCount > 0) {
+ int typeParameterCount = _typeParameters.length;
+ if (typeParameterCount > 0) {
builder.append("<");
- for (int i = 0; i < variableCount; i++) {
+ for (int i = 0; i < typeParameterCount; i++) {
if (i > 0) {
builder.append(", ");
}
- ((_typeVariables[i] as TypeVariableElementImpl)).appendTo(builder);
+ ((_typeParameters[i] as TypeParameterElementImpl)).appendTo(builder);
}
builder.append(">");
}
@@ -4105,6 +4112,7 @@
int get hashCode => _definingCompilationUnit.hashCode;
bool get isBrowserApplication => _entryPoint != null && isOrImportsBrowserLibrary;
bool get isDartCore => name == "dart.core";
+ bool get isInSdk => name.startsWith("dart.");
bool isUpToDate2(int timeStamp) {
Set<LibraryElement> visitedLibraries = new Set();
return isUpToDate(this, timeStamp, visitedLibraries);
@@ -4399,10 +4407,23 @@
* @param firstElement the first element that conflicts
* @param secondElement the second element that conflicts
*/
- MultiplyDefinedElementImpl(AnalysisContext context, Element firstElement, Element secondElement) {
+ MultiplyDefinedElementImpl.con1(AnalysisContext context, Element firstElement, Element secondElement) {
+ this._context = context;
_name = firstElement.name;
_conflictingElements = computeConflictingElements(firstElement, secondElement);
}
+
+ /**
+ * Initialize a newly created element to represent a list of conflicting elements.
+ *
+ * @param context the analysis context in which the multiply defined elements are defined
+ * @param conflictingElements the elements that conflict
+ */
+ MultiplyDefinedElementImpl.con2(AnalysisContext context, List<Element> conflictingElements) {
+ this._context = context;
+ _name = conflictingElements[0].name;
+ this._conflictingElements = conflictingElements;
+ }
accept(ElementVisitor visitor) => visitor.visitMultiplyDefinedElement(this);
String computeDocumentationComment() => null;
Element getAncestor(Type elementClass) => null;
@@ -4450,13 +4471,13 @@
* @param elements the list to which the element(s) are to be added
* @param element the element(s) to be added
*/
- void add(List<Element> elements, Element element) {
+ void add(Set<Element> elements, Element element) {
if (element is MultiplyDefinedElementImpl) {
for (Element conflictingElement in ((element as MultiplyDefinedElementImpl))._conflictingElements) {
- elements.add(conflictingElement);
+ javaSetAdd(elements, conflictingElement);
}
} else {
- elements.add(element);
+ javaSetAdd(elements, element);
}
}
@@ -4470,7 +4491,7 @@
* @return an array containing all of the conflicting elements
*/
List<Element> computeConflictingElements(Element firstElement, Element secondElement) {
- List<Element> elements = new List<Element>();
+ Set<Element> elements = new Set<Element>();
add(elements, firstElement);
add(elements, secondElement);
return new List.from(elements);
@@ -4913,54 +4934,54 @@
bool get isStatic => true;
}
/**
- * Instances of the class `TypeVariableElementImpl` implement a `TypeVariableElement`.
+ * Instances of the class `TypeParameterElementImpl` implement a [TypeParameterElement].
*
* @coverage dart.engine.element
*/
-class TypeVariableElementImpl extends ElementImpl implements TypeVariableElement {
+class TypeParameterElementImpl extends ElementImpl implements TypeParameterElement {
/**
- * The type defined by this type variable.
+ * The type defined by this type parameter.
*/
- TypeVariableType _type;
+ TypeParameterType _type;
/**
- * The type representing the bound associated with this variable, or `null` if this variable
- * does not have an explicit bound.
+ * The type representing the bound associated with this parameter, or `null` if this
+ * parameter does not have an explicit bound.
*/
Type2 _bound;
/**
- * An empty array of type variable elements.
+ * An empty array of type parameter elements.
*/
- static List<TypeVariableElement> EMPTY_ARRAY = new List<TypeVariableElement>(0);
+ static List<TypeParameterElement> EMPTY_ARRAY = new List<TypeParameterElement>(0);
/**
- * Initialize a newly created type variable element to have the given name.
+ * Initialize a newly created type parameter element to have the given name.
*
* @param name the name of this element
*/
- TypeVariableElementImpl(Identifier name) : super.con1(name);
- accept(ElementVisitor visitor) => visitor.visitTypeVariableElement(this);
+ TypeParameterElementImpl(Identifier name) : super.con1(name);
+ accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this);
Type2 get bound => _bound;
- ElementKind get kind => ElementKind.TYPE_VARIABLE;
- TypeVariableType get type => _type;
+ ElementKind get kind => ElementKind.TYPE_PARAMETER;
+ TypeParameterType get type => _type;
/**
- * Set the type representing the bound associated with this variable to the given type.
+ * Set the type representing the bound associated with this parameter to the given type.
*
- * @param bound the type representing the bound associated with this variable
+ * @param bound the type representing the bound associated with this parameter
*/
void set bound(Type2 bound2) {
this._bound = bound2;
}
/**
- * Set the type defined by this type variable to the given type
+ * Set the type defined by this type parameter to the given type
*
- * @param type the type defined by this type variable
+ * @param type the type defined by this type parameter
*/
- void set type(TypeVariableType type2) {
+ void set type(TypeParameterType type2) {
this._type = type2;
}
void appendTo(JavaStringBuilder builder) {
@@ -5344,7 +5365,7 @@
*/
Type2 substituteFor(Type2 type) {
List<Type2> argumentTypes = _definingType.typeArguments;
- List<Type2> parameterTypes = TypeVariableTypeImpl.getTypes(_definingType.typeVariables);
+ List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(_definingType.typeParameters);
return type.substitute2(argumentTypes, parameterTypes) as Type2;
}
@@ -5453,7 +5474,7 @@
}
Type2 baseType = baseParameter.type;
List<Type2> argumentTypes = definingType.typeArguments;
- List<Type2> parameterTypes = TypeVariableTypeImpl.getTypes(definingType.typeVariables);
+ List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(definingType.typeParameters);
Type2 substitutedType = baseType.substitute2(argumentTypes, parameterTypes);
if (baseType == substitutedType) {
return baseParameter;
@@ -5828,7 +5849,7 @@
if (parameters.length == 0) {
return namedParameterTypes;
}
- List<Type2> typeParameters = TypeVariableTypeImpl.getTypes(typeVariables);
+ List<Type2> typeParameters = TypeParameterTypeImpl.getTypes(this.typeParameters);
for (ParameterElement parameter in parameters) {
if (identical(parameter.parameterKind, ParameterKind.NAMED)) {
namedParameterTypes[parameter.name] = parameter.type.substitute2(_typeArguments, typeParameters);
@@ -5841,7 +5862,7 @@
if (parameters.length == 0) {
return TypeImpl.EMPTY_ARRAY;
}
- List<Type2> typeParameters = TypeVariableTypeImpl.getTypes(typeVariables);
+ List<Type2> typeParameters = TypeParameterTypeImpl.getTypes(this.typeParameters);
List<Type2> types = new List<Type2>();
for (ParameterElement parameter in parameters) {
if (identical(parameter.parameterKind, ParameterKind.REQUIRED)) {
@@ -5855,7 +5876,7 @@
if (parameters.length == 0) {
return TypeImpl.EMPTY_ARRAY;
}
- List<Type2> typeParameters = TypeVariableTypeImpl.getTypes(typeVariables);
+ List<Type2> typeParameters = TypeParameterTypeImpl.getTypes(this.typeParameters);
List<Type2> types = new List<Type2>();
for (ParameterElement parameter in parameters) {
if (identical(parameter.parameterKind, ParameterKind.POSITIONAL)) {
@@ -5878,19 +5899,22 @@
}
Type2 get returnType {
Type2 baseReturnType = this.baseReturnType;
- return baseReturnType.substitute2(_typeArguments, TypeVariableTypeImpl.getTypes(typeVariables));
+ if (baseReturnType == null) {
+ return DynamicTypeImpl.instance;
+ }
+ return baseReturnType.substitute2(_typeArguments, TypeParameterTypeImpl.getTypes(typeParameters));
}
List<Type2> get typeArguments => _typeArguments;
- List<TypeVariableElement> get typeVariables {
+ List<TypeParameterElement> get typeParameters {
Element element = this.element;
if (element is FunctionTypeAliasElement) {
- return ((element as FunctionTypeAliasElement)).typeVariables;
+ return ((element as FunctionTypeAliasElement)).typeParameters;
}
ClassElement definingClass = element.getAncestor(ClassElement);
if (definingClass != null) {
- return definingClass.typeVariables;
+ return definingClass.typeParameters;
}
- return TypeVariableElementImpl.EMPTY_ARRAY;
+ return TypeParameterElementImpl.EMPTY_ARRAY;
}
int get hashCode {
Element element = this.element;
@@ -6322,9 +6346,9 @@
List<InterfaceType> get interfaces {
ClassElement classElement = element;
List<InterfaceType> interfaces = classElement.interfaces;
- List<TypeVariableElement> typeVariables = classElement.typeVariables;
+ List<TypeParameterElement> typeParameters = classElement.typeParameters;
List<Type2> parameterTypes = classElement.type.typeArguments;
- if (typeVariables.length == 0) {
+ if (typeParameters.length == 0) {
return interfaces;
}
int count = interfaces.length;
@@ -6387,9 +6411,9 @@
List<InterfaceType> get mixins {
ClassElement classElement = element;
List<InterfaceType> mixins = classElement.mixins;
- List<TypeVariableElement> typeVariables = classElement.typeVariables;
+ List<TypeParameterElement> typeParameters = classElement.typeParameters;
List<Type2> parameterTypes = classElement.type.typeArguments;
- if (typeVariables.length == 0) {
+ if (typeParameters.length == 0) {
return mixins;
}
int count = mixins.length;
@@ -6409,7 +6433,7 @@
return supertype.substitute2(_typeArguments, classElement.type.typeArguments);
}
List<Type2> get typeArguments => _typeArguments;
- List<TypeVariableElement> get typeVariables => element.typeVariables;
+ List<TypeParameterElement> get typeParameters => element.typeParameters;
int get hashCode {
ClassElement element = this.element;
if (element == null) {
@@ -6459,7 +6483,7 @@
bool isSubtypeOf(Type2 type2) {
if (identical(type2, DynamicTypeImpl.instance)) {
return true;
- } else if (type2 is TypeVariableType) {
+ } else if (type2 is TypeParameterType) {
return true;
} else if (type2 is FunctionType) {
ClassElement element = this.element;
@@ -6802,46 +6826,47 @@
}
}
/**
- * Instances of the class `TypeVariableTypeImpl` defines the behavior of objects representing
- * the type introduced by a type variable.
+ * Instances of the class `TypeParameterTypeImpl` defines the behavior of objects representing
+ * the type introduced by a type parameter.
*
* @coverage dart.engine.type
*/
-class TypeVariableTypeImpl extends TypeImpl implements TypeVariableType {
+class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
/**
- * An empty array of type variable types.
+ * An empty array of type parameter types.
*/
- static List<TypeVariableType> EMPTY_ARRAY = new List<TypeVariableType>(0);
+ static List<TypeParameterType> EMPTY_ARRAY = new List<TypeParameterType>(0);
/**
- * Return an array containing the type variable types defined by the given array of type variable
- * elements.
+ * Return an array containing the type parameter types defined by the given array of type
+ * parameter elements.
*
- * @param typeVariables the type variable elements defining the type variable types to be returned
- * @return the type variable types defined by the type variable elements
+ * @param typeParameters the type parameter elements defining the type parameter types to be
+ * returned
+ * @return the type parameter types defined by the type parameter elements
*/
- static List<TypeVariableType> getTypes(List<TypeVariableElement> typeVariables) {
- int count = typeVariables.length;
+ static List<TypeParameterType> getTypes(List<TypeParameterElement> typeParameters) {
+ int count = typeParameters.length;
if (count == 0) {
return EMPTY_ARRAY;
}
- List<TypeVariableType> types = new List<TypeVariableType>(count);
+ List<TypeParameterType> types = new List<TypeParameterType>(count);
for (int i = 0; i < count; i++) {
- types[i] = typeVariables[i].type;
+ types[i] = typeParameters[i].type;
}
return types;
}
/**
- * Initialize a newly created type variable to be declared by the given element and to have the
- * given name.
+ * Initialize a newly created type parameter type to be declared by the given element and to have
+ * the given name.
*
- * @param element the element representing the declaration of the type variable
+ * @param element the element representing the declaration of the type parameter
*/
- TypeVariableTypeImpl(TypeVariableElement element) : super(element, element.name);
- bool operator ==(Object object) => object is TypeVariableTypeImpl && element == ((object as TypeVariableTypeImpl)).element;
- TypeVariableElement get element => super.element as TypeVariableElement;
+ TypeParameterTypeImpl(TypeParameterElement element) : super(element, element.name);
+ bool operator ==(Object object) => object is TypeParameterTypeImpl && element == ((object as TypeParameterTypeImpl)).element;
+ TypeParameterElement get element => super.element as TypeParameterElement;
int get hashCode => element.hashCode;
bool isMoreSpecificThan(Type2 type) {
Type2 upperBound = element.bound;
@@ -7139,7 +7164,7 @@
* * <i>T</i> is bottom.
* * <i>S</i> is dynamic.
* * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
- * * <i>T</i> is a type variable and <i>S</i> is the upper bound of <i>T</i>.
+ * * <i>T</i> is a type parameter and <i>S</i> is the upper bound of <i>T</i>.
* * Covariance: <i>T</i> is of the form <i>I<T<sub>1</sub>, …, T<sub>n</sub>></i>
* and S</i> is of the form <i>I<S<sub>1</sub>, …, S<sub>n</sub>></i> and
* <i>T<sub>i</sub> « S<sub>i</sub></i>, <i>1 <= i <= n</i>.
@@ -7319,8 +7344,8 @@
InterfaceType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
}
/**
- * The interface `ParameterizedType` defines the behavior common to objects representing the
- * type with type parameters, such as class and function type alias.
+ * The interface `ParameterizedType` defines the behavior common to objects representing a
+ * type with type parameters, such as a class or function type alias.
*
* @coverage dart.engine.type
*/
@@ -7338,11 +7363,11 @@
List<Type2> get typeArguments;
/**
- * Return an array containing all of the type variables declared for this type.
+ * Return an array containing all of the type parameters declared for this type.
*
- * @return the type variables declared for this type
+ * @return the type parameters declared for this type
*/
- List<TypeVariableElement> get typeVariables;
+ List<TypeParameterElement> get typeParameters;
}
/**
* The interface `Type` defines the behavior of objects representing the declared type of
@@ -7467,13 +7492,13 @@
Type2 substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
}
/**
- * The interface `TypeVariableType` defines the behavior of objects representing the type
- * introduced by a type variable.
+ * The interface `TypeParameterType` defines the behavior of objects representing the type
+ * introduced by a type parameter.
*
* @coverage dart.engine.type
*/
-abstract class TypeVariableType implements Type2 {
- TypeVariableElement get element;
+abstract class TypeParameterType implements Type2 {
+ TypeParameterElement get element;
}
/**
* The interface `VoidType` defines the behavior of the unique object representing the type
diff --git a/pkg/analyzer_experimental/lib/src/generated/engine.dart b/pkg/analyzer_experimental/lib/src/generated/engine.dart
index eb510b8..44685da 100644
--- a/pkg/analyzer_experimental/lib/src/generated/engine.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/engine.dart
@@ -4,6 +4,7 @@
import 'java_core.dart';
import 'java_engine.dart';
import 'utilities_collection.dart';
+import 'utilities_general.dart';
import 'instrumentation.dart';
import 'error.dart';
import 'source.dart';
@@ -75,25 +76,14 @@
Logger _logger = Logger.NULL;
/**
- * A flag indicating whether the new analysis context should be created.
- */
- bool _useExperimentalContext = false;
-
- /**
* Create a new context in which analysis can be performed.
*
* @return the analysis context that was created
*/
AnalysisContext createAnalysisContext() {
if (Instrumentation.isNullLogger) {
- if (_useExperimentalContext) {
- return new DelegatingAnalysisContextImpl2();
- }
return new DelegatingAnalysisContextImpl();
}
- if (_useExperimentalContext) {
- return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl2());
- }
return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl());
}
@@ -105,13 +95,6 @@
Logger get logger => _logger;
/**
- * Return `true` if the new analysis context should be created.
- *
- * @return `true` if the new analysis context should be created
- */
- bool get useExperimentalContext => _useExperimentalContext;
-
- /**
* Set the logger that should receive information about errors within the analysis engine to the
* given logger.
*
@@ -121,15 +104,6 @@
void set logger(Logger logger2) {
this._logger = logger2 == null ? Logger.NULL : logger2;
}
-
- /**
- * Set whether the new analysis context should be created to the given flag.
- *
- * @param use `true` if the new analysis context should be created
- */
- void set useExperimentalContext(bool use) {
- _useExperimentalContext = use;
- }
}
/**
* Container with statistics about the [AnalysisContext].
@@ -137,7 +111,16 @@
abstract class AnalysisContentStatistics {
/**
- * @return the statistics for each kind of cached data.
+ * Return the exceptions that caused some entries to have a state of [CacheState#ERROR].
+ *
+ * @return the exceptions that caused some entries to have a state of [CacheState#ERROR]
+ */
+ List<AnalysisException> get exceptions;
+
+ /**
+ * Return the statistics for each kind of cached data.
+ *
+ * @return the statistics for each kind of cached data
*/
List<AnalysisContentStatistics_CacheRow> get cacheRows;
}
@@ -677,6 +660,13 @@
abstract class AnalysisOptions {
/**
+ * Return `true` if analysis is to generate dart2js related hint results.
+ *
+ * @return `true` if analysis is to generate dart2js related hint results
+ */
+ bool get dart2jsHint;
+
+ /**
* Return `true` if analysis is to generate hint results (e.g. type inference based
* information and pub best practices).
*
@@ -791,6 +781,55 @@
removedContainers.add(container);
}
}
+ String toString() {
+ JavaStringBuilder builder = new JavaStringBuilder();
+ bool needsSeparator = appendSources(builder, added3, false, "added");
+ needsSeparator = appendSources(builder, changed3, needsSeparator, "changed");
+ appendSources(builder, removed3, needsSeparator, "removed");
+ int count = removedContainers.length;
+ if (count > 0) {
+ if (removed3.isEmpty) {
+ if (needsSeparator) {
+ builder.append("; ");
+ }
+ builder.append("removed: from ");
+ builder.append(count);
+ builder.append(" containers");
+ } else {
+ builder.append(", and more from ");
+ builder.append(count);
+ builder.append(" containers");
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Append the given sources to the given builder, prefixed with the given label and possibly a
+ * separator.
+ *
+ * @param builder the builder to which the sources are to be appended
+ * @param sources the sources to be appended
+ * @param needsSeparator `true` if a separator is needed before the label
+ * @param label the label used to prefix the sources
+ * @return `true` if future lists of sources will need a separator
+ */
+ bool appendSources(JavaStringBuilder builder, List<Source> sources, bool needsSeparator, String label) {
+ if (sources.isEmpty) {
+ return needsSeparator;
+ }
+ if (needsSeparator) {
+ builder.append("; ");
+ }
+ builder.append(label);
+ String prefix = " ";
+ for (Source source in sources) {
+ builder.append(prefix);
+ builder.append(source.fullName);
+ prefix = ", ";
+ }
+ return true;
+ }
}
/**
* Instances of the class `AnalysisCache` implement an LRU cache of information related to
@@ -877,12 +916,12 @@
}
/**
- * Return a set containing all of the map entries mapping sources to cache entries. Clients should
- * not modify the returned set.
+ * Return a collection containing all of the map entries mapping sources to cache entries. Clients
+ * should not modify the returned collection.
*
- * @return a set containing all of the map entries mapping sources to cache entries
+ * @return a collection containing all of the map entries mapping sources to cache entries
*/
- Set<MapEntry<Source, SourceEntry>> entrySet() => getMapEntrySet(_sourceMap);
+ Iterable<MapEntry<Source, SourceEntry>> entrySet() => getMapEntrySet(_sourceMap);
/**
* Return the entry associated with the given source.
@@ -1285,15 +1324,17 @@
int _bitmask = 0;
/**
- * Mask indicating that this library is launchable: that the file has a main method.
+ * The index of the bit in the [bitmask] indicating that this library is launchable: that
+ * the file has a main method.
*/
- static int _LAUNCHABLE = 1 << 1;
+ static int _LAUNCHABLE_INDEX = 1;
/**
- * Mask indicating that the library is client code: that the library depends on the html library.
- * If the library is not "client code", then it is referenced as "server code".
+ * The index of the bit in the [bitmask] indicating that the library is client code: that
+ * the library depends on the html library. If the library is not "client code", then it is
+ * referred to as "server code".
*/
- static int _CLIENT_CODE = 1 << 2;
+ static int _CLIENT_CODE_INDEX = 2;
/**
* Flush any AST structures being maintained by this entry.
@@ -1404,11 +1445,11 @@
while (state != null) {
if (librarySource2 == state._librarySource) {
if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
- return _resolutionState._resolutionErrorsState;
+ return state._resolutionErrorsState;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
- return _resolutionState._resolvedUnitState;
+ return state._resolvedUnitState;
} else if (identical(descriptor, DartEntry.HINTS)) {
- return _resolutionState._hintsState;
+ return state._hintsState;
} else {
throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
}
@@ -1432,9 +1473,9 @@
} else if (identical(descriptor, DartEntry.INCLUDED_PARTS)) {
return _includedParts as Object;
} else if (identical(descriptor, DartEntry.IS_CLIENT)) {
- return ((_bitmask & _CLIENT_CODE) != 0 ? true : false) as Object;
+ return (BooleanArray.get2(_bitmask, _CLIENT_CODE_INDEX) as bool) as Object;
} else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
- return ((_bitmask & _LAUNCHABLE) != 0 ? true : false) as Object;
+ return (BooleanArray.get2(_bitmask, _LAUNCHABLE_INDEX) as bool) as Object;
} else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
return _parseErrors as Object;
} else if (identical(descriptor, DartEntry.PARSED_UNIT)) {
@@ -1695,10 +1736,10 @@
_includedParts = updatedValue(state, _includedParts, Source.EMPTY_ARRAY);
_includedPartsState = state;
} else if (identical(descriptor, DartEntry.IS_CLIENT)) {
- _bitmask = updatedValue2(state, _bitmask, _CLIENT_CODE);
+ _bitmask = updatedValue2(state, _bitmask, _CLIENT_CODE_INDEX);
_clientServerState = state;
} else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
- _bitmask = updatedValue2(state, _bitmask, _LAUNCHABLE);
+ _bitmask = updatedValue2(state, _bitmask, _LAUNCHABLE_INDEX);
_launchableState = state;
} else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
_parseErrors = updatedValue(state, _parseErrors, AnalysisError.NO_ERRORS);
@@ -1759,18 +1800,10 @@
_includedParts = value == null ? Source.EMPTY_ARRAY : (value as List<Source>);
_includedPartsState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.IS_CLIENT)) {
- if (((value as bool))) {
- _bitmask |= _CLIENT_CODE;
- } else {
- _bitmask &= ~_CLIENT_CODE;
- }
+ _bitmask = BooleanArray.set2(_bitmask, _CLIENT_CODE_INDEX, value as bool);
_clientServerState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
- if (((value as bool))) {
- _bitmask |= _LAUNCHABLE;
- } else {
- _bitmask &= ~_LAUNCHABLE;
- }
+ _bitmask = BooleanArray.set2(_bitmask, _LAUNCHABLE_INDEX, value as bool);
_launchableState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
_parseErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
@@ -1898,13 +1931,13 @@
* @param bitMask the mask used to access the bit whose state is being set
* @return the value of the data that should be kept in the cache
*/
- int updatedValue2(CacheState state, int currentValue, int bitMask) {
+ int updatedValue2(CacheState state, int currentValue, int bitIndex) {
if (identical(state, CacheState.VALID)) {
throw new IllegalArgumentException("Use setValue() to set the state to VALID");
} else if (identical(state, CacheState.IN_PROCESS)) {
return currentValue;
}
- return currentValue &= ~bitMask;
+ return BooleanArray.set2(currentValue, bitIndex, false);
}
}
/**
@@ -2345,6 +2378,14 @@
static final DataDescriptor<LineInfo> LINE_INFO = new DataDescriptor<LineInfo>("SourceEntry.LINE_INFO");
/**
+ * Return the exception that caused one or more values to have a state of [CacheState#ERROR]
+ * .
+ *
+ * @return the exception that caused one or more values to be uncomputable
+ */
+ AnalysisException get exception;
+
+ /**
* Return the kind of the source, or `null` if the kind is not currently cached.
*
* @return the kind of the source
@@ -2399,6 +2440,11 @@
int _modificationTime = 0;
/**
+ * The exception that caused one or more values to have a state of [CacheState#ERROR].
+ */
+ AnalysisException _exception;
+
+ /**
* The state of the cached line information.
*/
CacheState _lineInfoState = CacheState.INVALID;
@@ -2408,6 +2454,14 @@
* currently cached.
*/
LineInfo _lineInfo;
+
+ /**
+ * Return the exception that caused one or more values to have a state of [CacheState#ERROR]
+ * .
+ *
+ * @return the exception that caused one or more values to be uncomputable
+ */
+ AnalysisException get exception => _exception;
int get modificationTime => _modificationTime;
CacheState getState(DataDescriptor descriptor) {
if (identical(descriptor, SourceEntry.LINE_INFO)) {
@@ -2425,6 +2479,16 @@
}
/**
+ * Set the exception that caused one or more values to have a state of [CacheState#ERROR] to
+ * the given exception.
+ *
+ * @param exception the exception that caused one or more values to be uncomputable
+ */
+ void set exception(AnalysisException exception2) {
+ this._exception = exception2;
+ }
+
+ /**
* Set the most recent time at which the state of the source matched the state represented by this
* entry to the given time.
*
@@ -2516,17 +2580,19 @@
*/
class AnalysisContentStatisticsImpl implements AnalysisContentStatistics {
Map<String, AnalysisContentStatistics_CacheRow> _dataMap = new Map<String, AnalysisContentStatistics_CacheRow>();
+ Set<AnalysisException> _exceptions = new Set<AnalysisException>();
List<AnalysisContentStatistics_CacheRow> get cacheRows {
Iterable<AnalysisContentStatistics_CacheRow> items = _dataMap.values;
return new List.from(items);
}
+ List<AnalysisException> get exceptions => new List.from(_exceptions);
void putCacheItem(DartEntry dartEntry, DataDescriptor descriptor) {
- putCacheItem3(descriptor, dartEntry.getState(descriptor));
+ putCacheItem3(dartEntry, descriptor, dartEntry.getState(descriptor));
}
void putCacheItem2(DartEntry dartEntry, Source librarySource, DataDescriptor descriptor) {
- putCacheItem3(descriptor, dartEntry.getState2(descriptor, librarySource));
+ putCacheItem3(dartEntry, descriptor, dartEntry.getState2(descriptor, librarySource));
}
- void putCacheItem3(DataDescriptor rowDesc, CacheState state) {
+ void putCacheItem3(SourceEntry dartEntry, DataDescriptor rowDesc, CacheState state) {
String rowName = rowDesc.toString();
AnalysisContentStatisticsImpl_CacheRowImpl row = _dataMap[rowName] as AnalysisContentStatisticsImpl_CacheRowImpl;
if (row == null) {
@@ -2534,6 +2600,12 @@
_dataMap[rowName] = row;
}
row.incState(state);
+ if (identical(state, CacheState.ERROR)) {
+ AnalysisException exception = dartEntry.exception;
+ if (exception != null) {
+ javaSetAdd(_exceptions, exception);
+ }
+ }
}
}
class AnalysisContentStatisticsImpl_CacheRowImpl implements AnalysisContentStatistics_CacheRow {
@@ -2580,2431 +2652,6 @@
class AnalysisContextImpl implements InternalAnalysisContext {
/**
- * Helper for [getStatistics], puts the library-specific state into the given statistics
- * object.
- */
- static void putStatCacheItem(AnalysisContentStatisticsImpl statistics, DartEntry dartEntry, Source librarySource, DataDescriptor key) {
- statistics.putCacheItem3(key, dartEntry.getState2(key, librarySource));
- }
-
- /**
- * Helper for [getStatistics], puts the library independent state into the given
- * statistics object.
- */
- static void putStatCacheItem2(AnalysisContentStatisticsImpl statistics, SourceEntry entry, DataDescriptor key) {
- statistics.putCacheItem3(key, entry.getState(key));
- }
-
- /**
- * The set of analysis options controlling the behavior of this context.
- */
- AnalysisOptions _options = new AnalysisOptionsImpl();
-
- /**
- * The source factory used to create the sources that can be analyzed in this context.
- */
- SourceFactory _sourceFactory;
-
- /**
- * A table mapping the sources known to the context to the information known about the source.
- */
- Map<Source, SourceEntry> _sourceMap = new Map<Source, SourceEntry>();
-
- /**
- * An array containing the order in which sources will be analyzed by the method
- * [performAnalysisTask].
- */
- List<Source> _priorityOrder = Source.EMPTY_ARRAY;
-
- /**
- * A table mapping sources to the change notices that are waiting to be returned related to that
- * source.
- */
- Map<Source, ChangeNoticeImpl> _pendingNotices = new Map<Source, ChangeNoticeImpl>();
-
- /**
- * A list containing the most recently accessed sources with the most recently used at the end of
- * the list. When more sources are added than the maximum allowed then the least recently used
- * source will be removed and will have it's cached AST structure flushed.
- */
- List<Source> _recentlyUsed = new List<Source>();
-
- /**
- * The number of times that the flushing of information from the cache has been disabled without
- * being re-enabled.
- */
- int _cacheRemovalCount = 0;
-
- /**
- * The object used to synchronize access to all of the caches.
- */
- Object _cacheLock = new Object();
-
- /**
- * The maximum number of sources for which data should be kept in the cache.
- */
- static int _MAX_CACHE_SIZE = 64;
-
- /**
- * The maximum number of sources that can be on the priority list. This <b>must</b> be less than
- * the [MAX_CACHE_SIZE] in order to prevent an infinite loop in performAnalysisTask().
- *
- * @see #setAnalysisPriorityOrder(List)
- */
- static int _MAX_PRIORITY_LIST_SIZE = _MAX_CACHE_SIZE - 4;
-
- /**
- * The name of the 'src' attribute in a HTML tag.
- */
- static String _ATTRIBUTE_SRC = "src";
-
- /**
- * The name of the 'type' attribute in a HTML tag.
- */
- static String _ATTRIBUTE_TYPE = "type";
-
- /**
- * The name of the 'script' tag in an HTML file.
- */
- static String _TAG_SCRIPT = "script";
-
- /**
- * The value of the 'type' attribute of a 'script' tag that indicates that the script is written
- * in Dart.
- */
- static String _TYPE_DART = "application/dart";
-
- /**
- * Initialize a newly created analysis context.
- */
- AnalysisContextImpl() : super() {
- if (AnalysisEngine.instance.useExperimentalContext) {
- throw new RuntimeException("Should not be creating an instance of AnalysisContextImpl");
- }
- }
- void addSourceInfo(Source source, SourceEntry info) {
- _sourceMap[source] = info;
- }
- void applyChanges(ChangeSet changeSet) {
- if (changeSet.isEmpty) {
- return;
- }
- {
- List<Source> removedSources = new List<Source>.from(changeSet.removed3);
- for (SourceContainer container in changeSet.removedContainers) {
- addSourcesInContainer(removedSources, container);
- }
- bool addedDartSource = false;
- for (Source source in changeSet.added3) {
- if (sourceAvailable(source)) {
- addedDartSource = true;
- }
- }
- for (Source source in changeSet.changed3) {
- sourceChanged(source);
- }
- for (Source source in removedSources) {
- sourceRemoved(source);
- }
- if (addedDartSource) {
- for (MapEntry<Source, SourceEntry> mapEntry in getMapEntrySet(_sourceMap)) {
- if (!mapEntry.getKey().isInSystemLibrary && mapEntry.getValue() is DartEntry) {
- DartEntryImpl dartCopy = ((mapEntry.getValue() as DartEntry)).writableCopy;
- dartCopy.invalidateAllResolutionInformation();
- mapEntry.setValue(dartCopy);
- }
- }
- }
- }
- }
- String computeDocumentationComment(Element element) {
- if (element == null) {
- return null;
- }
- Source source = element.source;
- if (source == null) {
- return null;
- }
- CompilationUnit unit = parseCompilationUnit(source);
- if (unit == null) {
- return null;
- }
- NodeLocator locator = new NodeLocator.con1(element.nameOffset);
- ASTNode nameNode = locator.searchWithin(unit);
- while (nameNode != null) {
- if (nameNode is AnnotatedNode) {
- Comment comment = ((nameNode as AnnotatedNode)).documentationComment;
- if (comment == null) {
- return null;
- }
- JavaStringBuilder builder = new JavaStringBuilder();
- List<Token> tokens = comment.tokens;
- for (int i = 0; i < tokens.length; i++) {
- if (i > 0) {
- builder.append('\n');
- }
- builder.append(tokens[i].lexeme);
- }
- return builder.toString();
- }
- nameNode = nameNode.parent;
- }
- return null;
- }
- List<AnalysisError> computeErrors(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry is DartEntry) {
- List<AnalysisError> errors = new List<AnalysisError>();
- DartEntry dartEntry = sourceEntry as DartEntry;
- ListUtilities.addAll(errors, internalGetDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
- if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) {
- ListUtilities.addAll(errors, internalGetDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
- } else {
- List<Source> libraries = getLibrariesContaining(source);
- for (Source librarySource in libraries) {
- ListUtilities.addAll(errors, internalGetDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS));
- }
- }
- if (errors.isEmpty) {
- return AnalysisError.NO_ERRORS;
- }
- return new List.from(errors);
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- return internalGetHtmlResolutionData(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS, AnalysisError.NO_ERRORS);
- }
- return AnalysisError.NO_ERRORS;
- }
- List<Source> computeExportedLibraries(Source source) => internalGetDartParseData2(source, DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_ARRAY);
- HtmlElement computeHtmlElement(Source source) {
- HtmlEntry htmlEntry = getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- return null;
- }
- CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
- if (elementState != CacheState.ERROR && elementState != CacheState.VALID) {
- htmlEntry = internalResolveHtml(source);
- }
- return htmlEntry.getValue(HtmlEntry.ELEMENT);
- }
- List<Source> computeImportedLibraries(Source source) => internalGetDartParseData2(source, DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_ARRAY);
- SourceKind computeKindOf(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry == null) {
- return SourceKind.UNKNOWN;
- } else if (sourceEntry is DartEntry) {
- try {
- return internalGetDartParseData(source, sourceEntry as DartEntry, DartEntry.SOURCE_KIND);
- } on AnalysisException catch (exception) {
- return SourceKind.UNKNOWN;
- }
- }
- return sourceEntry.kind;
- }
- LibraryElement computeLibraryElement(Source source) {
- {
- DartEntry dartEntry = getDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- LibraryElement element = dartEntry.getValue(DartEntry.ELEMENT);
- if (element == null) {
- LibraryResolver resolver = new LibraryResolver(this);
- try {
- element = resolver.resolveLibrary(source, true);
- recordResolutionResults(resolver);
- } on AnalysisException catch (exception) {
- DartEntryImpl dartCopy = getDartEntry(source).writableCopy;
- dartCopy.recordResolutionError();
- _sourceMap[source] = dartCopy;
- AnalysisEngine.instance.logger.logError2("Could not resolve the library ${source.fullName}", exception);
- }
- }
- return element;
- }
- }
- LineInfo computeLineInfo(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry is HtmlEntry) {
- return internalGetHtmlParseData(source, SourceEntry.LINE_INFO, null);
- } else if (sourceEntry is DartEntry) {
- return internalGetDartParseData2(source, SourceEntry.LINE_INFO, null);
- }
- return null;
- }
- ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) {
- while (true) {
- {
- SourceEntry sourceEntry = getSourceEntry(source);
- if (sourceEntry is! DartEntry) {
- throw new AnalysisException.con1("computeResolvableCompilationUnit for non-Dart: ${source.fullName}");
- }
- DartEntry dartEntry = sourceEntry as DartEntry;
- if (identical(dartEntry.getState(DartEntry.PARSED_UNIT), CacheState.ERROR)) {
- throw new AnalysisException.con1("Internal error: computeResolvableCompilationUnit could not parse ${source.fullName}");
- }
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- CompilationUnit unit = dartCopy.resolvableCompilationUnit;
- if (unit != null) {
- _sourceMap[source] = dartCopy;
- return new ResolvableCompilationUnit(dartCopy.modificationTime, unit);
- }
- }
- internalParseDart(source);
- }
- }
- ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) {
- HtmlEntry htmlEntry = getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- throw new AnalysisException.con1("computeResolvableHtmlUnit invoked for non-HTML file: ${source.fullName}");
- }
- htmlEntry = internalCacheHtmlParseData(source, htmlEntry, [HtmlEntry.PARSED_UNIT]);
- HtmlUnit unit = htmlEntry.getValue(HtmlEntry.PARSED_UNIT);
- if (unit == null) {
- throw new AnalysisException.con1("Internal error: computeResolvableHtmlUnit could not parse ${source.fullName}");
- }
- return new ResolvableHtmlUnit(htmlEntry.modificationTime, unit);
- }
- AnalysisContext extractContext(SourceContainer container) => extractContextInto(container, AnalysisEngine.instance.createAnalysisContext() as InternalAnalysisContext);
- InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) {
- List<Source> sourcesToRemove = new List<Source>();
- {
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- Source source = entry.getKey();
- if (container.contains(source)) {
- sourcesToRemove.add(source);
- newContext.addSourceInfo(source, entry.getValue().writableCopy);
- }
- }
- }
- return newContext;
- }
- AnalysisOptions get analysisOptions => _options;
- Element getElement(ElementLocation location) {
- try {
- List<String> components = ((location as ElementLocationImpl)).components;
- Source librarySource = computeSourceFromEncoding(components[0]);
- ElementImpl element = computeLibraryElement(librarySource) as ElementImpl;
- for (int i = 1; i < components.length; i++) {
- if (element == null) {
- return null;
- }
- element = element.getChild(components[i]);
- }
- return element;
- } on AnalysisException catch (exception) {
- return null;
- }
- }
- AnalysisErrorInfo getErrors(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- return new AnalysisErrorInfoImpl(dartEntry.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- return new AnalysisErrorInfoImpl(htmlEntry.allErrors, htmlEntry.getValue(SourceEntry.LINE_INFO));
- }
- return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
- }
- HtmlElement getHtmlElement(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry is HtmlEntry) {
- return ((sourceEntry as HtmlEntry)).getValue(HtmlEntry.ELEMENT);
- }
- return null;
- }
- List<Source> getHtmlFilesReferencing(Source source) {
- SourceKind sourceKind = getKindOf(source);
- if (sourceKind == null) {
- return Source.EMPTY_ARRAY;
- }
- {
- List<Source> htmlSources = new List<Source>();
- while (true) {
- if (sourceKind == SourceKind.LIBRARY) {
- } else if (sourceKind == SourceKind.PART) {
- List<Source> librarySources = getLibrariesContaining(source);
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
- if (identical(sourceEntry.kind, SourceKind.HTML)) {
- List<Source> referencedLibraries = ((sourceEntry as HtmlEntry)).getValue(HtmlEntry.REFERENCED_LIBRARIES);
- if (containsAny(referencedLibraries, librarySources)) {
- htmlSources.add(entry.getKey());
- }
- }
- }
- }
- break;
- }
- if (htmlSources.isEmpty) {
- return Source.EMPTY_ARRAY;
- }
- return new List.from(htmlSources);
- }
- }
- List<Source> get htmlSources => getSources(SourceKind.HTML);
- SourceKind getKindOf(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry == null) {
- return SourceKind.UNKNOWN;
- }
- return sourceEntry.kind;
- }
- List<Source> get launchableClientLibrarySources {
- List<Source> sources = new List<Source>();
- {
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- Source source = entry.getKey();
- SourceEntry sourceEntry = entry.getValue();
- if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
- sources.add(source);
- }
- }
- }
- return new List.from(sources);
- }
- List<Source> get launchableServerLibrarySources {
- List<Source> sources = new List<Source>();
- {
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- Source source = entry.getKey();
- SourceEntry sourceEntry = entry.getValue();
- if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
- sources.add(source);
- }
- }
- }
- return new List.from(sources);
- }
- List<Source> getLibrariesContaining(Source source) {
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry != null && identical(sourceEntry.kind, SourceKind.LIBRARY)) {
- return <Source> [source];
- }
- List<Source> librarySources = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- sourceEntry = entry.getValue();
- if (identical(sourceEntry.kind, SourceKind.LIBRARY)) {
- if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.INCLUDED_PARTS), source)) {
- librarySources.add(entry.getKey());
- }
- }
- }
- if (librarySources.isEmpty) {
- return Source.EMPTY_ARRAY;
- }
- return new List.from(librarySources);
- }
- }
- List<Source> getLibrariesDependingOn(Source librarySource) {
- {
- List<Source> dependentLibraries = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
- if (identical(sourceEntry.kind, SourceKind.LIBRARY)) {
- if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.EXPORTED_LIBRARIES), librarySource)) {
- dependentLibraries.add(entry.getKey());
- }
- if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.IMPORTED_LIBRARIES), librarySource)) {
- dependentLibraries.add(entry.getKey());
- }
- }
- }
- if (dependentLibraries.isEmpty) {
- return Source.EMPTY_ARRAY;
- }
- return new List.from(dependentLibraries);
- }
- }
- LibraryElement getLibraryElement(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry is DartEntry) {
- return ((sourceEntry as DartEntry)).getValue(DartEntry.ELEMENT);
- }
- return null;
- }
- List<Source> get librarySources => getSources(SourceKind.LIBRARY);
- LineInfo getLineInfo(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry != null) {
- return sourceEntry.getValue(SourceEntry.LINE_INFO);
- }
- return null;
- }
- Namespace getPublicNamespace(LibraryElement library) {
- Source source = library.definingCompilationUnit.source;
- DartEntry dartEntry = getReadableDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- {
- Namespace namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
- if (namespace == null) {
- NamespaceBuilder builder = new NamespaceBuilder();
- namespace = builder.createPublicNamespace(library);
- DartEntryImpl dartCopy = getDartEntry(source).writableCopy;
- dartCopy.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
- _sourceMap[source] = dartCopy;
- }
- return namespace;
- }
- }
- Namespace getPublicNamespace2(Source source) {
- DartEntry dartEntry = getReadableDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- {
- Namespace namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
- if (namespace == null) {
- LibraryElement library = computeLibraryElement(source);
- if (library == null) {
- return null;
- }
- NamespaceBuilder builder = new NamespaceBuilder();
- namespace = builder.createPublicNamespace(library);
- DartEntryImpl dartCopy = getDartEntry(source).writableCopy;
- dartCopy.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
- _sourceMap[source] = dartCopy;
- }
- return namespace;
- }
- }
- CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
- if (library == null) {
- return null;
- }
- return getResolvedCompilationUnit2(unitSource, library.source);
- }
- CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) {
- SourceEntry sourceEntry = getReadableSourceEntry(unitSource);
- if (sourceEntry is DartEntry) {
- return ((sourceEntry as DartEntry)).getValue2(DartEntry.RESOLVED_UNIT, librarySource);
- }
- return null;
- }
- SourceFactory get sourceFactory => _sourceFactory;
-
- /**
- * Return a list of the sources that would be processed by [performAnalysisTask]. This
- * method is intended to be used for testing purposes only.
- *
- * @return a list of the sources that would be processed by [performAnalysisTask]
- */
- List<Source> get sourcesNeedingProcessing {
- List<Source> sources = new List<Source>();
- {
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- CacheState parsedUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
- CacheState elementState = dartEntry.getState(DartEntry.ELEMENT);
- if (identical(parsedUnitState, CacheState.INVALID) || identical(elementState, CacheState.INVALID)) {
- sources.add(entry.getKey());
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
- CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
- if (identical(parsedUnitState, CacheState.INVALID) || identical(elementState, CacheState.INVALID)) {
- sources.add(entry.getKey());
- }
- }
- }
- }
- return sources;
- }
- AnalysisContentStatistics get statistics {
- AnalysisContentStatisticsImpl statistics = new AnalysisContentStatisticsImpl();
- {
- for (MapEntry<Source, SourceEntry> mapEntry in getMapEntrySet(_sourceMap)) {
- SourceEntry entry = mapEntry.getValue();
- if (entry is DartEntry) {
- Source source = mapEntry.getKey();
- DartEntry dartEntry = entry as DartEntry;
- SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
- putStatCacheItem2(statistics, dartEntry, DartEntry.PARSE_ERRORS);
- putStatCacheItem2(statistics, dartEntry, DartEntry.PARSED_UNIT);
- putStatCacheItem2(statistics, dartEntry, DartEntry.SOURCE_KIND);
- putStatCacheItem2(statistics, dartEntry, DartEntry.LINE_INFO);
- if (identical(kind, SourceKind.LIBRARY)) {
- putStatCacheItem2(statistics, dartEntry, DartEntry.ELEMENT);
- putStatCacheItem2(statistics, dartEntry, DartEntry.EXPORTED_LIBRARIES);
- putStatCacheItem2(statistics, dartEntry, DartEntry.IMPORTED_LIBRARIES);
- putStatCacheItem2(statistics, dartEntry, DartEntry.INCLUDED_PARTS);
- putStatCacheItem2(statistics, dartEntry, DartEntry.IS_CLIENT);
- putStatCacheItem2(statistics, dartEntry, DartEntry.IS_LAUNCHABLE);
- }
- List<Source> librarySources = getLibrariesContaining(source);
- for (Source librarySource in librarySources) {
- putStatCacheItem(statistics, dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
- putStatCacheItem(statistics, dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
- }
- }
- }
- }
- return statistics;
- }
- bool isClientLibrary(Source librarySource) {
- SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- return dartEntry.getValue(DartEntry.IS_CLIENT) && dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
- }
- return false;
- }
- bool isServerLibrary(Source librarySource) {
- SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- return !dartEntry.getValue(DartEntry.IS_CLIENT) && dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
- }
- return false;
- }
- void mergeContext(AnalysisContext context) {
- if (context is InstrumentedAnalysisContextImpl) {
- context = ((context as InstrumentedAnalysisContextImpl)).basis;
- }
- if (context is! AnalysisContextImpl) {
- return;
- }
- {
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(((context as AnalysisContextImpl))._sourceMap)) {
- Source newSource = entry.getKey();
- SourceEntry existingEntry = getSourceEntry(newSource);
- if (existingEntry == null) {
- _sourceMap[newSource] = entry.getValue().writableCopy;
- } else {
- }
- }
- }
- }
- CompilationUnit parseCompilationUnit(Source source) {
- DartEntry dartEntry = getReadableDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- CompilationUnit unit = dartEntry.anyParsedCompilationUnit;
- if (unit == null) {
- CacheState state = dartEntry.getState(DartEntry.PARSED_UNIT);
- while (state != CacheState.VALID && state != CacheState.ERROR) {
- dartEntry = internalParseDart(source);
- state = dartEntry.getState(DartEntry.PARSED_UNIT);
- }
- unit = dartEntry.anyParsedCompilationUnit;
- }
- return unit;
- }
- HtmlUnit parseHtmlUnit(Source source) => internalGetHtmlParseData(source, HtmlEntry.PARSED_UNIT, null);
- List<ChangeNotice> performAnalysisTask() {
- {
- if (!performSingleAnalysisTask() && _pendingNotices.isEmpty) {
- return null;
- }
- if (_pendingNotices.isEmpty) {
- return ChangeNoticeImpl.EMPTY_ARRAY;
- }
- List<ChangeNotice> notices = new List.from(_pendingNotices.values);
- _pendingNotices.clear();
- return notices;
- }
- }
- 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();
- DartEntry dartEntry = getDartEntry(librarySource);
- if (dartEntry != null) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- recordElementData(dartCopy, library, htmlSource);
- _sourceMap[librarySource] = dartCopy;
- }
- }
- }
- }
- CompilationUnit resolveCompilationUnit(Source source2, LibraryElement library) {
- if (library == null) {
- return null;
- }
- return resolveCompilationUnit2(source2, library.source);
- }
- CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) {
- {
- accessed(unitSource);
- DartEntry dartEntry = getDartEntry(unitSource);
- if (dartEntry == null) {
- return null;
- }
- CompilationUnit unit = dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource);
- if (unit == null) {
- disableCacheRemoval();
- try {
- LibraryElement libraryElement = computeLibraryElement(librarySource);
- unit = dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource);
- if (unit == null && libraryElement != null) {
- Source coreLibrarySource = libraryElement.context.sourceFactory.forUri(DartSdk.DART_CORE);
- LibraryElement coreElement = computeLibraryElement(coreLibrarySource);
- TypeProvider typeProvider = new TypeProviderImpl(coreElement);
- ResolvableCompilationUnit resolvableUnit = computeResolvableCompilationUnit(unitSource);
- CompilationUnit unitAST = resolvableUnit.compilationUnit;
- new DeclarationResolver().resolve(unitAST, find(libraryElement, unitSource));
- RecordingErrorListener errorListener = new RecordingErrorListener();
- TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor.con2(libraryElement, unitSource, typeProvider, errorListener);
- unitAST.accept(typeResolverVisitor);
- InheritanceManager inheritanceManager = new InheritanceManager(libraryElement);
- ResolverVisitor resolverVisitor = new ResolverVisitor.con2(libraryElement, unitSource, typeProvider, inheritanceManager, errorListener);
- unitAST.accept(resolverVisitor);
- for (ProxyConditionalAnalysisError conditionalCode in resolverVisitor.proxyConditionalAnalysisErrors) {
- if (conditionalCode.shouldIncludeErrorCode()) {
- resolverVisitor.reportError(conditionalCode.analysisError);
- }
- }
- ErrorReporter errorReporter = new ErrorReporter(errorListener, unitSource);
- ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, libraryElement, typeProvider, inheritanceManager);
- unitAST.accept(errorVerifier);
- ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, typeProvider);
- unitAST.accept(constantVerifier);
- unitAST.resolutionErrors = errorListener.errors;
- DartEntryImpl dartCopy = getDartEntry(unitSource).writableCopy;
- dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, unitAST);
- _sourceMap[unitSource] = dartCopy;
- unit = unitAST;
- }
- } finally {
- enableCacheRemoval();
- }
- }
- return unit;
- }
- }
- HtmlUnit resolveHtmlUnit(Source source) => parseHtmlUnit(source);
- void set analysisOptions(AnalysisOptions options2) {
- {
- this._options = options2;
- invalidateAllResults();
- }
- }
- void set analysisPriorityOrder(List<Source> sources) {
- {
- if (sources == null || sources.isEmpty) {
- _priorityOrder = Source.EMPTY_ARRAY;
- } else {
- while (sources.remove(null)) {
- }
- int count = Math.min(sources.length, _MAX_PRIORITY_LIST_SIZE);
- _priorityOrder = new List<Source>(count);
- for (int i = 0; i < count; i++) {
- _priorityOrder[i] = sources[i];
- }
- }
- }
- }
- void setContents(Source source, String contents) {
- {
- if (_sourceFactory.setContents(source, contents)) {
- sourceChanged(source);
- }
- }
- }
- void set sourceFactory(SourceFactory factory) {
- {
- if (identical(_sourceFactory, factory)) {
- return;
- } else if (factory.context != null) {
- throw new IllegalStateException("Source factories cannot be shared between contexts");
- }
- if (_sourceFactory != null) {
- _sourceFactory.context = null;
- }
- factory.context = this;
- _sourceFactory = factory;
- invalidateAllResults();
- }
- }
- Iterable<Source> sourcesToResolve(List<Source> changedSources) {
- List<Source> librarySources = new List<Source>();
- for (Source source in changedSources) {
- if (identical(computeKindOf(source), SourceKind.LIBRARY)) {
- librarySources.add(source);
- }
- }
- return librarySources;
- }
-
- /**
- * Record that the given source was just accessed for some unspecified purpose.
- *
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source that was accessed
- */
- void accessed(Source source) {
- if (_recentlyUsed.remove(source)) {
- _recentlyUsed.add(source);
- return;
- }
- if (_cacheRemovalCount == 0 && _recentlyUsed.length >= _MAX_CACHE_SIZE) {
- flushAstFromCache();
- }
- _recentlyUsed.add(source);
- }
-
- /**
- * Add all of the sources contained in the given source container to the given list of sources.
- *
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param sources the list to which sources are to be added
- * @param container the source container containing the sources to be added to the list
- */
- void addSourcesInContainer(List<Source> sources, SourceContainer container) {
- for (Source source in _sourceMap.keys.toSet()) {
- if (container.contains(source)) {
- sources.add(source);
- }
- }
- }
-
- /**
- * Given the encoded form of a source, use the source factory to reconstitute the original source.
- *
- * @param encoding the encoded form of a source
- * @return the source represented by the encoding
- */
- Source computeSourceFromEncoding(String encoding) {
- {
- return _sourceFactory.fromEncoding(encoding);
- }
- }
-
- /**
- * Return `true` if the given array of sources contains the given source.
- *
- * @param sources the sources being searched
- * @param targetSource the source being searched for
- * @return `true` if the given source is in the array
- */
- bool contains(List<Source> sources, Source targetSource) {
- for (Source source in sources) {
- if (source == targetSource) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Return `true` if the given array of sources contains any of the given target sources.
- *
- * @param sources the sources being searched
- * @param targetSources the sources being searched for
- * @return `true` if any of the given target sources are in the array
- */
- bool containsAny(List<Source> sources, List<Source> targetSources) {
- for (Source targetSource in targetSources) {
- if (contains(sources, targetSource)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Create a source information object suitable for the given source. Return the source information
- * object that was created, or `null` if the source should not be tracked by this context.
- *
- * @param source the source for which an information object is being created
- * @return the source information object that was created
- */
- SourceEntry createSourceEntry(Source source) {
- String name = source.shortName;
- if (AnalysisEngine.isHtmlFileName(name)) {
- HtmlEntryImpl htmlEntry = new HtmlEntryImpl();
- htmlEntry.modificationTime = source.modificationStamp;
- _sourceMap[source] = htmlEntry;
- return htmlEntry;
- } else {
- DartEntryImpl dartEntry = new DartEntryImpl();
- dartEntry.modificationTime = source.modificationStamp;
- _sourceMap[source] = dartEntry;
- return dartEntry;
- }
- }
-
- /**
- * Disable flushing information from the cache until [enableCacheRemoval] has been
- * called.
- */
- void disableCacheRemoval() {
- _cacheRemovalCount++;
- }
-
- /**
- * Re-enable flushing information from the cache.
- */
- void enableCacheRemoval() {
- if (_cacheRemovalCount > 0) {
- _cacheRemovalCount--;
- }
- if (_cacheRemovalCount == 0) {
- while (_recentlyUsed.length >= _MAX_CACHE_SIZE) {
- flushAstFromCache();
- }
- }
- }
-
- /**
- * Search the compilation units that are part of the given library and return the element
- * representing the compilation unit with the given source. Return `null` if there is no
- * such compilation unit.
- *
- * @param libraryElement the element representing the library being searched through
- * @param unitSource the source for the compilation unit whose element is to be returned
- * @return the element representing the compilation unit
- */
- CompilationUnitElement find(LibraryElement libraryElement, Source unitSource) {
- CompilationUnitElement element = libraryElement.definingCompilationUnit;
- if (element.source == unitSource) {
- return element;
- }
- for (CompilationUnitElement partElement in libraryElement.parts) {
- if (partElement.source == unitSource) {
- return partElement;
- }
- }
- return null;
- }
-
- /**
- * Flush one AST structure from the cache.
- *
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
- */
- void flushAstFromCache() {
- Source removedSource = removeAstToFlush();
- SourceEntry sourceEntry = _sourceMap[removedSource];
- if (sourceEntry is HtmlEntry) {
- HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.FLUSHED);
- _sourceMap[removedSource] = htmlCopy;
- } else if (sourceEntry is DartEntry) {
- DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- for (Source librarySource in getLibrariesContaining(removedSource)) {
- dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.FLUSHED);
- }
- _sourceMap[removedSource] = dartCopy;
- }
- }
-
- /**
- * Return the compilation unit information associated with the given source, or `null` if
- * the source is not known to this context. This method should be used to access the compilation
- * unit information rather than accessing the compilation unit map directly because sources in the
- * SDK are implicitly part of every analysis context and are therefore only added to the map when
- * first accessed.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source for which information is being sought
- * @return the compilation unit information associated with the given source
- */
- DartEntry getDartEntry(Source source) {
- SourceEntry sourceEntry = getSourceEntry(source);
- if (sourceEntry == null) {
- sourceEntry = new DartEntryImpl();
- _sourceMap[source] = sourceEntry;
- return sourceEntry as DartEntry;
- } else if (sourceEntry is DartEntry) {
- return sourceEntry as DartEntry;
- }
- return null;
- }
-
- /**
- * Return the sources of libraries that are referenced in the specified HTML file.
- *
- * @param htmlSource the source of the HTML file being analyzed
- * @param htmlUnit the AST for the HTML file being analyzed
- * @return the sources of libraries that are referenced in the HTML file
- */
- List<Source> getLibrarySources2(Source htmlSource, HtmlUnit htmlUnit) {
- List<Source> libraries = new List<Source>();
- htmlUnit.accept(new RecursiveXmlVisitor_6(this, htmlSource, libraries));
- if (libraries.isEmpty) {
- return Source.EMPTY_ARRAY;
- }
- return new List.from(libraries);
- }
-
- /**
- * Look through the cache for a task that needs to be performed. Return the task that was found,
- * or `null` if there is no more work to be done.
- *
- * @return the next task that needs to be performed
- */
- AnalysisContextImpl_AnalysisTask get nextTaskAnalysisTask {
- {
- for (Source source in _priorityOrder) {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
- if (identical(parseErrorsState, CacheState.INVALID) || identical(parseErrorsState, CacheState.FLUSHED)) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_ParseDartTask(this, source);
- }
- CacheState parseUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
- if (identical(parseUnitState, CacheState.INVALID) || identical(parseUnitState, CacheState.FLUSHED)) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.IN_PROCESS);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_ParseDartTask(this, source);
- }
- for (Source librarySource in getLibrariesContaining(source)) {
- SourceEntry libraryEntry = _sourceMap[librarySource];
- if (libraryEntry is DartEntry) {
- CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
- if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
- DartEntryImpl libraryCopy = ((libraryEntry as DartEntry)).writableCopy;
- libraryCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
- _sourceMap[librarySource] = libraryCopy;
- return new AnalysisContextImpl_ResolveDartLibraryTask(this, librarySource);
- }
- }
- CacheState resolvedUnitState = dartEntry.getState2(DartEntry.RESOLVED_UNIT, librarySource);
- if (identical(resolvedUnitState, CacheState.INVALID) || identical(resolvedUnitState, CacheState.FLUSHED)) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.IN_PROCESS);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_ResolveDartUnitTask(this, source, librarySource);
- }
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
- if (identical(parsedUnitState, CacheState.INVALID) || identical(parsedUnitState, CacheState.FLUSHED)) {
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.IN_PROCESS);
- _sourceMap[source] = htmlCopy;
- return new AnalysisContextImpl_ParseHtmlTask(this, source);
- }
- CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
- if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.IN_PROCESS);
- _sourceMap[source] = htmlCopy;
- return new AnalysisContextImpl_ResolveHtmlTask(this, source);
- }
- }
- }
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- if (identical(dartEntry.getState(DartEntry.PARSED_UNIT), CacheState.INVALID)) {
- Source source = entry.getKey();
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_ParseDartTask(this, source);
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- if (identical(htmlEntry.getState(HtmlEntry.PARSED_UNIT), CacheState.INVALID)) {
- Source source = entry.getKey();
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.IN_PROCESS);
- _sourceMap[source] = htmlCopy;
- return new AnalysisContextImpl_ParseHtmlTask(this, source);
- }
- }
- }
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
- if (sourceEntry is DartEntry && identical(sourceEntry.kind, SourceKind.LIBRARY)) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- if (identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
- Source source = entry.getKey();
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_ResolveDartLibraryTask(this, source);
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- if (identical(htmlEntry.getState(HtmlEntry.ELEMENT), CacheState.INVALID)) {
- Source source = entry.getKey();
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.IN_PROCESS);
- _sourceMap[source] = htmlCopy;
- return new AnalysisContextImpl_ResolveHtmlTask(this, source);
- }
- }
- }
- return null;
- }
- }
-
- /**
- * Return a change notice for the given source, creating one if one does not already exist.
- *
- * @param source the source for which changes are being reported
- * @return a change notice for the given source
- */
- ChangeNoticeImpl getNotice(Source source) {
- ChangeNoticeImpl notice = _pendingNotices[source];
- if (notice == null) {
- notice = new ChangeNoticeImpl(source);
- _pendingNotices[source] = notice;
- }
- return notice;
- }
-
- /**
- * Return the cache entry associated with the given source, or `null` if the source is not a
- * Dart file.
- *
- * @param source the source for which a cache entry is being sought
- * @return the source cache entry associated with the given source
- */
- DartEntry getReadableDartEntry(Source source) {
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(source);
- }
- if (sourceEntry is DartEntry) {
- accessed(source);
- return sourceEntry as DartEntry;
- }
- return null;
- }
- }
-
- /**
- * Return the cache entry associated with the given source, or `null` if the source is not
- * an HTML file.
- *
- * @param source the source for which a cache entry is being sought
- * @return the source cache entry associated with the given source
- */
- HtmlEntry getReadableHtmlEntry(Source source) {
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(source);
- }
- if (sourceEntry is HtmlEntry) {
- accessed(source);
- return sourceEntry as HtmlEntry;
- }
- return null;
- }
- }
-
- /**
- * Return the cache entry associated with the given source, or `null` if there is no entry
- * associated with the source.
- *
- * @param source the source for which a cache entry is being sought
- * @return the source cache entry associated with the given source
- */
- SourceEntry getReadableSourceEntry(Source source) {
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(source);
- }
- if (sourceEntry != null) {
- accessed(source);
- }
- return sourceEntry;
- }
- }
-
- /**
- * Return the source information associated with the given source, or `null` if the source
- * is not known to this context. This method should be used to access the source information
- * rather than accessing the source map directly because sources in the SDK are implicitly part of
- * every analysis context and are therefore only added to the map when first accessed.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source for which information is being sought
- * @return the source information associated with the given source
- */
- SourceEntry getSourceEntry(Source source) {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(source);
- }
- return sourceEntry;
- }
-
- /**
- * Return an array containing all of the sources known to this context that have the given kind.
- *
- * @param kind the kind of sources to be returned
- * @return all of the sources known to this context that have the given kind
- */
- List<Source> getSources(SourceKind kind2) {
- List<Source> sources = new List<Source>();
- {
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- if (identical(entry.getValue().kind, kind2)) {
- sources.add(entry.getKey());
- }
- }
- }
- return new List.from(sources);
- }
-
- /**
- * Given a source for an HTML file, return a cache entry in which all of the data represented by
- * the given descriptors is available. This method assumes that the data can be produced by
- * parsing the source if it is not already cached.
- *
- * @param htmlEntry the cache entry associated with the HTML file
- * @param descriptor the descriptor representing the data to be returned
- * @return a cache entry containing the required data
- */
- bool hasHtmlParseDataCached(HtmlEntry htmlEntry, List<DataDescriptor> descriptors) {
- for (DataDescriptor descriptor in descriptors) {
- CacheState state = htmlEntry.getState(descriptor);
- if (state != CacheState.VALID && state != CacheState.ERROR) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Given a source for a Dart file, return a cache entry in which the data represented by the given
- * descriptor is available. This method assumes that the data can be produced by parsing the
- * source if it is not already cached.
- *
- * @param source the source representing the Dart file
- * @param dartEntry the cache entry associated with the Dart file
- * @param descriptor the descriptor representing the data to be returned
- * @return a cache entry containing the required data
- * @throws AnalysisException if data could not be returned because the source could not be
- * resolved
- */
- DartEntry internalCacheDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
- CacheState state = dartEntry.getState(descriptor);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- dartEntry = internalParseDart(source);
- state = dartEntry.getState(descriptor);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return a cache entry in which
- * all of the data represented by the given descriptors is available. This method assumes that the
- * data can be produced by resolving the source in the context of the library if it is not already
- * cached.
- *
- * @param unitSource the source representing the Dart file
- * @param librarySource the source representing the library containing the Dart file
- * @param dartEntry the cache entry associated with the Dart file
- * @param descriptor the descriptor representing the data to be returned
- * @return the requested data about the given source
- * @throws AnalysisException if data could not be returned because the source could not be parsed
- */
- DartEntry internalCacheDartResolutionData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
- CacheState state = dartEntry.getState2(descriptor, librarySource);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- dartEntry = internalResolveDart(unitSource, librarySource);
- state = dartEntry.getState2(descriptor, librarySource);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for an HTML file, return a cache entry in which all of the data represented by
- * the given descriptors is available. This method assumes that the data can be produced by
- * parsing the source if it is not already cached.
- *
- * @param source the source representing the HTML file
- * @param htmlEntry the cache entry associated with the HTML file
- * @param descriptor the descriptor representing the data to be returned
- * @return a cache entry containing the required data
- * @throws AnalysisException if data could not be returned because the source could not be
- * resolved
- */
- HtmlEntry internalCacheHtmlParseData(Source source, HtmlEntry htmlEntry, List<DataDescriptor> descriptors) {
- while (!hasHtmlParseDataCached(htmlEntry, descriptors)) {
- htmlEntry = internalParseHtml(source);
- }
- return htmlEntry;
- }
-
- /**
- * Given a source for a Dart file, return the data represented by the given descriptor that is
- * associated with that source. This method assumes that the data can be produced by parsing the
- * source if it is not already cached.
- *
- * @param source the source representing the Dart file
- * @param dartEntry the cache entry associated with the Dart file
- * @param descriptor the descriptor representing the data to be returned
- * @return the requested data about the given source
- * @throws AnalysisException if data could not be returned because the source could not be parsed
- */
- Object internalGetDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry = internalCacheDartParseData(source, dartEntry, descriptor);
- return dartEntry.getValue(descriptor);
- }
-
- /**
- * Given a source for a Dart file, return the data represented by the given descriptor that is
- * associated with that source, or the given default value if the source is not a Dart file. This
- * method assumes that the data can be produced by parsing the source if it is not already cached.
- *
- * @param source the source representing the Dart file
- * @param descriptor the descriptor representing the data to be returned
- * @param defaultValue the value to be returned if the source is not a Dart file
- * @return the requested data about the given source
- * @throws AnalysisException if data could not be returned because the source could not be parsed
- */
- Object internalGetDartParseData2(Source source, DataDescriptor descriptor, Object defaultValue) {
- DartEntry dartEntry = getReadableDartEntry(source);
- if (dartEntry == null) {
- return defaultValue;
- }
- return internalGetDartParseData(source, dartEntry, descriptor);
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return the data represented by
- * the given descriptor that is associated with that source. This method assumes that the data can
- * be produced by resolving the source in the context of the library if it is not already cached.
- *
- * @param unitSource the source representing the Dart file
- * @param librarySource the source representing the library containing the Dart file
- * @param dartEntry the entry representing the Dart file
- * @param descriptor the descriptor representing the data to be returned
- * @return the requested data about the given source
- * @throws AnalysisException if data could not be returned because the source could not be parsed
- */
- Object internalGetDartResolutionData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry = internalCacheDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
- return dartEntry.getValue2(descriptor, librarySource);
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return the data represented by
- * the given descriptor that is associated with that source. This method assumes that the data can
- * be produced by resolving the source in the context of the library if it is not already cached.
- *
- * @param unitSource the source representing the Dart file
- * @param librarySource the source representing the library containing the Dart file
- * @param descriptor the descriptor representing the data to be returned
- * @param defaultValue the value to be returned if the file is not a Dart file
- * @return the requested data about the given source
- * @throws AnalysisException if data could not be returned because the source could not be parsed
- */
- Object internalGetDartResolutionData2(Source unitSource, Source librarySource, DataDescriptor descriptor, Object defaultValue) {
- DartEntry dartEntry = getReadableDartEntry(unitSource);
- if (dartEntry == null) {
- return defaultValue;
- }
- dartEntry = internalCacheDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
- return dartEntry.getValue(descriptor);
- }
-
- /**
- * Given a source for an HTML file, return the data represented by the given descriptor that is
- * associated with that source, or the given default value if the source is not an HTML file. This
- * method assumes that the data can be produced by parsing the source if it is not already cached.
- *
- * @param source the source representing the Dart file
- * @param descriptor the descriptor representing the data to be returned
- * @param defaultValue the value to be returned if the source is not a Dart file
- * @return the requested data about the given source
- * @throws AnalysisException if data could not be returned because the source could not be parsed
- */
- Object internalGetHtmlParseData(Source source, DataDescriptor descriptor, Object defaultValue) {
- HtmlEntry htmlEntry = getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- return defaultValue;
- }
- htmlEntry = internalCacheHtmlParseData(source, htmlEntry, [descriptor]);
- return htmlEntry.getValue(descriptor);
- }
-
- /**
- * Given a source for an HTML file, return the data represented by the given descriptor that is
- * associated with that source, or the given default value if the source is not an HTML file. This
- * method assumes that the data can be produced by resolving the source if it is not already
- * cached.
- *
- * @param source the source representing the HTML file
- * @param descriptor the descriptor representing the data to be returned
- * @param defaultValue the value to be returned if the source is not an HTML file
- * @return the requested data about the given source
- * @throws AnalysisException if data could not be returned because the source could not be
- * resolved
- */
- Object internalGetHtmlResolutionData(Source source, HtmlEntry htmlEntry, DataDescriptor descriptor, Object defaultValue) {
- if (htmlEntry == null) {
- return defaultValue;
- }
- CacheState state = htmlEntry.getState(descriptor);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- htmlEntry = internalResolveHtml(source);
- state = htmlEntry.getState(descriptor);
- }
- return htmlEntry.getValue(descriptor);
- }
- CompilationUnit internalParseCompilationUnit(DartEntryImpl dartCopy, Source source) {
- try {
- accessed(source);
- RecordingErrorListener errorListener = new RecordingErrorListener();
- AnalysisContextImpl_ScanResult scanResult = internalScan(source, errorListener);
- Parser parser = new Parser(source, errorListener);
- CompilationUnit unit = parser.parseCompilationUnit(scanResult._token);
- LineInfo lineInfo = new LineInfo(scanResult._lineStarts);
- List<AnalysisError> errors = errorListener.getErrors2(source);
- bool hasPartOfDirective = false;
- bool hasLibraryDirective = false;
- Set<Source> exportedSources = new Set<Source>();
- Set<Source> importedSources = new Set<Source>();
- Set<Source> includedSources = new Set<Source>();
- for (Directive directive in unit.directives) {
- if (directive is ExportDirective) {
- Source exportSource = resolveSource(source, directive as ExportDirective);
- if (exportSource != null) {
- javaSetAdd(exportedSources, exportSource);
- }
- } else if (directive is ImportDirective) {
- Source importSource = resolveSource(source, directive as ImportDirective);
- if (importSource != null) {
- javaSetAdd(importedSources, importSource);
- }
- } else if (directive is LibraryDirective) {
- hasLibraryDirective = true;
- } else if (directive is PartDirective) {
- Source partSource = resolveSource(source, directive as PartDirective);
- if (partSource != null) {
- javaSetAdd(includedSources, partSource);
- }
- } else if (directive is PartOfDirective) {
- hasPartOfDirective = true;
- }
- }
- unit.parsingErrors = errors;
- unit.lineInfo = lineInfo;
- if (identical(dartCopy.getState(DartEntry.SOURCE_KIND), CacheState.INVALID)) {
- if (hasPartOfDirective && !hasLibraryDirective) {
- dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
- } else {
- dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
- }
- }
- dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
- dartCopy.setValue(DartEntry.PARSED_UNIT, unit);
- dartCopy.setValue(DartEntry.PARSE_ERRORS, errors);
- dartCopy.setValue(DartEntry.EXPORTED_LIBRARIES, toArray(exportedSources));
- dartCopy.setValue(DartEntry.IMPORTED_LIBRARIES, toArray(importedSources));
- dartCopy.setValue(DartEntry.INCLUDED_PARTS, toArray(includedSources));
- return dartCopy.getValue(DartEntry.PARSED_UNIT);
- } on AnalysisException catch (exception) {
- dartCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.ERROR);
- dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.ERROR);
- dartCopy.setState(DartEntry.EXPORTED_LIBRARIES, CacheState.ERROR);
- dartCopy.setState(DartEntry.IMPORTED_LIBRARIES, CacheState.ERROR);
- dartCopy.setState(DartEntry.INCLUDED_PARTS, CacheState.ERROR);
- throw exception;
- }
- }
-
- /**
- * Scan and parse the given Dart file, updating the cache as appropriate, and return the updated
- * cache entry associated with the source.
- *
- * @param source the source representing the compilation unit to be parsed
- * @return the updated cache entry associated with the source
- * @throws AnalysisException if the source does not represent a Dart compilation unit or if the
- * compilation unit cannot be parsed for some reason
- */
- DartEntry internalParseDart(Source source) {
- AnalysisContextImpl_ScanResult scanResult = null;
- LineInfo lineInfo = null;
- CompilationUnit unit = null;
- List<AnalysisError> errors = null;
- bool hasPartOfDirective = false;
- bool hasLibraryDirective = false;
- Set<Source> exportedSources = new Set<Source>();
- Set<Source> importedSources = new Set<Source>();
- Set<Source> includedSources = new Set<Source>();
- AnalysisException thrownException = null;
- try {
- RecordingErrorListener errorListener = new RecordingErrorListener();
- scanResult = internalScan(source, errorListener);
- Parser parser = new Parser(source, errorListener);
- unit = parser.parseCompilationUnit(scanResult._token);
- lineInfo = new LineInfo(scanResult._lineStarts);
- errors = errorListener.getErrors2(source);
- for (Directive directive in unit.directives) {
- if (directive is ExportDirective) {
- Source exportSource = resolveSource(source, directive as ExportDirective);
- if (exportSource != null) {
- javaSetAdd(exportedSources, exportSource);
- }
- } else if (directive is ImportDirective) {
- Source importSource = resolveSource(source, directive as ImportDirective);
- if (importSource != null) {
- javaSetAdd(importedSources, importSource);
- }
- } else if (directive is LibraryDirective) {
- hasLibraryDirective = true;
- } else if (directive is PartDirective) {
- Source partSource = resolveSource(source, directive as PartDirective);
- if (partSource != null) {
- javaSetAdd(includedSources, partSource);
- }
- } else if (directive is PartOfDirective) {
- hasPartOfDirective = true;
- }
- }
- unit.parsingErrors = errors;
- unit.lineInfo = lineInfo;
- } on AnalysisException catch (exception) {
- thrownException = exception;
- }
- DartEntry dartEntry = null;
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry is! DartEntry) {
- throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${source.fullName}");
- }
- dartEntry = sourceEntry as DartEntry;
- accessed(source);
- int sourceTime = source.modificationStamp;
- int resultTime = scanResult == null ? sourceTime : scanResult.modificationTime;
- if (sourceTime == resultTime) {
- if (dartEntry.modificationTime != sourceTime) {
- sourceChanged(source);
- dartEntry = getReadableDartEntry(source);
- }
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- if (thrownException == null) {
- dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
- if (hasPartOfDirective && !hasLibraryDirective) {
- dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
- } else {
- dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
- }
- dartCopy.setValue(DartEntry.PARSED_UNIT, unit);
- dartCopy.setValue(DartEntry.PARSE_ERRORS, errors);
- dartCopy.setValue(DartEntry.EXPORTED_LIBRARIES, toArray(exportedSources));
- dartCopy.setValue(DartEntry.IMPORTED_LIBRARIES, toArray(importedSources));
- dartCopy.setValue(DartEntry.INCLUDED_PARTS, toArray(includedSources));
- } else {
- dartCopy.recordParseError();
- }
- _sourceMap[source] = dartCopy;
- dartEntry = dartCopy;
- }
- }
- if (thrownException != null) {
- if (thrownException.cause is! JavaIOException) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${source.fullName}", thrownException);
- }
- throw thrownException;
- }
- return dartEntry;
- }
-
- /**
- * Scan and parse the given HTML file, updating the cache as appropriate, and return the updated
- * cache entry associated with the source.
- *
- * @param source the source representing the HTML file to be parsed
- * @return the updated cache entry associated with the source
- * @throws AnalysisException if the source does not represent an HTML file or if the file cannot
- * be parsed for some reason
- */
- HtmlEntry internalParseHtml(Source source) {
- HtmlParseResult result = null;
- LineInfo lineInfo = null;
- AnalysisException thrownException = null;
- try {
- result = new HtmlParser(source).parse(scanHtml(source));
- lineInfo = new LineInfo(result.lineStarts);
- } on AnalysisException catch (exception) {
- thrownException = exception;
- }
- HtmlEntry htmlEntry = null;
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry is! HtmlEntry) {
- throw new AnalysisException.con1("Internal error: attempting to parse non-HTML file as a HTML file: ${source.fullName}");
- }
- htmlEntry = sourceEntry as HtmlEntry;
- accessed(source);
- int sourceTime = source.modificationStamp;
- int resultTime = result == null ? sourceTime : result.modificationTime;
- if (sourceTime == resultTime) {
- if (htmlEntry.modificationTime != sourceTime) {
- sourceChanged(source);
- htmlEntry = getReadableHtmlEntry(source);
- }
- HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
- if (thrownException == null) {
- HtmlUnit unit = result.htmlUnit;
- htmlCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
- htmlCopy.setValue(HtmlEntry.PARSED_UNIT, unit);
- htmlCopy.setValue(HtmlEntry.REFERENCED_LIBRARIES, getLibrarySources2(source, unit));
- } else {
- htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
- htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
- }
- _sourceMap[source] = htmlCopy;
- htmlEntry = htmlCopy;
- }
- }
- if (thrownException != null) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${source.fullName}", thrownException);
- throw thrownException;
- }
- ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(htmlEntry.allErrors, lineInfo);
- return htmlEntry;
- }
- DartEntry internalResolveDart(Source unitSource, Source librarySource) {
- DartEntry dartEntry = getReadableDartEntry(unitSource);
- if (dartEntry == null) {
- throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${unitSource.fullName}");
- }
- LibraryResolver resolver = null;
- AnalysisException thrownException = null;
- try {
- resolver = new LibraryResolver(this);
- resolver.resolveLibrary(librarySource, true);
- } on AnalysisException catch (exception) {
- thrownException = exception;
- }
- if (thrownException == null) {
- {
- accessed(unitSource);
- }
- recordResolutionResults(resolver);
- dartEntry = getReadableDartEntry(unitSource);
- } else {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${unitSource.fullName}", thrownException);
- bool unitIsLibrary = unitSource == librarySource;
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState2(DartEntry.RESOLUTION_ERRORS, librarySource, CacheState.ERROR);
- if (unitIsLibrary) {
- dartCopy.setState(DartEntry.ELEMENT, CacheState.ERROR);
- }
- _sourceMap[unitSource] = dartCopy;
- if (!unitIsLibrary) {
- DartEntry libraryEntry = getReadableDartEntry(librarySource);
- if (libraryEntry != null) {
- DartEntryImpl libraryCopy = dartEntry.writableCopy;
- libraryCopy.setState2(DartEntry.RESOLUTION_ERRORS, librarySource, CacheState.ERROR);
- libraryCopy.setState(DartEntry.ELEMENT, CacheState.ERROR);
- _sourceMap[librarySource] = libraryCopy;
- }
- }
- throw thrownException;
- }
- ChangeNoticeImpl notice = getNotice(unitSource);
- notice.setErrors(dartEntry.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
- return dartEntry;
- }
-
- /**
- * Scan and parse the given HTML file, updating the cache as appropriate, and return the updated
- * cache entry associated with the source.
- *
- * @param source the source representing the HTML file to be parsed
- * @return the updated cache entry associated with the source
- * @throws AnalysisException if the source does not represent an HTML file or if the file cannot
- * be parsed for some reason
- */
- HtmlEntry internalResolveHtml(Source source) {
- HtmlEntry htmlEntry = getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- throw new AnalysisException.con1("Internal error: attempting to parse non-HTML file as a HTML file: ${source.fullName}");
- }
- int resultTime = 0;
- HtmlElement element = null;
- List<AnalysisError> resolutionErrors = null;
- AnalysisException thrownException = null;
- try {
- htmlEntry = internalCacheHtmlParseData(source, htmlEntry, [HtmlEntry.PARSED_UNIT]);
- HtmlUnit unit = htmlEntry.getValue(HtmlEntry.PARSED_UNIT);
- if (unit == null) {
- throw new AnalysisException.con1("Internal error: internalCacheHtmlParseData returned an entry without a parsed HTML unit");
- }
- resultTime = htmlEntry.modificationTime;
- HtmlUnitBuilder builder = new HtmlUnitBuilder(this);
- element = builder.buildHtmlElement2(source, resultTime, unit);
- resolutionErrors = builder.errorListener.getErrors2(source);
- } on AnalysisException catch (exception) {
- thrownException = exception;
- }
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry is! HtmlEntry) {
- throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as a HTML file: ${source.fullName}");
- }
- htmlEntry = sourceEntry as HtmlEntry;
- accessed(source);
- int sourceTime = source.modificationStamp;
- if (sourceTime == resultTime) {
- if (htmlEntry.modificationTime != sourceTime) {
- sourceChanged(source);
- htmlEntry = getReadableHtmlEntry(source);
- }
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- if (thrownException == null) {
- htmlCopy.setValue(HtmlEntry.RESOLUTION_ERRORS, resolutionErrors);
- htmlCopy.setValue(HtmlEntry.ELEMENT, element);
- } else {
- htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.ERROR);
- htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.ERROR);
- }
- _sourceMap[source] = htmlCopy;
- htmlEntry = htmlCopy;
- }
- }
- if (thrownException != null) {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${source.fullName}", thrownException);
- throw thrownException;
- }
- ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(htmlEntry.allErrors, htmlEntry.getValue(SourceEntry.LINE_INFO));
- return htmlEntry;
- }
- AnalysisContextImpl_ScanResult internalScan(Source source, AnalysisErrorListener errorListener) {
- AnalysisContextImpl_ScanResult result = new AnalysisContextImpl_ScanResult();
- Source_ContentReceiver receiver = new Source_ContentReceiver_7(source, errorListener, result);
- try {
- source.getContents(receiver);
- } catch (exception) {
- throw new AnalysisException.con3(exception);
- }
- return result;
- }
-
- /**
- * Invalidate all of the results computed by this context.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- */
- void invalidateAllResults() {
- for (MapEntry<Source, SourceEntry> mapEntry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = mapEntry.getValue();
- if (sourceEntry is HtmlEntry) {
- HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
- htmlCopy.invalidateAllResolutionInformation();
- mapEntry.setValue(htmlCopy);
- } else if (sourceEntry is DartEntry) {
- DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
- dartCopy.invalidateAllResolutionInformation();
- mapEntry.setValue(dartCopy);
- }
- }
- }
-
- /**
- * In response to a change to at least one of the compilation units in the given library,
- * invalidate any results that are dependent on the result of resolving that library.
- *
- * @param librarySource the source of the library being invalidated
- */
- void invalidateLibraryResolution(Source librarySource) {
- DartEntry libraryEntry = getDartEntry(librarySource);
- if (libraryEntry != null) {
- List<Source> includedParts = libraryEntry.getValue(DartEntry.INCLUDED_PARTS);
- DartEntryImpl libraryCopy = libraryEntry.writableCopy;
- libraryCopy.invalidateAllResolutionInformation();
- libraryCopy.setState(DartEntry.INCLUDED_PARTS, CacheState.INVALID);
- _sourceMap[librarySource] = libraryCopy;
- for (Source unitSource in includedParts) {
- DartEntry partEntry = getDartEntry(unitSource);
- if (partEntry != null) {
- DartEntryImpl dartCopy = partEntry.writableCopy;
- dartCopy.invalidateAllResolutionInformation();
- _sourceMap[unitSource] = dartCopy;
- }
- }
- }
- }
-
- /**
- * Return `true` if this library is, or depends on, dart:html.
- *
- * @param library the library being tested
- * @param visitedLibraries a collection of the libraries that have been visited, used to prevent
- * infinite recursion
- * @return `true` if this library is, or depends on, dart:html
- */
- bool isClient(LibraryElement library, Source htmlSource, Set<LibraryElement> visitedLibraries) {
- if (visitedLibraries.contains(library)) {
- return false;
- }
- if (library.source == htmlSource) {
- return true;
- }
- javaSetAdd(visitedLibraries, library);
- for (LibraryElement imported in library.importedLibraries) {
- if (isClient(imported, htmlSource, visitedLibraries)) {
- return true;
- }
- }
- for (LibraryElement exported in library.exportedLibraries) {
- if (isClient(exported, htmlSource, visitedLibraries)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Return `true` if the given source is in the array of priority sources.
- *
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
- */
- bool isPrioritySource(Source source) {
- for (Source prioritySource in _priorityOrder) {
- if (source == prioritySource) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Perform a single analysis task.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @return `true` if work was done, implying that there might be more work to be done
- */
- bool performSingleAnalysisTask() {
- for (Source source in _priorityOrder) {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- CacheState parsedUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
- if (identical(parsedUnitState, CacheState.INVALID) || identical(parsedUnitState, CacheState.FLUSHED)) {
- safelyParseCompilationUnit(source, dartEntry);
- return true;
- }
- for (Source librarySource in getLibrariesContaining(source)) {
- SourceEntry libraryEntry = _sourceMap[librarySource];
- if (libraryEntry is DartEntry) {
- CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
- if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
- safelyResolveCompilationUnit(librarySource);
- return true;
- }
- }
- if (identical(dartEntry.getState2(DartEntry.RESOLVED_UNIT, librarySource), CacheState.FLUSHED)) {
- safelyResolveCompilationUnit2(source, librarySource);
- return true;
- }
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
- if (identical(parsedUnitState, CacheState.INVALID) || identical(parsedUnitState, CacheState.FLUSHED)) {
- safelyParseHtmlUnit(source);
- return true;
- }
- CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
- if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
- safelyResolveHtmlUnit(source);
- return true;
- }
- }
- }
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- if (identical(dartEntry.getState(DartEntry.PARSED_UNIT), CacheState.INVALID)) {
- safelyParseCompilationUnit(entry.getKey(), dartEntry);
- return true;
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- if (identical(htmlEntry.getState(HtmlEntry.PARSED_UNIT), CacheState.INVALID)) {
- safelyParseHtmlUnit(entry.getKey());
- return true;
- }
- }
- }
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
- if (sourceEntry is DartEntry && identical(sourceEntry.kind, SourceKind.LIBRARY)) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- if (identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
- safelyResolveCompilationUnit(entry.getKey());
- return true;
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- if (identical(htmlEntry.getState(HtmlEntry.ELEMENT), CacheState.INVALID)) {
- safelyResolveHtmlUnit(entry.getKey());
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Given a cache entry and a library element, record the library element and other information
- * gleaned from the element in the cache entry.
- *
- * @param dartCopy the cache entry in which data is to be recorded
- * @param library the library element used to record information
- * @param htmlSource the source for the HTML library
- */
- void recordElementData(DartEntryImpl dartCopy, LibraryElement library, 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>()));
- List<Source> unitSources = new List<Source>();
- unitSources.add(library.definingCompilationUnit.source);
- for (CompilationUnitElement part in library.parts) {
- Source partSource = part.source;
- unitSources.add(partSource);
- }
- dartCopy.setValue(DartEntry.INCLUDED_PARTS, new List.from(unitSources));
- }
-
- /**
- * Record the result of using the given resolver to resolve one or more libraries.
- *
- * @param resolver the resolver that has the needed results
- * @throws AnalysisException if the results cannot be retrieved for some reason
- */
- void recordResolutionResults(LibraryResolver resolver) {
- Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
- RecordingErrorListener errorListener = resolver.errorListener;
- for (Library library in resolver.resolvedLibraries) {
- Source librarySource = library.librarySource;
- for (Source source in library.compilationUnitSources) {
- CompilationUnit unit = library.getAST(source);
- List<AnalysisError> errors = errorListener.getErrors2(source);
- unit.resolutionErrors = errors;
- LineInfo lineInfo = unit.lineInfo;
- {
- DartEntry dartEntry = getDartEntry(source);
- if (dartEntry != null) {
- int sourceTime = source.modificationStamp;
- int resultTime = dartEntry.modificationTime;
- if (sourceTime == resultTime) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, unit);
- dartCopy.setValue2(DartEntry.RESOLUTION_ERRORS, librarySource, errors);
- if (identical(source, librarySource)) {
- recordElementData(dartCopy, library.libraryElement, htmlSource);
- }
- _sourceMap[source] = dartCopy;
- ChangeNoticeImpl notice = getNotice(source);
- notice.compilationUnit = unit;
- notice.setErrors(dartCopy.allErrors, lineInfo);
- } else {
- sourceChanged(source);
- }
- }
- }
- }
- }
- }
-
- /**
- * Remove and return one source from the list of recently used sources whose AST structure can be
- * flushed from the cache. The source that will be returned will be the source that has been
- * unreferenced for the longest period of time but that is not a priority for analysis.
- *
- * @return the source that was removed
- *
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
- */
- Source removeAstToFlush() {
- for (int i = 0; i < _recentlyUsed.length; i++) {
- Source source = _recentlyUsed[i];
- if (!isPrioritySource(source)) {
- return _recentlyUsed.removeAt(i);
- }
- }
- AnalysisEngine.instance.logger.logError2("Internal error: The number of priority sources is greater than the maximum cache size", new JavaException());
- return _recentlyUsed.removeAt(0);
- }
-
- /**
- * Return the result of resolving the URI of the given URI-based directive against the URI of the
- * given library, or `null` if the URI is not valid.
- *
- * @param librarySource the source representing the library containing the directive
- * @param directive the directive which URI should be resolved
- * @return the result of resolving the URI against the URI of the library
- */
- Source resolveSource(Source librarySource, UriBasedDirective directive) {
- StringLiteral uriLiteral = directive.uri;
- if (uriLiteral is StringInterpolation) {
- return null;
- }
- String uriContent = uriLiteral.stringValue.trim();
- if (uriContent == null || uriContent.isEmpty) {
- return null;
- }
- uriContent = Uri.encodeFull(uriContent);
- try {
- parseUriWithException(uriContent);
- return _sourceFactory.resolveUri(librarySource, uriContent);
- } on URISyntaxException catch (exception) {
- return null;
- }
- }
-
- /**
- * Parse the given source and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source to be parsed
- * @param dartEntry the cache entry associated with the source
- */
- void safelyParseCompilationUnit(Source source, DartEntry dartEntry) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- try {
- internalParseCompilationUnit(dartCopy, source);
- } on AnalysisException catch (exception) {
- if (exception.cause is! JavaIOException) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${source.fullName}", exception);
- }
- }
- _sourceMap[source] = dartCopy;
- }
-
- /**
- * Parse the given source and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source to be parsed
- */
- void safelyParseHtmlUnit(Source source) {
- try {
- parseHtmlUnit(source);
- } on AnalysisException catch (exception) {
- if (exception.cause is! JavaIOException) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${source.fullName}", exception);
- }
- }
- }
-
- /**
- * Resolve the given source and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source to be resolved
- */
- void safelyResolveCompilationUnit(Source source) {
- try {
- computeLibraryElement(source);
- } on AnalysisException catch (exception) {
- }
- }
-
- /**
- * Resolve the given source within the given library and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param unitSource the source to be resolved
- * @param librarySource the source
- */
- void safelyResolveCompilationUnit2(Source unitSource, Source librarySource) {
- try {
- resolveCompilationUnit2(unitSource, librarySource);
- } on AnalysisException catch (exception) {
- DartEntryImpl dartCopy = getReadableDartEntry(unitSource).writableCopy;
- dartCopy.recordResolutionError();
- _sourceMap[unitSource] = dartCopy;
- AnalysisEngine.instance.logger.logError2("Could not resolve ${unitSource.fullName} in ${librarySource.fullName}", exception);
- }
- }
-
- /**
- * Resolve the given source and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source to be resolved
- */
- void safelyResolveHtmlUnit(Source source) {
- try {
- computeHtmlElement(source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${source.fullName}", exception);
- }
- }
- HtmlScanResult scanHtml(Source source) {
- HtmlScanner scanner = new HtmlScanner(source);
- try {
- source.getContents(scanner);
- } catch (exception) {
- throw new AnalysisException.con3(exception);
- }
- return scanner.result;
- }
-
- /**
- * Create an entry for the newly added source. Return `true` if the new source is a Dart
- * file.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source that has been added
- * @return `true` if the new source is a Dart file
- */
- bool sourceAvailable(Source source) {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(source);
- } else {
- SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
- sourceCopy.modificationTime = source.modificationStamp;
- _sourceMap[source] = sourceCopy;
- }
- return sourceEntry is DartEntry;
- }
-
- /**
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source that has been changed
- */
- void sourceChanged(Source source) {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry is HtmlEntry) {
- HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
- htmlCopy.modificationTime = source.modificationStamp;
- htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.INVALID);
- htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.INVALID);
- htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.INVALID);
- htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.INVALID);
- _sourceMap[source] = htmlCopy;
- } else if (sourceEntry is DartEntry) {
- List<Source> containingLibraries = getLibrariesContaining(source);
- DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
- dartCopy.modificationTime = source.modificationStamp;
- dartCopy.setState(DartEntry.ELEMENT, CacheState.INVALID);
- dartCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
- dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.INVALID);
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.INVALID);
- dartCopy.setState(DartEntry.SOURCE_KIND, CacheState.INVALID);
- _sourceMap[source] = dartCopy;
- for (Source library in containingLibraries) {
- invalidateLibraryResolution(library);
- }
- }
- }
-
- /**
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source that has been deleted
- */
- void sourceRemoved(Source source) {
- DartEntry dartEntry = getDartEntry(source);
- if (dartEntry != null) {
- Set<Source> libraries = new Set<Source>();
- for (Source librarySource in getLibrariesContaining(source)) {
- javaSetAdd(libraries, librarySource);
- for (Source dependentLibrary in getLibrariesDependingOn(librarySource)) {
- javaSetAdd(libraries, dependentLibrary);
- }
- }
- for (Source librarySource in libraries) {
- invalidateLibraryResolution(librarySource);
- }
- }
- _sourceMap.remove(source);
- }
-
- /**
- * Efficiently convert the given set of sources to an array.
- *
- * @param sources the set to be converted
- * @return an array containing all of the sources in the given set
- */
- List<Source> toArray(Set<Source> sources) {
- int size = sources.length;
- if (size == 0) {
- return Source.EMPTY_ARRAY;
- }
- return new List.from(sources);
- }
-}
-/**
- * The interface `AnalysisTask` defines the behavior of objects used to perform an analysis
- * task.
- */
-abstract class AnalysisContextImpl_AnalysisTask {
-
- /**
- * Perform a single analysis task. Implementors should assume that the cache is not locked.
- */
- void perform();
-}
-/**
- * Instances of the class `ParseDartTask` parse a specific source as a Dart file.
- */
-class AnalysisContextImpl_ParseDartTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- /**
- * The source to be parsed.
- */
- Source _source;
-
- /**
- * Initialize a newly created task to parse the given source as a Dart file.
- *
- * @param source the source to be resolved
- */
- AnalysisContextImpl_ParseDartTask(this.AnalysisContextImpl_this, Source source) {
- this._source = source;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.internalParseDart(_source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${_source.fullName}", exception);
- }
- }
-}
-/**
- * Instances of the class `ParseHtmlTask` parse a specific source as an HTML file.
- */
-class AnalysisContextImpl_ParseHtmlTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- /**
- * The source to be parsed.
- */
- Source _source;
-
- /**
- * Initialize a newly created task to parse the given source as an HTML file.
- *
- * @param source the source to be resolved
- */
- AnalysisContextImpl_ParseHtmlTask(this.AnalysisContextImpl_this, Source source) {
- this._source = source;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.internalParseHtml(_source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${_source.fullName}", exception);
- }
- }
-}
-/**
- * Instances of the class `ResolveDartLibraryTask` resolve a specific source as a Dart
- * library.
- */
-class AnalysisContextImpl_ResolveDartLibraryTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- /**
- * The source to be resolved.
- */
- Source _source;
-
- /**
- * Initialize a newly created task to resolve the given source as a Dart file.
- *
- * @param source the source to be resolved
- */
- AnalysisContextImpl_ResolveDartLibraryTask(this.AnalysisContextImpl_this, Source source) {
- this._source = source;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.computeLibraryElement(_source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${_source.fullName}", exception);
- }
- }
-}
-/**
- * Instances of the class `ResolveDartUnitTask` resolve a specific source as a Dart file
- * within a library.
- */
-class AnalysisContextImpl_ResolveDartUnitTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- /**
- * The source to be resolved.
- */
- Source _unitSource;
-
- /**
- * The source of the library in which the source is to be resolved.
- */
- Source _librarySource;
-
- /**
- * Initialize a newly created task to resolve the given source as a Dart file.
- *
- * @param unitSource the source to be resolved
- * @param librarySource the source of the library in which the source is to be resolved
- */
- AnalysisContextImpl_ResolveDartUnitTask(this.AnalysisContextImpl_this, Source unitSource, Source librarySource) {
- this._unitSource = unitSource;
- this._librarySource = librarySource;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.resolveCompilationUnit2(_unitSource, _librarySource);
- } on AnalysisException catch (exception) {
- DartEntryImpl dartCopy = AnalysisContextImpl_this.getReadableDartEntry(_unitSource).writableCopy;
- dartCopy.recordResolutionError();
- AnalysisContextImpl_this._sourceMap[_unitSource] = dartCopy;
- AnalysisEngine.instance.logger.logError2("Could not resolve ${_unitSource.fullName} in ${_librarySource.fullName}", exception);
- }
- }
-}
-/**
- * Instances of the class `ResolveHtmlTask` resolve a specific source as an HTML file.
- */
-class AnalysisContextImpl_ResolveHtmlTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- /**
- * The source to be resolved.
- */
- Source _source;
-
- /**
- * Initialize a newly created task to resolve the given source as an HTML file.
- *
- * @param source the source to be resolved
- */
- AnalysisContextImpl_ResolveHtmlTask(this.AnalysisContextImpl_this, Source source) {
- this._source = source;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.computeHtmlElement(_source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${_source.fullName}", exception);
- }
- }
-}
-/**
- * Instances of the class `ScanResult` represent the results of scanning a source.
- */
-class AnalysisContextImpl_ScanResult {
-
- /**
- * The time at which the contents of the source were last modified.
- */
- int modificationTime = 0;
-
- /**
- * The first token in the token stream.
- */
- Token _token;
-
- /**
- * The line start information that was produced.
- */
- List<int> _lineStarts;
-}
-class RecursiveXmlVisitor_6 extends RecursiveXmlVisitor<Object> {
- final AnalysisContextImpl AnalysisContextImpl_this;
- Source htmlSource;
- List<Source> libraries;
- RecursiveXmlVisitor_6(this.AnalysisContextImpl_this, this.htmlSource, this.libraries) : super();
- Object visitXmlTagNode(XmlTagNode node) {
- if (javaStringEqualsIgnoreCase(node.tag.lexeme, AnalysisContextImpl._TAG_SCRIPT)) {
- bool isDartScript = false;
- XmlAttributeNode scriptAttribute = null;
- for (XmlAttributeNode attribute in node.attributes) {
- if (javaStringEqualsIgnoreCase(attribute.name.lexeme, AnalysisContextImpl._ATTRIBUTE_SRC)) {
- scriptAttribute = attribute;
- } else if (javaStringEqualsIgnoreCase(attribute.name.lexeme, AnalysisContextImpl._ATTRIBUTE_TYPE)) {
- String text = attribute.text;
- if (text != null && javaStringEqualsIgnoreCase(text, AnalysisContextImpl._TYPE_DART)) {
- isDartScript = true;
- }
- }
- }
- if (isDartScript && scriptAttribute != null) {
- String text = scriptAttribute.text;
- if (text != null) {
- try {
- Uri uri = new Uri(path: text);
- String fileName = uri.path;
- Source librarySource = AnalysisContextImpl_this._sourceFactory.resolveUri(htmlSource, fileName);
- if (librarySource != null && librarySource.exists()) {
- libraries.add(librarySource);
- }
- } catch (exception) {
- AnalysisEngine.instance.logger.logInformation2("Invalid URI ('${text}') in script tag in '${htmlSource.fullName}'", exception);
- }
- }
- }
- }
- return super.visitXmlTagNode(node);
- }
-}
-class Source_ContentReceiver_7 implements Source_ContentReceiver {
- Source source;
- AnalysisErrorListener errorListener;
- AnalysisContextImpl_ScanResult result;
- Source_ContentReceiver_7(this.source, this.errorListener, this.result);
- void accept(CharBuffer contents, int modificationTime2) {
- CharBufferScanner scanner = new CharBufferScanner(source, contents, errorListener);
- result.modificationTime = modificationTime2;
- result._token = scanner.tokenize();
- result._lineStarts = scanner.lineStarts;
- }
- void accept2(String contents, int modificationTime2) {
- StringScanner scanner = new StringScanner(source, contents, errorListener);
- result.modificationTime = modificationTime2;
- result._token = scanner.tokenize();
- result._lineStarts = scanner.lineStarts;
- }
-}
-/**
- * Instances of the class `AnalysisContextImpl` implement an [AnalysisContext].
- *
- * @coverage dart.engine
- */
-class AnalysisContextImpl2 implements InternalAnalysisContext {
-
- /**
* The set of analysis options controlling the behavior of this context.
*/
AnalysisOptions _options = new AnalysisOptionsImpl();
@@ -5040,7 +2687,7 @@
/**
* The object used to record the results of performing an analysis task.
*/
- AnalysisContextImpl2_AnalysisTaskResultRecorder _resultRecorder;
+ AnalysisContextImpl_AnalysisTaskResultRecorder _resultRecorder;
/**
* The maximum number of sources for which data should be kept in the cache.
@@ -5058,8 +2705,8 @@
/**
* Initialize a newly created analysis context.
*/
- AnalysisContextImpl2() : super() {
- _resultRecorder = new AnalysisContextImpl2_AnalysisTaskResultRecorder(this);
+ AnalysisContextImpl() : super() {
+ _resultRecorder = new AnalysisContextImpl_AnalysisTaskResultRecorder(this);
}
void addSourceInfo(Source source, SourceEntry info) {
_cache.put(source, info);
@@ -5087,8 +2734,9 @@
}
if (addedDartSource) {
for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
- if (!mapEntry.getKey().isInSystemLibrary && mapEntry.getValue() is DartEntry) {
- DartEntryImpl dartCopy = ((mapEntry.getValue() as DartEntry)).writableCopy;
+ SourceEntry sourceEntry = mapEntry.getValue();
+ if (!mapEntry.getKey().isInSystemLibrary && sourceEntry is DartEntry) {
+ DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
dartCopy.invalidateAllResolutionInformation();
mapEntry.setValue(dartCopy);
}
@@ -5139,10 +2787,12 @@
dartEntry = getReadableDartEntry(source);
if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) {
ListUtilities.addAll(errors, getDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry, DartEntry.HINTS));
} else {
List<Source> libraries = getLibrariesContaining(source);
for (Source librarySource in libraries) {
ListUtilities.addAll(errors, getDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS));
}
}
if (errors.isEmpty) {
@@ -5469,8 +3119,8 @@
if (identical(parseErrorsState, CacheState.INVALID) || identical(parseErrorsState, CacheState.FLUSHED)) {
javaSetAdd(sources, source);
}
- CacheState parseUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
- if (identical(parseUnitState, CacheState.INVALID) || identical(parseUnitState, CacheState.FLUSHED)) {
+ CompilationUnit parseUnit = dartEntry.anyParsedCompilationUnit;
+ if (parseUnit == null) {
javaSetAdd(sources, source);
}
for (Source librarySource in getLibrariesContaining(source)) {
@@ -5487,6 +3137,13 @@
javaSetAdd(sources, source);
}
}
+ CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, librarySource);
+ if (identical(hintsState, CacheState.INVALID) || identical(hintsState, CacheState.FLUSHED)) {
+ LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
+ if (libraryElement != null) {
+ javaSetAdd(sources, source);
+ }
+ }
}
}
} else if (sourceEntry is HtmlEntry) {
@@ -5517,9 +3174,11 @@
}
for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
SourceEntry sourceEntry = entry.getValue();
- if (sourceEntry is DartEntry && identical(sourceEntry.kind, SourceKind.LIBRARY)) {
+ if (sourceEntry is DartEntry) {
DartEntry dartEntry = sourceEntry as DartEntry;
- if (identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
+ if (identical(dartEntry.kind, SourceKind.LIBRARY) && identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
+ javaSetAdd(sources, entry.getKey());
+ } else if (identical(dartEntry.getState2(DartEntry.HINTS, entry.getKey()), CacheState.INVALID)) {
javaSetAdd(sources, entry.getKey());
}
} else if (sourceEntry is HtmlEntry) {
@@ -5555,6 +3214,7 @@
}
List<Source> librarySources = getLibrariesContaining(source);
for (Source librarySource in librarySources) {
+ statistics.putCacheItem2(dartEntry, librarySource, DartEntry.HINTS);
statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
}
@@ -5563,6 +3223,15 @@
}
return statistics;
}
+ TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement) {
+ DartEntry dartEntry = getReadableDartEntry(unitSource);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("internalResolveCompilationUnit invoked for non-Dart file: ${unitSource.fullName}");
+ }
+ Source librarySource = libraryElement.source;
+ dartEntry = cacheDartResolutionData(unitSource, librarySource, dartEntry, DartEntry.RESOLVED_UNIT);
+ return new TimestampedData<CompilationUnit>(dartEntry.modificationTime, dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource));
+ }
bool isClientLibrary(Source librarySource) {
SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
if (sourceEntry is DartEntry) {
@@ -5583,11 +3252,11 @@
if (context is InstrumentedAnalysisContextImpl) {
context = ((context as InstrumentedAnalysisContextImpl)).basis;
}
- if (context is! AnalysisContextImpl2) {
+ if (context is! AnalysisContextImpl) {
return;
}
{
- for (MapEntry<Source, SourceEntry> entry in ((context as AnalysisContextImpl2))._cache.entrySet()) {
+ for (MapEntry<Source, SourceEntry> entry in ((context as AnalysisContextImpl))._cache.entrySet()) {
Source newSource = entry.getKey();
SourceEntry existingEntry = getReadableSourceEntry(newSource);
if (existingEntry == null) {
@@ -5739,6 +3408,27 @@
}
/**
+ * Given a source for a Dart file and the library that contains it, return a cache entry in which
+ * the data represented by the given descriptor is available. This method assumes that the data
+ * can be produced by generating hints for the library if the data is not already cached.
+ *
+ * @param unitSource the source representing the Dart file
+ * @param librarySource the source representing the library containing the Dart file
+ * @param dartEntry the cache entry associated with the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return a cache entry containing the required data
+ * @throws AnalysisException if data could not be returned because the source could not be parsed
+ */
+ DartEntry cacheDartHintData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+ CacheState state = dartEntry.getState2(descriptor, librarySource);
+ while (state != CacheState.ERROR && state != CacheState.VALID) {
+ dartEntry = new GenerateDartHintsTask(this, getLibraryElement(librarySource)).perform(_resultRecorder) as DartEntry;
+ state = dartEntry.getState2(descriptor, librarySource);
+ }
+ return dartEntry;
+ }
+
+ /**
* Given a source for a Dart file, return a cache entry in which the data represented by the given
* descriptor is available. This method assumes that the data can be produced by parsing the
* source if it is not already cached.
@@ -5918,6 +3608,27 @@
}
/**
+ * Given a source for a Dart file and the library that contains it, return the data represented by
+ * the given descriptor that is associated with that source. This method assumes that the data can
+ * be produced by generating hints for the library if it is not already cached.
+ *
+ * @param unitSource the source representing the Dart file
+ * @param librarySource the source representing the library containing the Dart file
+ * @param dartEntry the entry representing the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
+ */
+ Object getDartHintData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+ dartEntry = cacheDartHintData(unitSource, librarySource, dartEntry, descriptor);
+ if (identical(descriptor, DartEntry.ELEMENT)) {
+ return dartEntry.getValue(descriptor);
+ }
+ return dartEntry.getValue2(descriptor, librarySource);
+ }
+
+ /**
* Given a source for a Dart file, return the data represented by the given descriptor that is
* associated with that source. This method assumes that the data can be produced by parsing the
* source if it is not already cached.
@@ -6064,6 +3775,7 @@
*/
AnalysisTask get nextTaskAnalysisTask {
{
+ bool enableHints = analysisOptions.hint;
for (Source source in _cache.priorityOrder) {
SourceEntry sourceEntry = _cache.get(source);
if (sourceEntry is DartEntry) {
@@ -6075,8 +3787,8 @@
_cache.put(source, dartCopy);
return new ParseDartTask(this, source);
}
- CacheState parseUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
- if (identical(parseUnitState, CacheState.INVALID) || identical(parseUnitState, CacheState.FLUSHED)) {
+ CompilationUnit parseUnit = dartEntry.anyParsedCompilationUnit;
+ if (parseUnit == null) {
DartEntryImpl dartCopy = dartEntry.writableCopy;
dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.IN_PROCESS);
_cache.put(source, dartCopy);
@@ -6102,6 +3814,16 @@
return new ResolveDartUnitTask(this, source, libraryElement);
}
}
+ CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, librarySource);
+ if (enableHints && (identical(hintsState, CacheState.INVALID) || identical(hintsState, CacheState.FLUSHED))) {
+ LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
+ if (libraryElement != null) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new GenerateDartHintsTask(this, libraryElement);
+ }
+ }
}
}
} else if (sourceEntry is HtmlEntry) {
@@ -6146,14 +3868,22 @@
}
for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
SourceEntry sourceEntry = entry.getValue();
- if (sourceEntry is DartEntry && identical(sourceEntry.kind, SourceKind.LIBRARY)) {
+ if (sourceEntry is DartEntry) {
+ Source source = entry.getKey();
DartEntry dartEntry = sourceEntry as DartEntry;
- if (identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
- Source source = entry.getKey();
+ if (identical(dartEntry.kind, SourceKind.LIBRARY) && identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
DartEntryImpl dartCopy = dartEntry.writableCopy;
dartCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
_cache.put(source, dartCopy);
return new ResolveDartLibraryTask(this, source, source);
+ } else if (enableHints && identical(dartEntry.getState2(DartEntry.HINTS, source), CacheState.INVALID)) {
+ LibraryElement libraryElement = dartEntry.getValue(DartEntry.ELEMENT);
+ if (libraryElement != null) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState2(DartEntry.HINTS, source, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new GenerateDartHintsTask(this, libraryElement);
+ }
}
} else if (sourceEntry is HtmlEntry) {
HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
@@ -6302,9 +4032,9 @@
libraryCopy.setState(DartEntry.INCLUDED_PARTS, CacheState.INVALID);
_cache.put(librarySource, libraryCopy);
for (Source partSource in includedParts) {
- DartEntry partEntry = getReadableDartEntry(partSource);
- if (partEntry != null) {
- DartEntryImpl partCopy = partEntry.writableCopy;
+ SourceEntry partEntry = _cache.get(partSource);
+ if (partEntry is DartEntry) {
+ DartEntryImpl partCopy = ((partEntry as DartEntry)).writableCopy;
partCopy.invalidateAllResolutionInformation();
_cache.put(partSource, partCopy);
}
@@ -6363,6 +4093,90 @@
}
/**
+ * Record the results produced by performing a [GenerateDartHintsTask]. If the results were
+ * computed from data that is now out-of-date, then the results will not be recorded.
+ *
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
+ */
+ DartEntry recordGenerateDartHintsTask(GenerateDartHintsTask task) {
+ Source librarySource = task.libraryElement.source;
+ AnalysisException thrownException = task.exception;
+ DartEntry libraryEntry = null;
+ Map<Source, TimestampedData<List<AnalysisError>>> hintMap = task.hintMap;
+ if (hintMap == null) {
+ {
+ SourceEntry sourceEntry = _cache.get(librarySource);
+ if (sourceEntry is! DartEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to generate hints for non-Dart file as a Dart file: ${librarySource.fullName}");
+ }
+ if (thrownException == null) {
+ thrownException = new AnalysisException.con1("GenerateDartHintsTask returned a null hint map without throwing an exception: ${librarySource.fullName}");
+ }
+ DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR);
+ dartCopy.exception = thrownException;
+ _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();
+ {
+ SourceEntry sourceEntry = _cache.get(unitSource);
+ if (sourceEntry is! DartEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${unitSource.fullName}");
+ }
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ if (unitSource == librarySource) {
+ libraryEntry = dartEntry;
+ }
+ _cache.accessed(unitSource);
+ int sourceTime = unitSource.modificationStamp;
+ int resultTime = results.modificationTime;
+ if (sourceTime == resultTime) {
+ if (dartEntry.modificationTime != sourceTime) {
+ sourceChanged(unitSource);
+ dartEntry = getReadableDartEntry(unitSource);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${unitSource.fullName}");
+ }
+ }
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null) {
+ dartCopy.setValue2(DartEntry.HINTS, librarySource, results.data);
+ ChangeNoticeImpl notice = getNotice(unitSource);
+ notice.setErrors(dartCopy.allErrors, dartCopy.getValue(SourceEntry.LINE_INFO));
+ } else {
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(unitSource, dartCopy);
+ dartEntry = dartCopy;
+ } else {
+ if (identical(dartEntry.getState2(DartEntry.HINTS, librarySource), CacheState.IN_PROCESS)) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.INVALID);
+ } else {
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(unitSource, dartCopy);
+ dartEntry = dartCopy;
+ }
+ }
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return libraryEntry;
+ }
+
+ /**
* Record the results produced by performing a [ParseDartTask]. If the results were computed
* from data that is now out-of-date, then the results will not be recorded.
*
@@ -6408,11 +4222,17 @@
} else {
dartCopy.recordParseError();
}
+ dartCopy.exception = thrownException;
_cache.put(source, dartCopy);
dartEntry = dartCopy;
} else {
DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.recordParseNotInProcess();
+ if (thrownException == null || resultTime >= 0) {
+ dartCopy.recordParseNotInProcess();
+ } else {
+ dartCopy.recordParseError();
+ }
+ dartCopy.exception = thrownException;
_cache.put(source, dartCopy);
dartEntry = dartCopy;
}
@@ -6466,19 +4286,27 @@
htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
}
+ htmlCopy.exception = thrownException;
_cache.put(source, htmlCopy);
htmlEntry = htmlCopy;
} else {
HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
- if (identical(htmlCopy.getState(SourceEntry.LINE_INFO), CacheState.IN_PROCESS)) {
- htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
+ if (thrownException == null || resultTime >= 0) {
+ if (identical(htmlCopy.getState(SourceEntry.LINE_INFO), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
+ }
+ if (identical(htmlCopy.getState(HtmlEntry.PARSED_UNIT), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.INVALID);
+ }
+ if (identical(htmlCopy.getState(HtmlEntry.REFERENCED_LIBRARIES), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.INVALID);
+ }
+ } else {
+ htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
+ htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
+ htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
}
- if (identical(htmlCopy.getState(HtmlEntry.PARSED_UNIT), CacheState.IN_PROCESS)) {
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.INVALID);
- }
- if (identical(htmlCopy.getState(HtmlEntry.REFERENCED_LIBRARIES), CacheState.IN_PROCESS)) {
- htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.INVALID);
- }
+ htmlCopy.exception = thrownException;
_cache.put(source, htmlCopy);
htmlEntry = htmlCopy;
}
@@ -6501,56 +4329,68 @@
LibraryResolver resolver = task.libraryResolver;
AnalysisException thrownException = task.exception;
DartEntry unitEntry = null;
- {
- if (allModificationTimesMatch(resolver)) {
- Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
- Source unitSource = task.unitSource;
- RecordingErrorListener errorListener = resolver.errorListener;
- for (Library library in resolver.resolvedLibraries) {
- Source librarySource = library.librarySource;
- for (Source source in library.compilationUnitSources) {
- CompilationUnit unit = library.getAST(source);
- List<AnalysisError> errors = errorListener.getErrors2(source);
- unit.resolutionErrors = errors;
- LineInfo lineInfo = unit.lineInfo;
- DartEntry dartEntry = _cache.get(source) as DartEntry;
- int sourceTime = source.modificationStamp;
- if (dartEntry.modificationTime != sourceTime) {
- sourceChanged(source);
- dartEntry = getReadableDartEntry(source);
- if (dartEntry == null) {
- throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
+ Source unitSource = task.unitSource;
+ if (resolver != null) {
+ {
+ if (allModificationTimesMatch(resolver)) {
+ Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
+ RecordingErrorListener errorListener = resolver.errorListener;
+ for (Library library in resolver.resolvedLibraries) {
+ Source librarySource = library.librarySource;
+ for (Source source in library.compilationUnitSources) {
+ CompilationUnit unit = library.getAST(source);
+ List<AnalysisError> errors = errorListener.getErrors2(source);
+ unit.resolutionErrors = errors;
+ LineInfo lineInfo = unit.lineInfo;
+ DartEntry dartEntry = _cache.get(source) as DartEntry;
+ int sourceTime = source.modificationStamp;
+ if (dartEntry.modificationTime != sourceTime) {
+ sourceChanged(source);
+ dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
+ }
}
- }
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- if (thrownException == null) {
- dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, unit);
- dartCopy.setValue2(DartEntry.RESOLUTION_ERRORS, librarySource, errors);
- if (identical(source, librarySource)) {
- recordElementData(dartCopy, library.libraryElement, htmlSource);
- }
- } else {
- dartCopy.recordResolutionError();
- }
- _cache.put(source, dartCopy);
- if (source == unitSource) {
- unitEntry = dartCopy;
- }
- ChangeNoticeImpl notice = getNotice(source);
- notice.compilationUnit = unit;
- notice.setErrors(dartCopy.allErrors, lineInfo);
- }
- }
- } else {
- for (Library library in resolver.resolvedLibraries) {
- for (Source source in library.compilationUnitSources) {
- DartEntry dartEntry = getReadableDartEntry(source);
- if (dartEntry != null) {
DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.recordResolutionNotInProcess();
+ if (thrownException == null) {
+ dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
+ dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
+ dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, unit);
+ dartCopy.setValue2(DartEntry.RESOLUTION_ERRORS, librarySource, errors);
+ if (identical(source, librarySource)) {
+ recordElementData(dartCopy, library.libraryElement, htmlSource);
+ }
+ } else {
+ dartCopy.recordResolutionError();
+ }
+ dartCopy.exception = thrownException;
_cache.put(source, dartCopy);
+ if (source == unitSource) {
+ unitEntry = dartCopy;
+ }
+ ChangeNoticeImpl notice = getNotice(source);
+ notice.compilationUnit = unit;
+ notice.setErrors(dartCopy.allErrors, lineInfo);
+ }
+ }
+ } else {
+ for (Library library in resolver.resolvedLibraries) {
+ for (Source source in library.compilationUnitSources) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry != null) {
+ int resultTime = library.getModificationTime(source);
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ dartCopy.recordResolutionNotInProcess();
+ } else {
+ dartCopy.recordResolutionError();
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ if (source == unitSource) {
+ unitEntry = dartCopy;
+ }
+ }
}
}
}
@@ -6559,6 +4399,12 @@
if (thrownException != null) {
throw thrownException;
}
+ if (unitEntry == null) {
+ unitEntry = getReadableDartEntry(unitSource);
+ if (unitEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${unitSource.fullName}");
+ }
+ }
return unitEntry;
}
@@ -6571,40 +4417,47 @@
* @throws AnalysisException if the results could not be recorded
*/
SourceEntry recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
- Source source = task.source;
+ Source unitSource = task.source;
+ Source librarySource = task.librarySource;
AnalysisException thrownException = task.exception;
DartEntry dartEntry = null;
{
- SourceEntry sourceEntry = _cache.get(source);
+ SourceEntry sourceEntry = _cache.get(unitSource);
if (sourceEntry is! DartEntry) {
- throw new AnalysisException.con1("Internal error: attempting to reolve non-Dart file as a Dart file: ${source.fullName}");
+ throw new AnalysisException.con1("Internal error: attempting to reolve non-Dart file as a Dart file: ${unitSource.fullName}");
}
dartEntry = sourceEntry as DartEntry;
- _cache.accessed(source);
- int sourceTime = source.modificationStamp;
+ _cache.accessed(unitSource);
+ int sourceTime = unitSource.modificationStamp;
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (dartEntry.modificationTime != sourceTime) {
- sourceChanged(source);
- dartEntry = getReadableDartEntry(source);
+ sourceChanged(unitSource);
+ dartEntry = getReadableDartEntry(unitSource);
if (dartEntry == null) {
- throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${unitSource.fullName}");
}
}
DartEntryImpl dartCopy = dartEntry.writableCopy;
if (thrownException == null) {
- dartCopy.setValue2(DartEntry.RESOLVED_UNIT, task.librarySource, task.resolvedUnit);
+ dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, task.resolvedUnit);
} else {
- dartCopy.setState(DartEntry.RESOLVED_UNIT, CacheState.ERROR);
+ dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.ERROR);
}
- _cache.put(source, dartCopy);
+ dartCopy.exception = thrownException;
+ _cache.put(unitSource, dartCopy);
dartEntry = dartCopy;
} else {
DartEntryImpl dartCopy = dartEntry.writableCopy;
- if (identical(dartCopy.getState(DartEntry.RESOLVED_UNIT), CacheState.IN_PROCESS)) {
- dartCopy.setState(DartEntry.RESOLVED_UNIT, CacheState.INVALID);
+ if (thrownException == null || resultTime >= 0) {
+ if (identical(dartCopy.getState(DartEntry.RESOLVED_UNIT), CacheState.IN_PROCESS)) {
+ dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.INVALID);
+ }
+ } else {
+ dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.ERROR);
}
- _cache.put(source, dartCopy);
+ dartCopy.exception = thrownException;
+ _cache.put(unitSource, dartCopy);
dartEntry = dartCopy;
}
}
@@ -6650,16 +4503,22 @@
} else {
htmlCopy.recordResolutionError();
}
+ htmlCopy.exception = thrownException;
_cache.put(source, htmlCopy);
htmlEntry = htmlCopy;
} else {
HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- if (identical(htmlCopy.getState(HtmlEntry.ELEMENT), CacheState.IN_PROCESS)) {
- htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.INVALID);
+ if (thrownException == null || resultTime >= 0) {
+ if (identical(htmlCopy.getState(HtmlEntry.ELEMENT), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.INVALID);
+ }
+ if (identical(htmlCopy.getState(HtmlEntry.RESOLUTION_ERRORS), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.INVALID);
+ }
+ } else {
+ htmlCopy.recordResolutionError();
}
- if (identical(htmlCopy.getState(HtmlEntry.RESOLUTION_ERRORS), CacheState.IN_PROCESS)) {
- htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.INVALID);
- }
+ htmlCopy.exception = thrownException;
_cache.put(source, htmlCopy);
htmlEntry = htmlCopy;
}
@@ -6741,14 +4600,15 @@
* Instances of the class `AnalysisTaskResultRecorder` are used by an analysis context to
* record the results of a task.
*/
-class AnalysisContextImpl2_AnalysisTaskResultRecorder implements AnalysisTaskVisitor<SourceEntry> {
- final AnalysisContextImpl2 AnalysisContextImpl2_this;
- AnalysisContextImpl2_AnalysisTaskResultRecorder(this.AnalysisContextImpl2_this);
- DartEntry visitParseDartTask(ParseDartTask task) => AnalysisContextImpl2_this.recordParseDartTaskResults(task);
- HtmlEntry visitParseHtmlTask(ParseHtmlTask task) => AnalysisContextImpl2_this.recordParseHtmlTaskResults(task);
- DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) => AnalysisContextImpl2_this.recordResolveDartLibraryTaskResults(task);
- SourceEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisContextImpl2_this.recordResolveDartUnitTaskResults(task);
- SourceEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl2_this.recordResolveHtmlTaskResults(task);
+class AnalysisContextImpl_AnalysisTaskResultRecorder implements AnalysisTaskVisitor<SourceEntry> {
+ final AnalysisContextImpl AnalysisContextImpl_this;
+ AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
+ SourceEntry visitGenerateDartHintsTask(GenerateDartHintsTask task) => AnalysisContextImpl_this.recordGenerateDartHintsTask(task);
+ DartEntry visitParseDartTask(ParseDartTask task) => AnalysisContextImpl_this.recordParseDartTaskResults(task);
+ HtmlEntry visitParseHtmlTask(ParseHtmlTask task) => AnalysisContextImpl_this.recordParseHtmlTaskResults(task);
+ DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) => AnalysisContextImpl_this.recordResolveDartLibraryTaskResults(task);
+ SourceEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisContextImpl_this.recordResolveDartUnitTaskResults(task);
+ SourceEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl_this.recordResolveHtmlTaskResults(task);
}
/**
* Instances of the class `AnalysisErrorInfoImpl` represent the analysis errors and line info
@@ -6809,6 +4669,12 @@
* information and pub best practices).
*/
bool _hint = true;
+
+ /**
+ * A flag indicating whether analysis is to generate dart2js related hint results.
+ */
+ bool _dart2jsHint = true;
+ bool get dart2jsHint => _dart2jsHint;
bool get hint => _hint;
/**
@@ -6820,6 +4686,15 @@
bool get strictMode => _strictMode;
/**
+ * Set whether analysis is to generate dart2js related hint results.
+ *
+ * @param hint `true` if analysis is to generate dart2js related hint results
+ */
+ void set dart2jsHint(bool dart2jsHints) {
+ this._dart2jsHint = dart2jsHints;
+ }
+
+ /**
* Set whether analysis is to generate hint results (e.g. type inference based information and pub
* best practices).
*
@@ -7183,253 +5058,6 @@
}
}
/**
- * Instances of the class `DelegatingAnalysisContextImpl` extend [AnalysisContextImpl
- ] to delegate sources to the appropriate analysis context. For instance, if the
- * source is in a system library then the analysis context from the [DartSdk] is used.
- *
- * @coverage dart.engine
- */
-class DelegatingAnalysisContextImpl2 extends AnalysisContextImpl2 {
-
- /**
- * This references the [InternalAnalysisContext] held onto by the [DartSdk] which is
- * used (instead of this [AnalysisContext]) for SDK sources. This field is set when
- * #setSourceFactory(SourceFactory) is called, and references the analysis context in the
- * [DartUriResolver] in the [SourceFactory], this analysis context assumes that there
- * will be such a resolver.
- */
- InternalAnalysisContext _sdkAnalysisContext;
- void addSourceInfo(Source source, SourceEntry info) {
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.addSourceInfo(source, info);
- } else {
- super.addSourceInfo(source, info);
- }
- }
- List<AnalysisError> computeErrors(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeErrors(source);
- } else {
- return super.computeErrors(source);
- }
- }
- List<Source> computeExportedLibraries(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeExportedLibraries(source);
- } else {
- return super.computeExportedLibraries(source);
- }
- }
- HtmlElement computeHtmlElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeHtmlElement(source);
- } else {
- return super.computeHtmlElement(source);
- }
- }
- List<Source> computeImportedLibraries(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeImportedLibraries(source);
- } else {
- return super.computeImportedLibraries(source);
- }
- }
- SourceKind computeKindOf(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeKindOf(source);
- } else {
- return super.computeKindOf(source);
- }
- }
- LibraryElement computeLibraryElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeLibraryElement(source);
- } else {
- return super.computeLibraryElement(source);
- }
- }
- LineInfo computeLineInfo(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeLineInfo(source);
- } else {
- return super.computeLineInfo(source);
- }
- }
- ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeResolvableCompilationUnit(source);
- } else {
- return super.computeResolvableCompilationUnit(source);
- }
- }
- AnalysisErrorInfo getErrors(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getErrors(source);
- } else {
- return super.getErrors(source);
- }
- }
- HtmlElement getHtmlElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getHtmlElement(source);
- } else {
- return super.getHtmlElement(source);
- }
- }
- List<Source> getHtmlFilesReferencing(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getHtmlFilesReferencing(source);
- } else {
- return super.getHtmlFilesReferencing(source);
- }
- }
- SourceKind getKindOf(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getKindOf(source);
- } else {
- return super.getKindOf(source);
- }
- }
- List<Source> getLibrariesContaining(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibrariesContaining(source);
- } else {
- return super.getLibrariesContaining(source);
- }
- }
- List<Source> getLibrariesDependingOn(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibrariesDependingOn(librarySource);
- } else {
- return super.getLibrariesDependingOn(librarySource);
- }
- }
- LibraryElement getLibraryElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibraryElement(source);
- } else {
- return super.getLibraryElement(source);
- }
- }
- List<Source> get librarySources => ArrayUtils.addAll(super.librarySources, _sdkAnalysisContext.librarySources);
- LineInfo getLineInfo(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getLineInfo(source);
- } else {
- return super.getLineInfo(source);
- }
- }
- Namespace getPublicNamespace(LibraryElement library) {
- Source source = library.source;
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getPublicNamespace(library);
- } else {
- return super.getPublicNamespace(library);
- }
- }
- Namespace getPublicNamespace2(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getPublicNamespace2(source);
- } else {
- return super.getPublicNamespace2(source);
- }
- }
- CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.getResolvedCompilationUnit(unitSource, library);
- } else {
- return super.getResolvedCompilationUnit(unitSource, library);
- }
- }
- CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.getResolvedCompilationUnit2(unitSource, librarySource);
- } else {
- return super.getResolvedCompilationUnit2(unitSource, librarySource);
- }
- }
- bool isClientLibrary(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.isClientLibrary(librarySource);
- } else {
- return super.isClientLibrary(librarySource);
- }
- }
- bool isServerLibrary(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.isServerLibrary(librarySource);
- } else {
- return super.isServerLibrary(librarySource);
- }
- }
- CompilationUnit parseCompilationUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.parseCompilationUnit(source);
- } else {
- return super.parseCompilationUnit(source);
- }
- }
- HtmlUnit parseHtmlUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.parseHtmlUnit(source);
- } else {
- return super.parseHtmlUnit(source);
- }
- }
- void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
- if (elementMap.isEmpty) {
- return;
- }
- Source source = new JavaIterator(elementMap.keys.toSet()).next();
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.recordLibraryElements(elementMap);
- } else {
- super.recordLibraryElements(elementMap);
- }
- }
- CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveCompilationUnit(source, library);
- } else {
- return super.resolveCompilationUnit(source, library);
- }
- }
- CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveCompilationUnit2(unitSource, librarySource);
- } else {
- return super.resolveCompilationUnit2(unitSource, librarySource);
- }
- }
- HtmlUnit resolveHtmlUnit(Source unitSource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveHtmlUnit(unitSource);
- } else {
- return super.resolveHtmlUnit(unitSource);
- }
- }
- void setContents(Source source, String contents) {
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.setContents(source, contents);
- } else {
- super.setContents(source, contents);
- }
- }
- void set sourceFactory(SourceFactory factory) {
- super.sourceFactory = factory;
- DartSdk sdk = factory.dartSdk;
- if (sdk != null) {
- _sdkAnalysisContext = sdk.context as InternalAnalysisContext;
- if (_sdkAnalysisContext is DelegatingAnalysisContextImpl2) {
- _sdkAnalysisContext = null;
- throw new IllegalStateException("The context provided by an SDK cannot itself be a delegating analysis context");
- }
- } else {
- throw new IllegalStateException("SourceFactorys provided to DelegatingAnalysisContextImpls must have a DartSdk associated with the provided SourceFactory.");
- }
- }
-}
-/**
* Instances of the class `InstrumentedAnalysisContextImpl` implement an
* [AnalysisContext] by recording instrumentation data and delegating to
* another analysis context to do the non-instrumentation work.
@@ -7462,7 +5090,7 @@
* Create a new [InstrumentedAnalysisContextImpl] which wraps a new
* [AnalysisContextImpl] as the basis context.
*/
- InstrumentedAnalysisContextImpl() : this.con1(AnalysisEngine.instance.useExperimentalContext ? new DelegatingAnalysisContextImpl2() : new DelegatingAnalysisContextImpl());
+ InstrumentedAnalysisContextImpl() : this.con1(new DelegatingAnalysisContextImpl());
/**
* Create a new [InstrumentedAnalysisContextImpl] with a specified basis context, aka the
@@ -7770,6 +5398,7 @@
}
}
AnalysisContentStatistics get statistics => basis.statistics;
+ TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement) => basis.internalResolveCompilationUnit(unitSource, libraryElement);
bool isClientLibrary(Source librarySource) {
InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-isClientLibrary");
try {
@@ -8015,6 +5644,19 @@
AnalysisContentStatistics get statistics;
/**
+ * Return a time-stamped fully-resolved compilation unit for the given source in the given
+ * library.
+ *
+ * @param unitSource the source of the compilation unit for which a resolved AST structure is to
+ * be returned
+ * @param libraryElement the element representing the library in which the compilation unit is to
+ * be resolved
+ * @return a time-stamped fully-resolved compilation unit for the source
+ * @throws AnalysisException if the resolved compilation unit could not be computed
+ */
+ TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement);
+
+ /**
* Given a table mapping the source for the libraries represented by the corresponding elements to
* the elements representing the libraries, record those mappings.
*
@@ -8024,6 +5666,36 @@
void recordLibraryElements(Map<Source, LibraryElement> elementMap);
}
/**
+ * Container with global [AnalysisContext] performance statistics.
+ */
+class PerformanceStatistics {
+
+ /**
+ * The [TimeCounter] for time spent in scanning.
+ */
+ static TimeCounter scan = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in parsing.
+ */
+ static TimeCounter parse = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in resolving.
+ */
+ static TimeCounter resolve = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in error verifier.
+ */
+ static TimeCounter errors = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in hints generator.
+ */
+ static TimeCounter hints = new TimeCounter();
+}
+/**
* Instances of the class `RecordingErrorListener` implement an error listener that will
* record the errors that are reported to it in a way that is appropriate for caching those errors
* within an analysis context.
@@ -8116,7 +5788,6 @@
}
Object visitConstructorName(ConstructorName node) {
node.staticElement = null;
- node.element = null;
return super.visitConstructorName(node);
}
Object visitDirective(Directive node) {
@@ -8144,7 +5815,6 @@
}
Object visitInstanceCreationExpression(InstanceCreationExpression node) {
node.staticElement = null;
- node.element = null;
return super.visitInstanceCreationExpression(node);
}
Object visitPostfixExpression(PostfixExpression node) {
@@ -8159,7 +5829,6 @@
}
Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
node.staticElement = null;
- node.element = null;
return super.visitRedirectingConstructorInvocation(node);
}
Object visitSimpleIdentifier(SimpleIdentifier node) {
@@ -8169,7 +5838,6 @@
}
Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
node.staticElement = null;
- node.element = null;
return super.visitSuperConstructorInvocation(node);
}
}
@@ -8178,17 +5846,7 @@
* referenced by any other objects and for which we have modification stamp information. It is used
* by the [LibraryResolver] to resolve a library.
*/
-class ResolvableCompilationUnit {
-
- /**
- * The modification time of the source from which the AST was created.
- */
- int modificationTime = 0;
-
- /**
- * The AST that was created from the source.
- */
- CompilationUnit compilationUnit;
+class ResolvableCompilationUnit extends TimestampedData<CompilationUnit> {
/**
* Initialize a newly created holder to hold the given values.
@@ -8196,27 +5854,21 @@
* @param modificationTime the modification time of the source from which the AST was created
* @param unit the AST that was created from the source
*/
- ResolvableCompilationUnit(int modificationTime, CompilationUnit unit) {
- this.modificationTime = modificationTime;
- this.compilationUnit = unit;
- }
+ ResolvableCompilationUnit(int modificationTime, CompilationUnit unit) : super(modificationTime, unit);
+
+ /**
+ * Return the AST that was created from the source.
+ *
+ * @return the AST that was created from the source
+ */
+ CompilationUnit get compilationUnit => data;
}
/**
* Instances of the class `ResolvableHtmlUnit` represent an HTML unit that is not referenced
* by any other objects and for which we have modification stamp information. It is used by the
* [ResolveHtmlTask] to resolve an HTML source.
*/
-class ResolvableHtmlUnit {
-
- /**
- * The modification time of the source from which the AST was created.
- */
- int modificationTime = 0;
-
- /**
- * The AST that was created from the source.
- */
- HtmlUnit compilationUnit;
+class ResolvableHtmlUnit extends TimestampedData<HtmlUnit> {
/**
* Initialize a newly created holder to hold the given values.
@@ -8224,9 +5876,40 @@
* @param modificationTime the modification time of the source from which the AST was created
* @param unit the AST that was created from the source
*/
- ResolvableHtmlUnit(int modificationTime, HtmlUnit unit) {
+ ResolvableHtmlUnit(int modificationTime, HtmlUnit unit) : super(modificationTime, unit);
+
+ /**
+ * Return the AST that was created from the source.
+ *
+ * @return the AST that was created from the source
+ */
+ HtmlUnit get compilationUnit => data;
+}
+/**
+ * Instances of the class `TimestampedData` represent analysis data for which we have a
+ * modification time.
+ */
+class TimestampedData<E> {
+
+ /**
+ * The modification time of the source from which the data was created.
+ */
+ int modificationTime = 0;
+
+ /**
+ * The data that was created from the source.
+ */
+ E data;
+
+ /**
+ * Initialize a newly created holder to hold the given values.
+ *
+ * @param modificationTime the modification time of the source from which the data was created
+ * @param unit the data that was created from the source
+ */
+ TimestampedData(int modificationTime, E data) {
this.modificationTime = modificationTime;
- this.compilationUnit = unit;
+ this.data = data;
}
}
/**
@@ -8320,6 +6003,15 @@
abstract class AnalysisTaskVisitor<E> {
/**
+ * Visit a [GenerateDartHintsTask].
+ *
+ * @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 visitGenerateDartHintsTask(GenerateDartHintsTask task);
+
+ /**
* Visit a [ParseDartTask].
*
* @param task the task to be visited
@@ -8365,6 +6057,76 @@
E visitResolveHtmlTask(ResolveHtmlTask task);
}
/**
+ * Instances of the class `GenerateDartHintsTask` generate hints for a single Dart library.
+ */
+class GenerateDartHintsTask extends AnalysisTask {
+
+ /**
+ * The element model for the library being analyzed.
+ */
+ LibraryElement libraryElement;
+
+ /**
+ * A table mapping the sources that were analyzed to the hints that were generated for the
+ * sources.
+ */
+ Map<Source, TimestampedData<List<AnalysisError>>> hintMap;
+
+ /**
+ * 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 libraryElement the element model for the library being analyzed
+ */
+ GenerateDartHintsTask(InternalAnalysisContext context, LibraryElement libraryElement) : super(context) {
+ this.libraryElement = libraryElement;
+ }
+ accept(AnalysisTaskVisitor visitor) => visitor.visitGenerateDartHintsTask(this);
+ String get taskDescription {
+ Source librarySource = libraryElement.source;
+ if (librarySource == null) {
+ return "generate Dart hints for library without source";
+ }
+ return "generate Dart hints for ${librarySource.fullName}";
+ }
+ void internalPerform() {
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ List<CompilationUnitElement> parts = libraryElement.parts;
+ int partCount = parts.length;
+ List<CompilationUnit> compilationUnits = new List<CompilationUnit>(partCount + 1);
+ Map<Source, TimestampedData<CompilationUnit>> timestampMap = new Map<Source, TimestampedData<CompilationUnit>>();
+ Source unitSource = libraryElement.definingCompilationUnit.source;
+ TimestampedData<CompilationUnit> resolvedUnit = getCompilationUnit(unitSource);
+ timestampMap[unitSource] = resolvedUnit;
+ compilationUnits[0] = resolvedUnit.data;
+ for (int i = 0; i < partCount; i++) {
+ unitSource = parts[i].source;
+ resolvedUnit = getCompilationUnit(unitSource);
+ timestampMap[unitSource] = resolvedUnit;
+ compilationUnits[i + 1] = resolvedUnit.data;
+ }
+ HintGenerator hintGenerator = new HintGenerator(compilationUnits, context, errorListener);
+ hintGenerator.generateForLibrary();
+ hintMap = new Map<Source, TimestampedData<List<AnalysisError>>>();
+ for (MapEntry<Source, TimestampedData<CompilationUnit>> entry in getMapEntrySet(timestampMap)) {
+ Source source = entry.getKey();
+ TimestampedData<CompilationUnit> unitData = entry.getValue();
+ List<AnalysisError> errors = errorListener.getErrors2(source);
+ hintMap[source] = new TimestampedData<List<AnalysisError>>(unitData.modificationTime, errors);
+ unitData.data.hints = errors;
+ }
+ }
+
+ /**
+ * Return the resolved compilation unit associated with the given source.
+ *
+ * @param unitSource the source for the compilation unit whose resolved AST is to be returned
+ * @return the resolved compilation unit associated with the given source
+ * @throws AnalysisException if the resolved compilation unit could not be computed
+ */
+ TimestampedData<CompilationUnit> getCompilationUnit(Source unitSource) => context.internalResolveCompilationUnit(unitSource, libraryElement);
+}
+/**
* Instances of the class `ParseDartTask` parse a specific source as a Dart file.
*/
class ParseDartTask extends AnalysisTask {
@@ -8469,17 +6231,25 @@
* @return `true` if the source contains a 'part of' directive
*/
bool hasPartOfDirective() => _hasPartOfDirective2;
- String get taskDescription => "parse as dart ${source.fullName}";
+ String get taskDescription {
+ if (source == null) {
+ return "parse as dart null source";
+ }
+ return "parse as dart ${source.fullName}";
+ }
void internalPerform() {
RecordingErrorListener errorListener = new RecordingErrorListener();
List<Token> token = [null];
- Source_ContentReceiver receiver = new Source_ContentReceiver_10(this, errorListener, token);
+ TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start();
+ Source_ContentReceiver receiver = new Source_ContentReceiver_9(this, errorListener, token);
try {
source.getContents(receiver);
} catch (exception) {
modificationTime = source.modificationStamp;
throw new AnalysisException.con3(exception);
}
+ timeCounterScan.stop();
+ TimeCounter_TimeCounterHandle timeCounterParse = PerformanceStatistics.parse.start();
Parser parser = new Parser(source, errorListener);
compilationUnit = parser.parseCompilationUnit(token[0]);
errors = errorListener.getErrors2(source);
@@ -8507,6 +6277,7 @@
}
compilationUnit.parsingErrors = errors;
compilationUnit.lineInfo = lineInfo;
+ timeCounterParse.stop();
}
/**
@@ -8549,11 +6320,11 @@
return new List.from(sources);
}
}
-class Source_ContentReceiver_10 implements Source_ContentReceiver {
+class Source_ContentReceiver_9 implements Source_ContentReceiver {
final ParseDartTask ParseDartTask_this;
RecordingErrorListener errorListener;
List<Token> token;
- Source_ContentReceiver_10(this.ParseDartTask_this, this.errorListener, this.token);
+ Source_ContentReceiver_9(this.ParseDartTask_this, this.errorListener, this.token);
void accept(CharBuffer contents, int modificationTime2) {
ParseDartTask_this.modificationTime = modificationTime2;
CharBufferScanner scanner = new CharBufferScanner(ParseDartTask_this.source, contents, errorListener);
@@ -8628,7 +6399,12 @@
this.source = source;
}
accept(AnalysisTaskVisitor visitor) => visitor.visitParseHtmlTask(this);
- String get taskDescription => "parse as html ${source.fullName}";
+ String get taskDescription {
+ if (source == null) {
+ return "parse as html null source";
+ }
+ return "parse as html ${source.fullName}";
+ }
void internalPerform() {
HtmlScanner scanner = new HtmlScanner(source);
try {
@@ -8651,17 +6427,17 @@
*/
List<Source> get librarySources {
List<Source> libraries = new List<Source>();
- htmlUnit.accept(new RecursiveXmlVisitor_11(this, libraries));
+ htmlUnit.accept(new RecursiveXmlVisitor_10(this, libraries));
if (libraries.isEmpty) {
return Source.EMPTY_ARRAY;
}
return new List.from(libraries);
}
}
-class RecursiveXmlVisitor_11 extends RecursiveXmlVisitor<Object> {
+class RecursiveXmlVisitor_10 extends RecursiveXmlVisitor<Object> {
final ParseHtmlTask ParseHtmlTask_this;
List<Source> libraries;
- RecursiveXmlVisitor_11(this.ParseHtmlTask_this, this.libraries) : super();
+ RecursiveXmlVisitor_10(this.ParseHtmlTask_this, this.libraries) : super();
Object visitXmlTagNode(XmlTagNode node) {
if (javaStringEqualsIgnoreCase(node.tag.lexeme, ParseHtmlTask._TAG_SCRIPT)) {
bool isDartScript = false;
@@ -8723,7 +6499,12 @@
this.librarySource = librarySource;
}
accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartLibraryTask(this);
- String get taskDescription => "resolve library ${librarySource.fullName}";
+ String get taskDescription {
+ if (librarySource == null) {
+ return "resolve library null source";
+ }
+ return "resolve library ${librarySource.fullName}";
+ }
void internalPerform() {
libraryResolver = new LibraryResolver(context);
libraryResolver.resolveLibrary(librarySource, true);
@@ -8774,7 +6555,13 @@
* @return the source for the library containing the source that is to be resolved
*/
Source get librarySource => _libraryElement.source;
- String get taskDescription => "resolve unit ${_libraryElement.source.fullName}";
+ String get taskDescription {
+ Source librarySource = _libraryElement.source;
+ if (librarySource == null) {
+ return "resolve unit null source";
+ }
+ return "resolve unit ${librarySource.fullName}";
+ }
void internalPerform() {
Source coreLibrarySource = _libraryElement.context.sourceFactory.forUri(DartSdk.DART_CORE);
LibraryElement coreElement = context.computeLibraryElement(coreLibrarySource);
@@ -8797,11 +6584,13 @@
resolverVisitor.reportError(conditionalCode.analysisError);
}
}
+ TimeCounter_TimeCounterHandle counterHandleErrors = PerformanceStatistics.errors.start();
ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, _libraryElement, typeProvider, inheritanceManager);
unit.accept(errorVerifier);
ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, typeProvider);
unit.accept(constantVerifier);
+ counterHandleErrors.stop();
unit.resolutionErrors = errorListener.errors;
resolvedUnit = unit;
}
@@ -8863,7 +6652,12 @@
this.source = source;
}
accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this);
- String get taskDescription => "resolve as html ${source.fullName}";
+ String get taskDescription {
+ if (source == null) {
+ return "resolve as html null source";
+ }
+ return "resolve as html ${source.fullName}";
+ }
void internalPerform() {
ResolvableHtmlUnit resolvableHtmlUnit = context.computeResolvableHtmlUnit(source);
HtmlUnit unit = resolvableHtmlUnit.compilationUnit;
diff --git a/pkg/analyzer_experimental/lib/src/generated/error.dart b/pkg/analyzer_experimental/lib/src/generated/error.dart
index 0cd73fa..b57ab78 100644
--- a/pkg/analyzer_experimental/lib/src/generated/error.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/error.dart
@@ -20,10 +20,9 @@
static final ErrorSeverity NONE = new ErrorSeverity('NONE', 0, " ", "none");
/**
- * The severity representing a suggestion. Suggestions are not specified in the Dart language
- * specification, but provide information about best practices.
+ * The severity representing an informational level analysis issue.
*/
- static final ErrorSeverity SUGGESTION = new ErrorSeverity('SUGGESTION', 1, "S", "suggestion");
+ static final ErrorSeverity INFO = new ErrorSeverity('INFO', 1, "I", "info");
/**
* The severity representing a warning. Warnings can become errors if the `-Werror` command
@@ -35,7 +34,7 @@
* The severity representing an error.
*/
static final ErrorSeverity ERROR = new ErrorSeverity('ERROR', 3, "E", "error");
- static final List<ErrorSeverity> values = [NONE, SUGGESTION, WARNING, ERROR];
+ static final List<ErrorSeverity> values = [NONE, INFO, WARNING, ERROR];
/**
* The name of the severity used when producing machine output.
@@ -363,6 +362,37 @@
ErrorProperty(String name, int ordinal) : super(name, ordinal);
}
/**
+ * The enumeration `TodoCode` defines the single TODO `ErrorCode`.
+ */
+class TodoCode extends Enum<TodoCode> implements ErrorCode {
+
+ /**
+ * The single enum of TodoCode.
+ */
+ static final TodoCode TODO = new TodoCode('TODO', 0);
+ static final List<TodoCode> values = [TODO];
+
+ /**
+ * This matches the two common Dart task styles
+ *
+ * * TODO:
+ * * TODO(username):
+ *
+ * As well as
+ * * TODO
+ *
+ * But not
+ * * todo
+ * * TODOS
+ */
+ static RegExp TODO_REGEX = new RegExp("([\\s/\\*])((TODO[^\\w\\d][^\\r\\n]*)|(TODO:?\$))");
+ TodoCode(String name, int ordinal) : super(name, ordinal);
+ String get correction => null;
+ ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
+ String get message => "%s";
+ ErrorType get type => ErrorType.TODO;
+}
+/**
* The enumeration `HintCode` defines the hints and coding recommendations for best practices
* which are not mentioned in the Dart Language Specification.
*/
@@ -390,13 +420,99 @@
static final HintCode DEAD_CODE_ON_CATCH_SUBTYPE = new HintCode.con1('DEAD_CODE_ON_CATCH_SUBTYPE', 2, "Dead code, this on-catch block will never be executed since '%s' is a subtype of '%s'");
/**
+ * Duplicate imports.
+ */
+ static final HintCode DUPLICATE_IMPORT = new HintCode.con1('DUPLICATE_IMPORT', 3, "Duplicate import");
+
+ /**
+ * Hint to use the ~/ operator.
+ */
+ static final HintCode DIVISION_OPTIMIZATION = new HintCode.con1('DIVISION_OPTIMIZATION', 4, "The operator x ~/ y is more efficient than (x / y).toInt()");
+
+ /**
+ * Hint for the `x is double` type checks.
+ */
+ static final HintCode IS_DOUBLE = new HintCode.con1('IS_DOUBLE', 5, "When compiled to JS, this test might return true when the left hand side is an int");
+
+ /**
+ * Hint for the `x is int` type checks.
+ */
+ static final HintCode IS_INT = new HintCode.con1('IS_INT', 6, "When compiled to JS, this test might return true when the left hand side is a double");
+
+ /**
+ * Hint for the `x is! double` type checks.
+ */
+ static final HintCode IS_NOT_DOUBLE = new HintCode.con1('IS_NOT_DOUBLE', 7, "When compiled to JS, this test might return false when the left hand side is an int");
+
+ /**
+ * Hint for the `x is! int` type checks.
+ */
+ static final HintCode IS_NOT_INT = new HintCode.con1('IS_NOT_INT', 8, "When compiled to JS, this test might return false when the left hand side is a double");
+
+ /**
+ * 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 final HintCode OVERRIDDING_PRIVATE_MEMBER = new HintCode.con1('OVERRIDDING_PRIVATE_MEMBER', 9, "The %s '%s' does not override the definition from '%s' because it is private and in a different library");
+
+ /**
+ * Hint for classes that override equals, but not hashCode.
+ *
+ * @param className the name of the current class
+ */
+ static final HintCode OVERRIDE_EQUALS_BUT_NOT_HASH_CODE = new HintCode.con1('OVERRIDE_EQUALS_BUT_NOT_HASH_CODE', 10, "The class '%s' overrides 'operator==', but not 'get hashCode'");
+
+ /**
+ * Type checks of the type `x is! Null` should be done with `x != null`.
+ */
+ static final HintCode TYPE_CHECK_IS_NOT_NULL = new HintCode.con1('TYPE_CHECK_IS_NOT_NULL', 11, "Tests for non-null should be done with '!= null'");
+
+ /**
+ * Type checks of the type `x is Null` should be done with `x == null`.
+ */
+ static final HintCode TYPE_CHECK_IS_NULL = new HintCode.con1('TYPE_CHECK_IS_NULL', 12, "Tests for null should be done with '== null'");
+
+ /**
+ * Unnecessary cast.
+ */
+ static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 13, "Unnecessary cast");
+
+ /**
+ * Unnecessary type checks, the result is always true.
+ */
+ static final HintCode UNNECESSARY_TYPE_CHECK_FALSE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_FALSE', 14, "Unnecessary type check, the result is always false");
+
+ /**
+ * Unnecessary type checks, the result is always false.
+ */
+ static final HintCode UNNECESSARY_TYPE_CHECK_TRUE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_TRUE', 15, "Unnecessary type check, the result is always true");
+
+ /**
* Unused imports are imports which are never not used.
*/
- static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 3, "Unused import");
+ static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 16, "Unused import");
static final List<HintCode> values = [
DEAD_CODE,
DEAD_CODE_CATCH_FOLLOWING_CATCH,
DEAD_CODE_ON_CATCH_SUBTYPE,
+ DUPLICATE_IMPORT,
+ DIVISION_OPTIMIZATION,
+ IS_DOUBLE,
+ IS_INT,
+ IS_NOT_DOUBLE,
+ IS_NOT_INT,
+ OVERRIDDING_PRIVATE_MEMBER,
+ OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
+ TYPE_CHECK_IS_NOT_NULL,
+ TYPE_CHECK_IS_NULL,
+ UNNECESSARY_CAST,
+ UNNECESSARY_TYPE_CHECK_FALSE,
+ UNNECESSARY_TYPE_CHECK_TRUE,
UNUSED_IMPORT];
/**
@@ -485,40 +601,46 @@
class ErrorType extends Enum<ErrorType> {
/**
+ * Task (todo) comments in user code.
+ */
+ static final ErrorType TODO = new ErrorType('TODO', 0, ErrorSeverity.INFO);
+
+ /**
* Extra analysis run over the code to follow best practices, which are not in the Dart Language
* Specification.
*/
- static final ErrorType HINT = new ErrorType('HINT', 0, ErrorSeverity.SUGGESTION);
+ static final ErrorType HINT = new ErrorType('HINT', 1, ErrorSeverity.WARNING);
/**
* Compile-time errors are errors that preclude execution. A compile time error must be reported
* by a Dart compiler before the erroneous code is executed.
*/
- static final ErrorType COMPILE_TIME_ERROR = new ErrorType('COMPILE_TIME_ERROR', 1, ErrorSeverity.ERROR);
+ static final ErrorType COMPILE_TIME_ERROR = new ErrorType('COMPILE_TIME_ERROR', 2, ErrorSeverity.ERROR);
/**
* Suggestions made in situations where the user has deviated from recommended pub programming
* practices.
*/
- static final ErrorType PUB_SUGGESTION = new ErrorType('PUB_SUGGESTION', 2, ErrorSeverity.SUGGESTION);
+ static final ErrorType PUB_SUGGESTION = new ErrorType('PUB_SUGGESTION', 3, ErrorSeverity.WARNING);
/**
* Static warnings are those warnings reported by the static checker. They have no effect on
* execution. Static warnings must be provided by Dart compilers used during development.
*/
- static final ErrorType STATIC_WARNING = new ErrorType('STATIC_WARNING', 3, ErrorSeverity.WARNING);
+ static final ErrorType STATIC_WARNING = new ErrorType('STATIC_WARNING', 4, ErrorSeverity.WARNING);
/**
* Many, but not all, static warnings relate to types, in which case they are known as static type
* warnings.
*/
- static final ErrorType STATIC_TYPE_WARNING = new ErrorType('STATIC_TYPE_WARNING', 4, ErrorSeverity.WARNING);
+ static final ErrorType STATIC_TYPE_WARNING = new ErrorType('STATIC_TYPE_WARNING', 5, ErrorSeverity.WARNING);
/**
* Syntactic errors are errors produced as a result of input that does not conform to the grammar.
*/
- static final ErrorType SYNTACTIC_ERROR = new ErrorType('SYNTACTIC_ERROR', 5, ErrorSeverity.ERROR);
+ static final ErrorType SYNTACTIC_ERROR = new ErrorType('SYNTACTIC_ERROR', 6, ErrorSeverity.ERROR);
static final List<ErrorType> values = [
+ TODO,
HINT,
COMPILE_TIME_ERROR,
PUB_SUGGESTION,
@@ -539,6 +661,7 @@
ErrorType(String name, int ordinal, ErrorSeverity severity) : super(name, ordinal) {
this.severity = severity;
}
+ String get displayName => name.toLowerCase().replaceAll('_', ' ');
}
/**
* The enumeration `CompileTimeErrorCode` defines the error codes used for compile time
@@ -604,7 +727,7 @@
* 12.30 Identifier Reference: It is a compile-time error if a built-in identifier is used as the
* declared name of a class, type parameter or type alias.
*/
- static final CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME = new CompileTimeErrorCode.con1('BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME', 6, "The built-in identifier '%s' cannot be used as a type variable name");
+ static final CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME = new CompileTimeErrorCode.con1('BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME', 6, "The built-in identifier '%s' cannot be used as a type parameter name");
/**
* 13.9 Switch: It is a compile-time error if the class <i>C</i> implements the operator
@@ -701,42 +824,50 @@
static final CompileTimeErrorCode CONST_INSTANCE_FIELD = new CompileTimeErrorCode.con1('CONST_INSTANCE_FIELD', 19, "Only static fields can be declared as 'const'");
/**
+ * 5 Variables: A constant variable must be initialized to a compile-time constant (12.1) or a
+ * compile-time error occurs.
+ *
+ * @param name the name of the uninitialized final variable
+ */
+ static final CompileTimeErrorCode CONST_NOT_INITIALIZED = new CompileTimeErrorCode.con1('CONST_NOT_INITIALIZED', 20, "The const variable '%s' must be initialized");
+
+ /**
* 12.11.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2, where e, e1 and e2
* are constant expressions that evaluate to a boolean value.
*/
- static final CompileTimeErrorCode CONST_EVAL_TYPE_BOOL = new CompileTimeErrorCode.con1('CONST_EVAL_TYPE_BOOL', 20, "An expression of type 'bool' was expected");
+ static final CompileTimeErrorCode CONST_EVAL_TYPE_BOOL = new CompileTimeErrorCode.con1('CONST_EVAL_TYPE_BOOL', 21, "An expression of type 'bool' was expected");
/**
* 12.11.2 Const: An expression of one of the forms e1 == e2 or e1 != e2 where e1 and e2 are
* constant expressions that evaluate to a numeric, string or boolean value or to null.
*/
- static final CompileTimeErrorCode CONST_EVAL_TYPE_BOOL_NUM_STRING = new CompileTimeErrorCode.con1('CONST_EVAL_TYPE_BOOL_NUM_STRING', 21, "An expression of type 'bool', 'num', 'String' or 'null' was expected");
+ static final CompileTimeErrorCode CONST_EVAL_TYPE_BOOL_NUM_STRING = new CompileTimeErrorCode.con1('CONST_EVAL_TYPE_BOOL_NUM_STRING', 22, "An expression of type 'bool', 'num', 'String' or 'null' was expected");
/**
* 12.11.2 Const: An expression of one of the forms ~e, e1 ^ e2, e1 & e2, e1 | e2, e1 >> e2 or e1
* << e2, where e, e1 and e2 are constant expressions that evaluate to an integer value or to
* null.
*/
- static final CompileTimeErrorCode CONST_EVAL_TYPE_INT = new CompileTimeErrorCode.con1('CONST_EVAL_TYPE_INT', 22, "An expression of type 'int' was expected");
+ static final CompileTimeErrorCode CONST_EVAL_TYPE_INT = new CompileTimeErrorCode.con1('CONST_EVAL_TYPE_INT', 23, "An expression of type 'int' was expected");
/**
* 12.11.2 Const: An expression of one of the forms e, e1 + e2, e1 - e2, e1 * e2, e1 / e2, e1 ~/
* e2, e1 > e2, e1 < e2, e1 >= e2, e1 <= e2 or e1 % e2, where e, e1 and e2 are constant
* expressions that evaluate to a numeric value or to null..
*/
- static final CompileTimeErrorCode CONST_EVAL_TYPE_NUM = new CompileTimeErrorCode.con1('CONST_EVAL_TYPE_NUM', 23, "An expression of type 'num' was expected");
+ static final CompileTimeErrorCode CONST_EVAL_TYPE_NUM = new CompileTimeErrorCode.con1('CONST_EVAL_TYPE_NUM', 24, "An expression of type 'num' was expected");
/**
* 12.11.2 Const: It is a compile-time error if evaluation of a constant object results in an
* uncaught exception being thrown.
*/
- static final CompileTimeErrorCode CONST_EVAL_THROWS_EXCEPTION = new CompileTimeErrorCode.con1('CONST_EVAL_THROWS_EXCEPTION', 24, "Evaluation of this constant expression causes exception");
+ static final CompileTimeErrorCode CONST_EVAL_THROWS_EXCEPTION = new CompileTimeErrorCode.con1('CONST_EVAL_THROWS_EXCEPTION', 25, "Evaluation of this constant expression causes exception");
/**
* 12.11.2 Const: It is a compile-time error if evaluation of a constant object results in an
* uncaught exception being thrown.
*/
- static final CompileTimeErrorCode CONST_EVAL_THROWS_IDBZE = new CompileTimeErrorCode.con1('CONST_EVAL_THROWS_IDBZE', 25, "Evaluation of this constant expression throws IntegerDivisionByZeroException");
+ static final CompileTimeErrorCode CONST_EVAL_THROWS_IDBZE = new CompileTimeErrorCode.con1('CONST_EVAL_THROWS_IDBZE', 26, "Evaluation of this constant expression throws IntegerDivisionByZeroException");
/**
* 12.11.2 Const: If <i>T</i> is a parameterized type <i>S<U<sub>1</sub>, …,
@@ -749,7 +880,7 @@
* @see CompileTimeErrorCode#NEW_WITH_INVALID_TYPE_PARAMETERS
* @see StaticTypeWarningCode#WRONG_NUMBER_OF_TYPE_ARGUMENTS
*/
- static final CompileTimeErrorCode CONST_WITH_INVALID_TYPE_PARAMETERS = new CompileTimeErrorCode.con1('CONST_WITH_INVALID_TYPE_PARAMETERS', 26, "The type '%s' is declared with %d type parameters, but %d type arguments were given");
+ static final CompileTimeErrorCode CONST_WITH_INVALID_TYPE_PARAMETERS = new CompileTimeErrorCode.con1('CONST_WITH_INVALID_TYPE_PARAMETERS', 27, "The type '%s' is declared with %d type parameters, but %d type arguments were given");
/**
* 12.11.2 Const: If <i>e</i> is of the form <i>const T(a<sub>1</sub>, …, a<sub>n</sub>,
@@ -757,13 +888,13 @@
* compile-time error if the type <i>T</i> does not declare a constant constructor with the same
* name as the declaration of <i>T</i>.
*/
- static final CompileTimeErrorCode CONST_WITH_NON_CONST = new CompileTimeErrorCode.con1('CONST_WITH_NON_CONST', 27, "The constructor being called is not a 'const' constructor");
+ static final CompileTimeErrorCode CONST_WITH_NON_CONST = new CompileTimeErrorCode.con1('CONST_WITH_NON_CONST', 28, "The constructor being called is not a 'const' constructor");
/**
* 12.11.2 Const: In all of the above cases, it is a compile-time error if <i>a<sub>i</sub>, 1
* <= i <= n + k</i>, is not a compile-time constant expression.
*/
- static final CompileTimeErrorCode CONST_WITH_NON_CONSTANT_ARGUMENT = new CompileTimeErrorCode.con1('CONST_WITH_NON_CONSTANT_ARGUMENT', 28, "Arguments of a constant creation must be constant expressions");
+ static final CompileTimeErrorCode CONST_WITH_NON_CONSTANT_ARGUMENT = new CompileTimeErrorCode.con1('CONST_WITH_NON_CONSTANT_ARGUMENT', 29, "Arguments of a constant creation must be constant expressions");
/**
* 12.11.2 Const: It is a compile-time error if <i>T</i> is not a class accessible in the current
@@ -776,12 +907,12 @@
*
* @param name the name of the non-type element
*/
- static final CompileTimeErrorCode CONST_WITH_NON_TYPE = new CompileTimeErrorCode.con1('CONST_WITH_NON_TYPE', 29, "The name '%s' is not a class");
+ static final CompileTimeErrorCode CONST_WITH_NON_TYPE = new CompileTimeErrorCode.con1('CONST_WITH_NON_TYPE', 30, "The name '%s' is not a class");
/**
* 12.11.2 Const: It is a compile-time error if <i>T</i> includes any type parameters.
*/
- static final CompileTimeErrorCode CONST_WITH_TYPE_PARAMETERS = new CompileTimeErrorCode.con1('CONST_WITH_TYPE_PARAMETERS', 30, "The constant creation cannot use a type parameter");
+ static final CompileTimeErrorCode CONST_WITH_TYPE_PARAMETERS = new CompileTimeErrorCode.con1('CONST_WITH_TYPE_PARAMETERS', 31, "The constant creation cannot use a type parameter");
/**
* 12.11.2 Const: It is a compile-time error if <i>T.id</i> is not the name of a constant
@@ -790,7 +921,7 @@
* @param typeName the name of the type
* @param constructorName the name of the requested constant constructor
*/
- static final CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR = new CompileTimeErrorCode.con1('CONST_WITH_UNDEFINED_CONSTRUCTOR', 31, "The class '%s' does not have a constant constructor '%s'");
+ static final CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR = new CompileTimeErrorCode.con1('CONST_WITH_UNDEFINED_CONSTRUCTOR', 32, "The class '%s' does not have a constant constructor '%s'");
/**
* 12.11.2 Const: It is a compile-time error if <i>T.id</i> is not the name of a constant
@@ -798,26 +929,26 @@
*
* @param typeName the name of the type
*/
- static final CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT = new CompileTimeErrorCode.con1('CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT', 32, "The class '%s' does not have a default constant constructor");
+ static final CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT = new CompileTimeErrorCode.con1('CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT', 33, "The class '%s' does not have a default constant constructor");
/**
* 15.3.1 Typedef: It is a compile-time error if any default values are specified in the signature
* of a function type alias.
*/
- static final CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS = new CompileTimeErrorCode.con1('DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS', 33, "Default values aren't allowed in typedefs");
+ static final CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS = new CompileTimeErrorCode.con1('DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS', 34, "Default values aren't allowed in typedefs");
/**
* 6.2.1 Required Formals: By means of a function signature that names the parameter and describes
* its type as a function type. It is a compile-time error if any default values are specified in
* the signature of such a function type.
*/
- static final CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER = new CompileTimeErrorCode.con1('DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER', 34, "Default values aren't allowed in function type parameters");
+ static final CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER = new CompileTimeErrorCode.con1('DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER', 35, "Default values aren't allowed in function type parameters");
/**
* 3.1 Scoping: It is a compile-time error if there is more than one entity with the same name
* declared in the same scope.
*/
- static final CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT = new CompileTimeErrorCode.con1('DUPLICATE_CONSTRUCTOR_DEFAULT', 35, "The default constructor is already defined");
+ static final CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT = new CompileTimeErrorCode.con1('DUPLICATE_CONSTRUCTOR_DEFAULT', 36, "The default constructor is already defined");
/**
* 3.1 Scoping: It is a compile-time error if there is more than one entity with the same name
@@ -825,7 +956,7 @@
*
* @param duplicateName the name of the duplicate entity
*/
- static final CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME = new CompileTimeErrorCode.con1('DUPLICATE_CONSTRUCTOR_NAME', 36, "The constructor with name '%s' is already defined");
+ static final CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME = new CompileTimeErrorCode.con1('DUPLICATE_CONSTRUCTOR_NAME', 37, "The constructor with name '%s' is already defined");
/**
* 3.1 Scoping: It is a compile-time error if there is more than one entity with the same name
@@ -838,7 +969,7 @@
*
* @param duplicateName the name of the duplicate entity
*/
- static final CompileTimeErrorCode DUPLICATE_DEFINITION = new CompileTimeErrorCode.con1('DUPLICATE_DEFINITION', 37, "The name '%s' is already defined");
+ static final CompileTimeErrorCode DUPLICATE_DEFINITION = new CompileTimeErrorCode.con1('DUPLICATE_DEFINITION', 38, "The name '%s' is already defined");
/**
* 7. Classes: It is a compile-time error if a class has an instance member and a static member
@@ -850,21 +981,21 @@
* @param name the name of the conflicting members
* @see #DUPLICATE_DEFINITION
*/
- static final CompileTimeErrorCode DUPLICATE_DEFINITION_INHERITANCE = new CompileTimeErrorCode.con1('DUPLICATE_DEFINITION_INHERITANCE', 38, "The name '%s' is already defined in '%s'");
+ static final CompileTimeErrorCode DUPLICATE_DEFINITION_INHERITANCE = new CompileTimeErrorCode.con1('DUPLICATE_DEFINITION_INHERITANCE', 39, "The name '%s' is already defined in '%s'");
/**
* 12.14.2 Binding Actuals to Formals: It is a compile-time error if <i>q<sub>i</sub> =
* q<sub>j</sub></i> for any <i>i != j</i> [where <i>q<sub>i</sub></i> is the label for a named
* argument].
*/
- static final CompileTimeErrorCode DUPLICATE_NAMED_ARGUMENT = new CompileTimeErrorCode.con1('DUPLICATE_NAMED_ARGUMENT', 39, "The argument for the named parameter '%s' was already specified");
+ static final CompileTimeErrorCode DUPLICATE_NAMED_ARGUMENT = new CompileTimeErrorCode.con1('DUPLICATE_NAMED_ARGUMENT', 40, "The argument for the named parameter '%s' was already specified");
/**
* SDK implementation libraries can be exported only by other SDK libraries.
*
* @param uri the uri pointing to a library
*/
- static final CompileTimeErrorCode EXPORT_INTERNAL_LIBRARY = new CompileTimeErrorCode.con1('EXPORT_INTERNAL_LIBRARY', 40, "The library '%s' is internal and cannot be exported");
+ static final CompileTimeErrorCode EXPORT_INTERNAL_LIBRARY = new CompileTimeErrorCode.con1('EXPORT_INTERNAL_LIBRARY', 41, "The library '%s' is internal and cannot be exported");
/**
* 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -872,7 +1003,7 @@
*
* @param uri the uri pointing to a non-library declaration
*/
- static final CompileTimeErrorCode EXPORT_OF_NON_LIBRARY = new CompileTimeErrorCode.con1('EXPORT_OF_NON_LIBRARY', 41, "The exported library '%s' must not have a part-of directive");
+ static final CompileTimeErrorCode EXPORT_OF_NON_LIBRARY = new CompileTimeErrorCode.con1('EXPORT_OF_NON_LIBRARY', 42, "The exported library '%s' must not have a part-of directive");
/**
* 7.9 Superclasses: It is a compile-time error if the extends clause of a class <i>C</i> includes
@@ -880,7 +1011,7 @@
*
* @param typeName the name of the superclass that was not found
*/
- static final CompileTimeErrorCode EXTENDS_NON_CLASS = new CompileTimeErrorCode.con1('EXTENDS_NON_CLASS', 42, "Classes can only extend other classes");
+ static final CompileTimeErrorCode EXTENDS_NON_CLASS = new CompileTimeErrorCode.con1('EXTENDS_NON_CLASS', 43, "Classes can only extend other classes");
/**
* 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
@@ -899,7 +1030,7 @@
* @param typeName the name of the type that cannot be extended
* @see #IMPLEMENTS_DISALLOWED_CLASS
*/
- static final CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('EXTENDS_DISALLOWED_CLASS', 43, "Classes cannot extend '%s'");
+ static final CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('EXTENDS_DISALLOWED_CLASS', 44, "Classes cannot extend '%s'");
/**
* 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i> or if <i>m >
@@ -911,21 +1042,21 @@
* @param requiredCount the maximum number of positional arguments
* @param argumentCount the actual number of positional arguments given
*/
- static final CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS = new CompileTimeErrorCode.con1('EXTRA_POSITIONAL_ARGUMENTS', 44, "%d positional arguments expected, but %d found");
+ static final CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS = new CompileTimeErrorCode.con1('EXTRA_POSITIONAL_ARGUMENTS', 45, "%d positional arguments expected, but %d found");
/**
* 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile time
* error if more than one initializer corresponding to a given instance variable appears in
* <i>k</i>'s list.
*/
- static final CompileTimeErrorCode FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS = new CompileTimeErrorCode.con1('FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS', 45, "The field '%s' cannot be initialized twice in the same constructor");
+ static final CompileTimeErrorCode FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS = new CompileTimeErrorCode.con1('FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS', 46, "The field '%s' cannot be initialized twice in the same constructor");
/**
* 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile time
* error if <i>k</i>'s initializer list contains an initializer for a variable that is initialized
* by means of an initializing formal of <i>k</i>.
*/
- static final CompileTimeErrorCode FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER = new CompileTimeErrorCode.con1('FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER', 46, "Fields cannot be initialized in both the parameter list and the initializers");
+ static final CompileTimeErrorCode FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER = new CompileTimeErrorCode.con1('FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER', 47, "Fields cannot be initialized in both the parameter list and the initializers");
/**
* 5 Variables: It is a compile-time error if a final instance variable that has is initialized by
@@ -934,19 +1065,19 @@
*
* @param name the name of the field in question
*/
- static final CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES = new CompileTimeErrorCode.con1('FINAL_INITIALIZED_MULTIPLE_TIMES', 47, "'%s' is a final field and so can only be set once");
+ static final CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES = new CompileTimeErrorCode.con1('FINAL_INITIALIZED_MULTIPLE_TIMES', 48, "'%s' is a final field and so can only be set once");
/**
* 7.6.1 Generative Constructors: It is a compile-time error if an initializing formal is used by
* a function other than a non-redirecting generative constructor.
*/
- static final CompileTimeErrorCode FIELD_INITIALIZER_FACTORY_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_FACTORY_CONSTRUCTOR', 48, "Initializing formal fields cannot be used in factory constructors");
+ static final CompileTimeErrorCode FIELD_INITIALIZER_FACTORY_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_FACTORY_CONSTRUCTOR', 49, "Initializing formal fields cannot be used in factory constructors");
/**
* 7.6.1 Generative Constructors: It is a compile-time error if an initializing formal is used by
* a function other than a non-redirecting generative constructor.
*/
- static final CompileTimeErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR', 49, "Initializing formal fields can only be used in constructors");
+ static final CompileTimeErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR', 50, "Initializing formal fields can only be used in constructors");
/**
* 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
@@ -955,7 +1086,7 @@
* 7.6.1 Generative Constructors: It is a compile-time error if an initializing formal is used by
* a function other than a non-redirecting generative constructor.
*/
- static final CompileTimeErrorCode FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR', 50, "The redirecting constructor cannot have a field initializer");
+ static final CompileTimeErrorCode FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR', 51, "The redirecting constructor cannot have a field initializer");
/**
* 7.2 Getters: It is a compile-time error if a class has both a getter and a method with the same
@@ -963,7 +1094,7 @@
*
* @param name the conflicting name of the getter and method
*/
- static final CompileTimeErrorCode GETTER_AND_METHOD_WITH_SAME_NAME = new CompileTimeErrorCode.con1('GETTER_AND_METHOD_WITH_SAME_NAME', 51, "'%s' cannot be used to name a getter, there is already a method with the same name");
+ static final CompileTimeErrorCode GETTER_AND_METHOD_WITH_SAME_NAME = new CompileTimeErrorCode.con1('GETTER_AND_METHOD_WITH_SAME_NAME', 52, "'%s' cannot be used to name a getter, there is already a method with the same name");
/**
* 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
@@ -982,13 +1113,13 @@
* @param typeName the name of the type that cannot be implemented
* @see #EXTENDS_DISALLOWED_CLASS
*/
- static final CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_DISALLOWED_CLASS', 52, "Classes cannot implement '%s'");
+ static final CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_DISALLOWED_CLASS', 53, "Classes cannot implement '%s'");
/**
* 7.10 Superinterfaces: It is a compile-time error if the implements clause of a class includes
* type dynamic.
*/
- static final CompileTimeErrorCode IMPLEMENTS_DYNAMIC = new CompileTimeErrorCode.con1('IMPLEMENTS_DYNAMIC', 53, "Classes cannot implement 'dynamic'");
+ static final CompileTimeErrorCode IMPLEMENTS_DYNAMIC = new CompileTimeErrorCode.con1('IMPLEMENTS_DYNAMIC', 54, "Classes cannot implement 'dynamic'");
/**
* 7.10 Superinterfaces: It is a compile-time error if the implements clause of a class <i>C</i>
@@ -997,7 +1128,7 @@
*
* @param typeName the name of the interface that was not found
*/
- static final CompileTimeErrorCode IMPLEMENTS_NON_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_NON_CLASS', 54, "Classes can only implement other classes");
+ static final CompileTimeErrorCode IMPLEMENTS_NON_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_NON_CLASS', 55, "Classes can only implement other classes");
/**
* 7.10 Superinterfaces: It is a compile-time error if a type <i>T</i> appears more than once in
@@ -1005,7 +1136,7 @@
*
* @param className the name of the class that is implemented more than once
*/
- static final CompileTimeErrorCode IMPLEMENTS_REPEATED = new CompileTimeErrorCode.con1('IMPLEMENTS_REPEATED', 55, "'%s' can only be implemented once");
+ static final CompileTimeErrorCode IMPLEMENTS_REPEATED = new CompileTimeErrorCode.con1('IMPLEMENTS_REPEATED', 56, "'%s' can only be implemented once");
/**
* 7.10 Superinterfaces: It is a compile-time error if the superclass of a class <i>C</i> appears
@@ -1013,7 +1144,7 @@
*
* @param className the name of the class that appears in both "extends" and "implements" clauses
*/
- static final CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_SUPER_CLASS', 56, "'%s' cannot be used in both 'extends' and 'implements' clauses");
+ static final CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_SUPER_CLASS', 57, "'%s' cannot be used in both 'extends' and 'implements' clauses");
/**
* 7.6.1 Generative Constructors: Note that <b>this</b> is not in scope on the right hand side of
@@ -1025,14 +1156,14 @@
*
* @param name the name of the type in question
*/
- static final CompileTimeErrorCode IMPLICIT_THIS_REFERENCE_IN_INITIALIZER = new CompileTimeErrorCode.con1('IMPLICIT_THIS_REFERENCE_IN_INITIALIZER', 57, "The 'this' expression cannot be implicitly used in initializers");
+ static final CompileTimeErrorCode IMPLICIT_THIS_REFERENCE_IN_INITIALIZER = new CompileTimeErrorCode.con1('IMPLICIT_THIS_REFERENCE_IN_INITIALIZER', 58, "Only static members can be accessed in initializers");
/**
* SDK implementation libraries can be imported only by other SDK libraries.
*
* @param uri the uri pointing to a library
*/
- static final CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY = new CompileTimeErrorCode.con1('IMPORT_INTERNAL_LIBRARY', 58, "The library '%s' is internal and cannot be imported");
+ static final CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY = new CompileTimeErrorCode.con1('IMPORT_INTERNAL_LIBRARY', 59, "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
@@ -1040,7 +1171,7 @@
*
* @param uri the uri pointing to a non-library declaration
*/
- static final CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = new CompileTimeErrorCode.con1('IMPORT_OF_NON_LIBRARY', 59, "The imported library '%s' must not have a part-of directive");
+ static final CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = new CompileTimeErrorCode.con1('IMPORT_OF_NON_LIBRARY', 60, "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
@@ -1049,7 +1180,7 @@
* @param expressionSource the expression source code that is the unexpected type
* @param expectedType the name of the expected type
*/
- static final CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES = new CompileTimeErrorCode.con1('INCONSISTENT_CASE_EXPRESSION_TYPES', 60, "Case expressions must have the same types, '%s' is not a %s'");
+ static final CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES = new CompileTimeErrorCode.con1('INCONSISTENT_CASE_EXPRESSION_TYPES', 61, "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
@@ -1060,7 +1191,7 @@
* immediately enclosing class
* @see #INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD
*/
- static final CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode.con1('INITIALIZER_FOR_NON_EXISTANT_FIELD', 61, "'%s' is not a variable in the enclosing class");
+ static final CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode.con1('INITIALIZER_FOR_NON_EXISTANT_FIELD', 62, "'%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
@@ -1071,7 +1202,7 @@
* enclosing class
* @see #INITIALIZING_FORMAL_FOR_STATIC_FIELD
*/
- static final CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD = new CompileTimeErrorCode.con1('INITIALIZER_FOR_STATIC_FIELD', 62, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
+ static final CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD = new CompileTimeErrorCode.con1('INITIALIZER_FOR_STATIC_FIELD', 63, "'%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
@@ -1083,7 +1214,7 @@
* @see #INITIALIZING_FORMAL_FOR_STATIC_FIELD
* @see #INITIALIZER_FOR_NON_EXISTANT_FIELD
*/
- static final CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD', 63, "'%s' is not a variable in the enclosing class");
+ static final CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD', 64, "'%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
@@ -1094,20 +1225,20 @@
* enclosing class
* @see #INITIALIZER_FOR_STATIC_FIELD
*/
- static final CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD = new CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_STATIC_FIELD', 64, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
+ static final CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD = new CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_STATIC_FIELD', 65, "'%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 final CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC = new CompileTimeErrorCode.con1('INSTANCE_MEMBER_ACCESS_FROM_STATIC', 65, "Instance member cannot be accessed from static method");
+ static final CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC = new CompileTimeErrorCode.con1('INSTANCE_MEMBER_ACCESS_FROM_STATIC', 66, "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 final CompileTimeErrorCode INVALID_ANNOTATION = new CompileTimeErrorCode.con1('INVALID_ANNOTATION', 66, "Annotation can be only constant variable or constant constructor invocation");
+ static final CompileTimeErrorCode INVALID_ANNOTATION = new CompileTimeErrorCode.con1('INVALID_ANNOTATION', 67, "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
@@ -1115,26 +1246,26 @@
*
* See TODOs in ConstantVisitor
*/
- static final CompileTimeErrorCode INVALID_CONSTANT = new CompileTimeErrorCode.con1('INVALID_CONSTANT', 67, "Invalid constant value");
+ static final CompileTimeErrorCode INVALID_CONSTANT = new CompileTimeErrorCode.con1('INVALID_CONSTANT', 68, "Invalid constant value");
/**
* 7.6 Constructors: It is a compile-time error if the name of a constructor is not a constructor
* name.
*/
- static final CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = new CompileTimeErrorCode.con1('INVALID_CONSTRUCTOR_NAME', 68, "Invalid constructor name");
+ static final CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = new CompileTimeErrorCode.con1('INVALID_CONSTRUCTOR_NAME', 69, "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 final CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = new CompileTimeErrorCode.con1('INVALID_FACTORY_NAME_NOT_A_CLASS', 69, "The name of the immediately enclosing class expected");
+ static final CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = new CompileTimeErrorCode.con1('INVALID_FACTORY_NAME_NOT_A_CLASS', 70, "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 final CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = new CompileTimeErrorCode.con1('INVALID_REFERENCE_TO_THIS', 70, "Invalid reference to 'this' expression");
+ static final CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = new CompileTimeErrorCode.con1('INVALID_REFERENCE_TO_THIS', 71, "Invalid reference to 'this' expression");
/**
* 12.6 Lists: It is a compile time error if the type argument of a constant list literal includes
@@ -1142,7 +1273,7 @@
*
* @name the name of the type parameter
*/
- static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = new CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 71, "Constant list literals cannot include a type parameter as a type argument, such as '%s'");
+ static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = new CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 72, "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
@@ -1150,7 +1281,7 @@
*
* @name the name of the type parameter
*/
- static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = new CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 72, "Constant map literals cannot include a type parameter as a type argument, such as '%s'");
+ static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = new CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 73, "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
@@ -1165,7 +1296,7 @@
* @param uri the URI that is invalid
* @see #URI_DOES_NOT_EXIST
*/
- static final CompileTimeErrorCode INVALID_URI = new CompileTimeErrorCode.con1('INVALID_URI', 73, "Invalid URI syntax: '%s'");
+ static final CompileTimeErrorCode INVALID_URI = new CompileTimeErrorCode.con1('INVALID_URI', 74, "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
@@ -1176,7 +1307,7 @@
*
* @param labelName the name of the unresolvable label
*/
- static final CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = new CompileTimeErrorCode.con1('LABEL_IN_OUTER_SCOPE', 74, "Cannot reference label '%s' declared in an outer method");
+ static final CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = new CompileTimeErrorCode.con1('LABEL_IN_OUTER_SCOPE', 75, "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
@@ -1187,7 +1318,7 @@
*
* @param labelName the name of the unresolvable label
*/
- static final CompileTimeErrorCode LABEL_UNDEFINED = new CompileTimeErrorCode.con1('LABEL_UNDEFINED', 75, "Cannot reference undefined label '%s'");
+ static final CompileTimeErrorCode LABEL_UNDEFINED = new CompileTimeErrorCode.con1('LABEL_UNDEFINED', 76, "Cannot reference undefined label '%s'");
/**
* 12.6 Lists: A run-time list literal <<i>E</i>> [<i>e<sub>1</sub></i> ...
@@ -1203,7 +1334,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 final CompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 76, "The element type '%s' cannot be assigned to the list type '%s'");
+ static final CompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 77, "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> :
@@ -1219,7 +1350,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 final CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 77, "The element type '%s' cannot be assigned to the map key type '%s'");
+ static final CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 78, "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> :
@@ -1235,13 +1366,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 final CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 78, "The element type '%s' cannot be assigned to the map value type '%s'");
+ static final CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 79, "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 final CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = new CompileTimeErrorCode.con1('MEMBER_WITH_CLASS_NAME', 79, "Class members cannot have the same name as the enclosing class");
+ static final CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = new CompileTimeErrorCode.con1('MEMBER_WITH_CLASS_NAME', 80, "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
@@ -1249,17 +1380,17 @@
*
* @param name the conflicting name of the getter and method
*/
- static final CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME = new CompileTimeErrorCode.con1('METHOD_AND_GETTER_WITH_SAME_NAME', 80, "'%s' cannot be used to name a method, there is already a getter with the same name");
+ static final CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME = new CompileTimeErrorCode.con1('METHOD_AND_GETTER_WITH_SAME_NAME', 81, "'%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 final CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL = new CompileTimeErrorCode.con1('MISSING_CONST_IN_LIST_LITERAL', 81, "List literals must be prefixed with 'const' when used as a constant expression");
+ static final CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL = new CompileTimeErrorCode.con1('MISSING_CONST_IN_LIST_LITERAL', 82, "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 final CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL = new CompileTimeErrorCode.con1('MISSING_CONST_IN_MAP_LITERAL', 82, "Map literals must be prefixed with 'const' when used as a constant expression");
+ static final CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL = new CompileTimeErrorCode.con1('MISSING_CONST_IN_MAP_LITERAL', 83, "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
@@ -1267,7 +1398,7 @@
*
* @param typeName the name of the mixin that is invalid
*/
- static final CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = new CompileTimeErrorCode.con1('MIXIN_DECLARES_CONSTRUCTOR', 83, "The class '%s' cannot be used as a mixin because it declares a constructor");
+ static final CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = new CompileTimeErrorCode.con1('MIXIN_DECLARES_CONSTRUCTOR', 84, "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
@@ -1275,7 +1406,7 @@
*
* @param typeName the name of the mixin that is invalid
*/
- static final CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = new CompileTimeErrorCode.con1('MIXIN_INHERITS_FROM_NOT_OBJECT', 84, "The class '%s' cannot be used as a mixin because it extends a class other than Object");
+ static final CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = new CompileTimeErrorCode.con1('MIXIN_INHERITS_FROM_NOT_OBJECT', 85, "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.
@@ -1294,43 +1425,43 @@
* @param typeName the name of the type that cannot be extended
* @see #IMPLEMENTS_DISALLOWED_CLASS
*/
- static final CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('MIXIN_OF_DISALLOWED_CLASS', 85, "Classes cannot mixin '%s'");
+ static final CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('MIXIN_OF_DISALLOWED_CLASS', 86, "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 final CompileTimeErrorCode MIXIN_OF_NON_CLASS = new CompileTimeErrorCode.con1('MIXIN_OF_NON_CLASS', 86, "Classes can only mixin other classes");
+ static final CompileTimeErrorCode MIXIN_OF_NON_CLASS = new CompileTimeErrorCode.con1('MIXIN_OF_NON_CLASS', 87, "Classes can only mixin other classes");
/**
* 9 Mixins: It is a compile-time error if a declared or derived mixin refers to super.
*/
- static final CompileTimeErrorCode MIXIN_REFERENCES_SUPER = new CompileTimeErrorCode.con1('MIXIN_REFERENCES_SUPER', 87, "The class '%s' cannot be used as a mixin because it references 'super'");
+ static final CompileTimeErrorCode MIXIN_REFERENCES_SUPER = new CompileTimeErrorCode.con1('MIXIN_REFERENCES_SUPER', 88, "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 final CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = new CompileTimeErrorCode.con1('MIXIN_WITH_NON_CLASS_SUPERCLASS', 88, "Mixin can only be applied to class");
+ static final CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = new CompileTimeErrorCode.con1('MIXIN_WITH_NON_CLASS_SUPERCLASS', 89, "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 final CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = new CompileTimeErrorCode.con1('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS', 89, "Constructor may have at most one 'this' redirection");
+ static final CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = new CompileTimeErrorCode.con1('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS', 90, "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 final CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = new CompileTimeErrorCode.con1('MULTIPLE_SUPER_INITIALIZERS', 90, "Constructor may have at most one 'super' initializer");
+ static final CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = new CompileTimeErrorCode.con1('MULTIPLE_SUPER_INITIALIZERS', 91, "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 final CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS = new CompileTimeErrorCode.con1('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS', 91, "Annotation creation must have arguments");
+ static final CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS = new CompileTimeErrorCode.con1('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS', 92, "Annotation creation must have arguments");
/**
* 7.6.1 Generative Constructors: If no superinitializer is provided, an implicit superinitializer
@@ -1340,7 +1471,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 final CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = new CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 92, "The class '%s' does not have a default constructor");
+ static final CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = new CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 93, "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
@@ -1349,13 +1480,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 final CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = new CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 93, "The class '%s' does not have a default constructor");
+ static final CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = new CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 94, "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 final CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = new CompileTimeErrorCode.con1('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 94, "A non-constant map literal without type arguments cannot be used as an expression statement");
+ static final CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = new CompileTimeErrorCode.con1('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 95, "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> …
@@ -1366,44 +1497,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 final CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = new CompileTimeErrorCode.con1('NON_CONSTANT_CASE_EXPRESSION', 95, "Case expressions must be constant");
+ static final CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = new CompileTimeErrorCode.con1('NON_CONSTANT_CASE_EXPRESSION', 96, "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 final CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = new CompileTimeErrorCode.con1('NON_CONSTANT_DEFAULT_VALUE', 96, "Default values of an optional parameter must be constant");
+ static final CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = new CompileTimeErrorCode.con1('NON_CONSTANT_DEFAULT_VALUE', 97, "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 final CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = new CompileTimeErrorCode.con1('NON_CONSTANT_LIST_ELEMENT', 97, "'const' lists must have all constant values");
+ static final CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = new CompileTimeErrorCode.con1('NON_CONSTANT_LIST_ELEMENT', 98, "'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 final CompileTimeErrorCode NON_CONSTANT_MAP_KEY = new CompileTimeErrorCode.con1('NON_CONSTANT_MAP_KEY', 98, "The keys in a map must be constant");
+ static final CompileTimeErrorCode NON_CONSTANT_MAP_KEY = new CompileTimeErrorCode.con1('NON_CONSTANT_MAP_KEY', 99, "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 final CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = new CompileTimeErrorCode.con1('NON_CONSTANT_MAP_VALUE', 99, "The values in a 'const' map must be constant");
+ static final CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = new CompileTimeErrorCode.con1('NON_CONSTANT_MAP_VALUE', 100, "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 final CompileTimeErrorCode NON_CONSTANT_ANNOTATION_CONSTRUCTOR = new CompileTimeErrorCode.con1('NON_CONSTANT_ANNOTATION_CONSTRUCTOR', 100, "Annotation creation can use only 'const' constructor");
+ static final CompileTimeErrorCode NON_CONSTANT_ANNOTATION_CONSTRUCTOR = new CompileTimeErrorCode.con1('NON_CONSTANT_ANNOTATION_CONSTRUCTOR', 101, "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 final CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = new CompileTimeErrorCode.con1('NON_CONSTANT_VALUE_IN_INITIALIZER', 101, "Initializer expressions in constant constructors must be constants");
+ static final CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = new CompileTimeErrorCode.con1('NON_CONSTANT_VALUE_IN_INITIALIZER', 102, "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>.
@@ -1414,7 +1545,7 @@
* @param requiredCount the expected number of required arguments
* @param argumentCount the actual number of positional arguments given
*/
- static final CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS = new CompileTimeErrorCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 102, "%d required argument(s) expected, but %d found");
+ static final CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS = new CompileTimeErrorCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 103, "%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
@@ -1422,17 +1553,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 final CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode.con1('NON_GENERATIVE_CONSTRUCTOR', 103, "The generative constructor '%s' expected, but factory found");
+ static final CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode.con1('NON_GENERATIVE_CONSTRUCTOR', 104, "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 final CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = new CompileTimeErrorCode.con1('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 104, "");
+ static final CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = new CompileTimeErrorCode.con1('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 105, "");
/**
* 7.1.1 Operators: It is a compile-time error to declare an optional parameter in an operator.
*/
- static final CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = new CompileTimeErrorCode.con1('OPTIONAL_PARAMETER_IN_OPERATOR', 105, "Optional parameters are not allowed when defining an operator");
+ static final CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = new CompileTimeErrorCode.con1('OPTIONAL_PARAMETER_IN_OPERATOR', 106, "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
@@ -1440,25 +1571,25 @@
*
* @param uri the uri pointing to a non-library declaration
*/
- static final CompileTimeErrorCode PART_OF_NON_PART = new CompileTimeErrorCode.con1('PART_OF_NON_PART', 106, "The included part '%s' must have a part-of directive");
+ static final CompileTimeErrorCode PART_OF_NON_PART = new CompileTimeErrorCode.con1('PART_OF_NON_PART', 107, "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 final CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = new CompileTimeErrorCode.con1('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 107, "The name '%s' is already used as an import prefix and cannot be used to name a top-level element");
+ static final CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = new CompileTimeErrorCode.con1('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 108, "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 final CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = new CompileTimeErrorCode.con1('PRIVATE_OPTIONAL_PARAMETER', 108, "Named optional parameters cannot start with an underscore");
+ static final CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = new CompileTimeErrorCode.con1('PRIVATE_OPTIONAL_PARAMETER', 109, "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 final CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = new CompileTimeErrorCode.con1('RECURSIVE_COMPILE_TIME_CONSTANT', 109, "");
+ static final CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = new CompileTimeErrorCode.con1('RECURSIVE_COMPILE_TIME_CONSTANT', 110, "");
/**
* 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
@@ -1469,13 +1600,13 @@
*
* https://code.google.com/p/dart/issues/detail?id=954
*/
- static final CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = new CompileTimeErrorCode.con1('RECURSIVE_CONSTRUCTOR_REDIRECT', 110, "Cycle in redirecting generative constructors");
+ static final CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = new CompileTimeErrorCode.con1('RECURSIVE_CONSTRUCTOR_REDIRECT', 111, "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 final CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = new CompileTimeErrorCode.con1('RECURSIVE_FACTORY_REDIRECT', 111, "Cycle in redirecting factory constructors");
+ static final CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = new CompileTimeErrorCode.con1('RECURSIVE_FACTORY_REDIRECT', 112, "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
@@ -1488,7 +1619,7 @@
* @param className the name of the class that implements itself recursively
* @param strImplementsPath a string representation of the implements loop
*/
- static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE', 112, "'%s' cannot be a superinterface of itself: %s");
+ static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE', 113, "'%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
@@ -1500,7 +1631,7 @@
*
* @param className the name of the class that implements itself recursively
*/
- static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS', 113, "'%s' cannot extend itself");
+ static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS', 114, "'%s' cannot extend itself");
/**
* 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1512,31 +1643,31 @@
*
* @param className the name of the class that implements itself recursively
*/
- static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS', 114, "'%s' cannot implement itself");
+ static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS', 115, "'%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 final CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = new CompileTimeErrorCode.con1('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 115, "Constant factory constructor cannot delegate to a non-constant constructor");
+ static final CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = new CompileTimeErrorCode.con1('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 116, "Constant factory constructor cannot delegate to a non-constant constructor");
/**
* 13.3 Local Variable Declaration: It is a compile-time error if <i>e</i> refers to the name
* <i>v</i> or the name <i>v=</i>.
*/
- static final CompileTimeErrorCode REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER = new CompileTimeErrorCode.con1('REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER', 116, "The name '%s' cannot be referenced in the initializer of a variable with the same name");
+ static final CompileTimeErrorCode REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER = new CompileTimeErrorCode.con1('REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER', 117, "The name '%s' cannot be referenced in the initializer of a variable with the same name");
/**
* 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 final CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = new CompileTimeErrorCode.con1('RETHROW_OUTSIDE_CATCH', 117, "rethrow must be inside of a catch clause");
+ static final CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = new CompileTimeErrorCode.con1('RETHROW_OUTSIDE_CATCH', 118, "rethrow must be inside of a catch clause");
/**
* 13.11 Return: It is a compile-time error if a return statement of the form <i>return e;</i>
* appears in a generative constructor.
*/
- static final CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode.con1('RETURN_IN_GENERATIVE_CONSTRUCTOR', 118, "Constructors cannot return a value");
+ static final CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode.con1('RETURN_IN_GENERATIVE_CONSTRUCTOR', 119, "Constructors cannot return a value");
/**
* 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -1546,19 +1677,19 @@
* initializer list, in class Object, in a factory constructor, or in a static method or variable
* initializer.
*/
- static final CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = new CompileTimeErrorCode.con1('SUPER_IN_INVALID_CONTEXT', 119, "Invalid context for 'super' invocation");
+ static final CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = new CompileTimeErrorCode.con1('SUPER_IN_INVALID_CONTEXT', 120, "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 final CompileTimeErrorCode SUPER_IN_REDIRECTING_CONSTRUCTOR = new CompileTimeErrorCode.con1('SUPER_IN_REDIRECTING_CONSTRUCTOR', 120, "The redirecting constructor cannot have a 'super' initializer");
+ static final CompileTimeErrorCode SUPER_IN_REDIRECTING_CONSTRUCTOR = new CompileTimeErrorCode.con1('SUPER_IN_REDIRECTING_CONSTRUCTOR', 121, "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 final CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = new CompileTimeErrorCode.con1('SUPER_INITIALIZER_IN_OBJECT', 121, "");
+ static final CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = new CompileTimeErrorCode.con1('SUPER_INITIALIZER_IN_OBJECT', 122, "");
/**
* 12.11 Instance Creation: It is a static type warning if any of the type arguments to a
@@ -1577,19 +1708,19 @@
* @param boundingTypeName the name of the bounding type
* @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
*/
- static final CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = new CompileTimeErrorCode.con1('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 122, "'%s' does not extend '%s'");
+ static final CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = new CompileTimeErrorCode.con1('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 123, "'%s' does not extend '%s'");
/**
* 15.3.1 Typedef: It is a compile-time error if a typedef refers to itself via a chain of
* references that does not include a class declaration.
*/
- static final CompileTimeErrorCode TYPE_ALIAS_CANNOT_REFERENCE_ITSELF = new CompileTimeErrorCode.con1('TYPE_ALIAS_CANNOT_REFERENCE_ITSELF', 123, "Type alias can reference itself only via the bounds of its generic parameters");
+ static final CompileTimeErrorCode TYPE_ALIAS_CANNOT_REFERENCE_ITSELF = new CompileTimeErrorCode.con1('TYPE_ALIAS_CANNOT_REFERENCE_ITSELF', 124, "Type alias can reference itself only via the bounds of its generic parameters");
/**
* 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 final CompileTimeErrorCode UNDEFINED_CLASS = new CompileTimeErrorCode.con1('UNDEFINED_CLASS', 124, "Undefined class '%s'");
+ static final CompileTimeErrorCode UNDEFINED_CLASS = new CompileTimeErrorCode.con1('UNDEFINED_CLASS', 125, "Undefined class '%s'");
/**
* 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -1597,7 +1728,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 final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = new CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 125, "The class '%s' does not have a generative constructor '%s'");
+ static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = new CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 126, "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
@@ -1605,7 +1736,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 final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = new CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 126, "The class '%s' does not have a default generative constructor");
+ static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = new CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 127, "The class '%s' does not have a default generative constructor");
/**
* 12.14.3 Unqualified Invocation: If there exists a lexically visible declaration named
@@ -1615,7 +1746,7 @@
*
* @param methodName the name of the method that is undefined
*/
- static final CompileTimeErrorCode UNDEFINED_FUNCTION = new CompileTimeErrorCode.con1('UNDEFINED_FUNCTION', 127, "The function '%s' is not defined");
+ static final CompileTimeErrorCode UNDEFINED_FUNCTION = new CompileTimeErrorCode.con1('UNDEFINED_FUNCTION', 128, "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>,
@@ -1627,7 +1758,7 @@
*
* @param name the name of the requested named parameter
*/
- static final CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = new CompileTimeErrorCode.con1('UNDEFINED_NAMED_PARAMETER', 128, "The named parameter '%s' is not defined");
+ static final CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = new CompileTimeErrorCode.con1('UNDEFINED_NAMED_PARAMETER', 129, "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
@@ -1642,7 +1773,7 @@
* @param uri the URI pointing to a non-existent file
* @see #INVALID_URI
*/
- static final CompileTimeErrorCode URI_DOES_NOT_EXIST = new CompileTimeErrorCode.con1('URI_DOES_NOT_EXIST', 129, "Target of URI does not exist: '%s'");
+ static final CompileTimeErrorCode URI_DOES_NOT_EXIST = new CompileTimeErrorCode.con1('URI_DOES_NOT_EXIST', 130, "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
@@ -1654,7 +1785,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 final CompileTimeErrorCode URI_WITH_INTERPOLATION = new CompileTimeErrorCode.con1('URI_WITH_INTERPOLATION', 130, "URIs cannot use string interpolation");
+ static final CompileTimeErrorCode URI_WITH_INTERPOLATION = new CompileTimeErrorCode.con1('URI_WITH_INTERPOLATION', 131, "URIs cannot use string interpolation");
/**
* 7.1.1 Operators: It is a compile-time error if the arity of the user-declared operator []= is
@@ -1667,7 +1798,7 @@
* @param expectedNumberOfParameters the number of parameters expected
* @param actualNumberOfParameters the number of parameters found in the operator declaration
*/
- static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 131, "Operator '%s' should declare exactly %d parameter(s), but %d found");
+ static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 132, "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
@@ -1675,13 +1806,13 @@
*
* @param actualNumberOfParameters the number of parameters found in the operator declaration
*/
- static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 132, "Operator '-' should declare 0 or 1 parameter, but %d found");
+ static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 133, "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 final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 133, "Setters should declare exactly one required parameter");
+ static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 134, "Setters should declare exactly one required parameter");
static final List<CompileTimeErrorCode> values = [
AMBIGUOUS_EXPORT,
ARGUMENT_DEFINITION_TEST_NON_PARAMETER,
@@ -1689,7 +1820,7 @@
BUILT_IN_IDENTIFIER_AS_TYPE,
BUILT_IN_IDENTIFIER_AS_TYPE_NAME,
BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME,
- BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME,
+ BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME,
CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
COMPILE_TIME_CONSTANT_RAISES_EXCEPTION,
CONFLICTING_GETTER_AND_METHOD,
@@ -1703,6 +1834,7 @@
CONST_FORMAL_PARAMETER,
CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
CONST_INSTANCE_FIELD,
+ CONST_NOT_INITIALIZED,
CONST_EVAL_TYPE_BOOL,
CONST_EVAL_TYPE_BOOL_NUM_STRING,
CONST_EVAL_TYPE_INT,
@@ -2294,13 +2426,13 @@
/**
* 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
- * instance member <i>m2</i> and <i>m1</i> has a different number of required parameters than
+ * instance member <i>m2</i> and <i>m1</i> has a greater number of required parameters than
* <i>m2</i>.
*
* @param paramCount the number of required parameters in the overridden member
* @param className the name of the class from the overridden method
*/
- static final StaticWarningCode INVALID_OVERRIDE_REQUIRED = new StaticWarningCode.con1('INVALID_OVERRIDE_REQUIRED', 38, "Must have exactly %d required parameters to match the overridden method from '%s'");
+ static final StaticWarningCode INVALID_OVERRIDE_REQUIRED = new StaticWarningCode.con1('INVALID_OVERRIDE_REQUIRED', 38, "Must have %d required parameters or less to match the overridden method from '%s'");
/**
* 7.3 Setters: It is a static warning if a setter <i>m1</i> overrides a setter <i>m2</i> and the
@@ -2530,7 +2662,7 @@
/**
* 15.1 Static Types: A type <i>T</i> is malformed iff: * <i>T</i> has the form <i>id</i> or the
* form <i>prefix.id</i>, and in the enclosing lexical scope, the name <i>id</i> (respectively
- * <i>prefix.id</i>) does not denote a type. * <i>T</i> denotes a type variable in the
+ * <i>prefix.id</i>) does not denote a type. * <i>T</i> denotes a type parameter in the
* enclosing lexical scope, but occurs in the signature or body of a static member. *
* <i>T</i> is a parameterized type of the form <i>G<S<sub>1</sub>, .., S<sub>n</sub>></i>,
* and <i>G</i> is malformed.
@@ -2820,7 +2952,7 @@
/**
* An error listener that ignores errors that are reported to it.
*/
- static final AnalysisErrorListener _NULL_LISTENER = new AnalysisErrorListener_5();
+ static final AnalysisErrorListener _NULL_LISTENER = new AnalysisErrorListener_6();
/**
* This method is invoked when an error has been found by the analysis engine.
@@ -2829,7 +2961,7 @@
*/
void onError(AnalysisError error);
}
-class AnalysisErrorListener_5 implements AnalysisErrorListener {
+class AnalysisErrorListener_6 implements AnalysisErrorListener {
void onError(AnalysisError event) {
}
}
diff --git a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
index d297da4..8af2198 100644
--- a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
@@ -38,13 +38,13 @@
/**
* A builder that will silently ignore all data and logging requests.
*/
- static final InstrumentationBuilder nullBuilder = new InstrumentationBuilder_16();
+ static final InstrumentationBuilder nullBuilder = new InstrumentationBuilder_15();
/**
* An instrumentation logger that can be used when no other instrumentation logger has been
* configured. This logger will silently ignore all data and logging requests.
*/
- static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_17();
+ static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_16();
/**
* The current instrumentation logger.
@@ -89,7 +89,7 @@
_CURRENT_LOGGER = logger2 == null ? _NULL_LOGGER : logger2;
}
}
-class InstrumentationBuilder_16 implements InstrumentationBuilder {
+class InstrumentationBuilder_15 implements InstrumentationBuilder {
InstrumentationBuilder data(String name, bool value) => this;
InstrumentationBuilder data2(String name, int value) => this;
InstrumentationBuilder data3(String name, String value) => this;
@@ -105,7 +105,7 @@
InstrumentationBuilder metric4(String name, List<String> value) => this;
InstrumentationBuilder record(Exception exception) => this;
}
-class InstrumentationLogger_17 implements InstrumentationLogger {
+class InstrumentationLogger_16 implements InstrumentationLogger {
InstrumentationBuilder createBuilder(String name) => Instrumentation.nullBuilder;
}
/**
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_core.dart b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
index 769fdf1..be03c50 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
@@ -502,6 +502,10 @@
return false;
}
+bool javaCollectionContainsAll(Iterable list, Iterable c) {
+ return c.fold(true, (bool prev, e) => prev && list.contains(e));
+}
+
javaMapPut(Map target, key, value) {
var oldValue = target[key];
target[key] = value;
@@ -562,3 +566,21 @@
String toString() => name;
int compareTo(E other) => ordinal - other.ordinal;
}
+
+class JavaPatternMatcher {
+ Iterator<Match> _matches;
+ Match _match;
+ JavaPatternMatcher(RegExp re, String input) {
+ _matches = re.allMatches(input).iterator;
+ }
+ bool find() {
+ if (!_matches.moveNext()) {
+ return false;
+ }
+ _match = _matches.current;
+ return true;
+ }
+ String group(int i) => _match[i];
+ int start() => _match.start;
+ int end() => _match.end;
+}
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/generated/parser.dart b/pkg/analyzer_experimental/lib/src/generated/parser.dart
index 4ab24aa..2264972 100644
--- a/pkg/analyzer_experimental/lib/src/generated/parser.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/parser.dart
@@ -201,7 +201,9 @@
InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.Parser.parseCompilationUnit");
try {
_currentToken = token;
- return parseCompilationUnit2();
+ CompilationUnit compilationUnit = parseCompilationUnit2();
+ gatherTodoComments(token);
+ return compilationUnit;
} finally {
instrumentation.log();
}
@@ -397,7 +399,7 @@
*
* @return the synthetic token that was created
*/
- Token createSyntheticToken(Keyword keyword) => new KeywordToken_14(keyword, _currentToken.offset);
+ Token createSyntheticToken(Keyword keyword) => new KeywordToken_13(keyword, _currentToken.offset);
/**
* Create a synthetic token with the given type.
@@ -480,6 +482,18 @@
}
return null;
}
+ void gatherTodoComments(Token token) {
+ while (token != null && token.type != TokenType.EOF) {
+ Token commentToken = token.precedingComments;
+ while (commentToken != null) {
+ if (identical(commentToken.type, TokenType.SINGLE_LINE_COMMENT) || identical(commentToken.type, TokenType.MULTI_LINE_COMMENT)) {
+ scrapeTodoComment(commentToken);
+ }
+ commentToken = commentToken.next;
+ }
+ token = token.next;
+ }
+ }
/**
* Advance to the next token in the token stream, making it the new current token.
@@ -586,7 +600,17 @@
if (afterIdentifier == null) {
return false;
}
- return isFunctionExpression(afterIdentifier);
+ if (isFunctionExpression(afterIdentifier)) {
+ return true;
+ }
+ if (matches(Keyword.GET)) {
+ Token afterName = skipSimpleIdentifier(_currentToken.next);
+ if (afterName == null) {
+ return false;
+ }
+ return matches4(afterName, TokenType.FUNCTION) || matches4(afterName, TokenType.OPEN_CURLY_BRACKET);
+ }
+ return false;
}
/**
@@ -1641,7 +1665,7 @@
}
/**
- * Parse the documentation comment and metadata preceeding a declaration. This method allows any
+ * Parse the documentation comment and metadata preceding a declaration. This method allows any
* number of documentation comments to occur before, after or between the metadata, but only
* returns the last (right-most) documentation comment that is found.
*
@@ -1684,7 +1708,7 @@
}
try {
List<bool> errorFound = [false];
- AnalysisErrorListener listener = new AnalysisErrorListener_15(errorFound);
+ AnalysisErrorListener listener = new AnalysisErrorListener_14(errorFound);
StringScanner scanner = new StringScanner(null, referenceSource, listener);
scanner.setSourceStart(1, 1, sourceOffset);
Token firstToken = scanner.tokenize();
@@ -1833,8 +1857,8 @@
if (partOfDirectiveFound) {
reportError8(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, []);
} else {
- for (Directive preceedingDirective in directives) {
- reportError9(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, preceedingDirective.keyword, []);
+ for (Directive precedingDirective in directives) {
+ reportError9(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, precedingDirective.keyword, []);
}
partOfDirectiveFound = true;
}
@@ -2652,6 +2676,7 @@
}
if (matches(Keyword.IN)) {
DeclaredIdentifier loopVariable = null;
+ SimpleIdentifier identifier = null;
if (variableList == null) {
reportError8(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, []);
} else {
@@ -2663,13 +2688,24 @@
if (variable.initializer != null) {
reportError8(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []);
}
- loopVariable = new DeclaredIdentifier.full(commentAndMetadata.comment, commentAndMetadata.metadata, variableList.keyword, variableList.type, variable.name);
+ Token keyword = variableList.keyword;
+ TypeName type = variableList.type;
+ if (keyword != null || type != null) {
+ loopVariable = new DeclaredIdentifier.full(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, type, variable.name);
+ } else {
+ if (!commentAndMetadata.metadata.isEmpty) {
+ }
+ identifier = variable.name;
+ }
}
Token inKeyword = expect(Keyword.IN);
Expression iterator = parseExpression2();
Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
Statement body = parseStatement2();
- return new ForEachStatement.full(forKeyword, leftParenthesis, loopVariable, inKeyword, iterator, rightParenthesis, body);
+ if (loopVariable == null) {
+ return new ForEachStatement.con2_full(forKeyword, leftParenthesis, identifier, inKeyword, iterator, rightParenthesis, body);
+ }
+ return new ForEachStatement.con1_full(forKeyword, leftParenthesis, loopVariable, inKeyword, iterator, rightParenthesis, body);
}
}
Token leftSeparator = expect2(TokenType.SEMICOLON);
@@ -2823,7 +2859,18 @@
* @param returnType the return type, or `null` if there is no return type
* @return the function declaration statement that was parsed
*/
- Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMetadata, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctionDeclaration(commentAndMetadata, null, returnType));
+ Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMetadata, TypeName returnType) {
+ FunctionDeclaration declaration = parseFunctionDeclaration(commentAndMetadata, null, returnType);
+ Token propertyKeyword = declaration.propertyKeyword;
+ if (propertyKeyword != null) {
+ if (identical(((propertyKeyword as KeywordToken)).keyword, Keyword.GET)) {
+ reportError9(ParserErrorCode.GETTER_IN_FUNCTION, propertyKeyword, []);
+ } else {
+ reportError9(ParserErrorCode.SETTER_IN_FUNCTION, propertyKeyword, []);
+ }
+ }
+ return new FunctionDeclarationStatement.full(declaration);
+ }
/**
* Parse a function expression.
@@ -4805,6 +4852,21 @@
}
/**
+ * Look for user defined tasks in comments and convert them into info level analysis issues.
+ *
+ * @param commentToken the comment token to analyze
+ */
+ void scrapeTodoComment(Token commentToken) {
+ JavaPatternMatcher matcher = new JavaPatternMatcher(TodoCode.TODO_REGEX, commentToken.lexeme);
+ if (matcher.find()) {
+ int offset = commentToken.offset + matcher.start() + matcher.group(1).length;
+ int length = matcher.group(2).length;
+ // TODO(scheglov) analyzer_experimental users don't expect it
+// _errorListener.onError(new AnalysisError.con2(_source, offset, length, TodoCode.TODO, [matcher.group(2)]));
+ }
+ }
+
+ /**
* Parse the 'final', 'const', 'var' or type preceding a variable declaration, starting at the
* given token, without actually creating a type or changing the current token. Return the token
* following the type that was parsed, or `null` if the given token is not the first token
@@ -5580,13 +5642,13 @@
}
}
}
-class KeywordToken_14 extends KeywordToken {
- KeywordToken_14(Keyword arg0, int arg1) : super(arg0, arg1);
+class KeywordToken_13 extends KeywordToken {
+ KeywordToken_13(Keyword arg0, int arg1) : super(arg0, arg1);
int get length => 0;
}
-class AnalysisErrorListener_15 implements AnalysisErrorListener {
+class AnalysisErrorListener_14 implements AnalysisErrorListener {
List<bool> errorFound;
- AnalysisErrorListener_15(this.errorFound);
+ AnalysisErrorListener_14(this.errorFound);
void onError(AnalysisError error) {
errorFound[0] = true;
}
@@ -5651,82 +5713,84 @@
static final ParserErrorCode FINAL_METHOD = new ParserErrorCode.con3('FINAL_METHOD', 48, "Getters, setters and methods cannot be declared to be 'final'");
static final ParserErrorCode FINAL_TYPEDEF = new ParserErrorCode.con3('FINAL_TYPEDEF', 49, "Type aliases cannot be declared to be 'final'");
static final ParserErrorCode FUNCTION_TYPED_PARAMETER_VAR = new ParserErrorCode.con3('FUNCTION_TYPED_PARAMETER_VAR', 50, "Function typed parameters cannot specify 'const', 'final' or 'var' instead of return type");
- static final ParserErrorCode GETTER_WITH_PARAMETERS = new ParserErrorCode.con3('GETTER_WITH_PARAMETERS', 51, "Getter should be declared without a parameter list");
- static final ParserErrorCode ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE = new ParserErrorCode.con3('ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE', 52, "Illegal assignment to non-assignable expression");
- static final ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS = new ParserErrorCode.con3('IMPLEMENTS_BEFORE_EXTENDS', 53, "The extends clause must be before the implements clause");
- static final ParserErrorCode IMPLEMENTS_BEFORE_WITH = new ParserErrorCode.con3('IMPLEMENTS_BEFORE_WITH', 54, "The with clause must be before the implements clause");
- static final ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new ParserErrorCode.con3('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 55, "Import directives must preceed part directives");
- static final ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con3('INITIALIZED_VARIABLE_IN_FOR_EACH', 56, "The loop variable in a for-each loop cannot be initialized");
- static final ParserErrorCode INVALID_CODE_POINT = new ParserErrorCode.con3('INVALID_CODE_POINT', 57, "The escape sequence '%s' is not a valid code point");
- static final ParserErrorCode INVALID_COMMENT_REFERENCE = new ParserErrorCode.con3('INVALID_COMMENT_REFERENCE', 58, "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
- static final ParserErrorCode INVALID_HEX_ESCAPE = new ParserErrorCode.con3('INVALID_HEX_ESCAPE', 59, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
- static final ParserErrorCode INVALID_OPERATOR = new ParserErrorCode.con3('INVALID_OPERATOR', 60, "The string '%s' is not a valid operator");
- static final ParserErrorCode INVALID_OPERATOR_FOR_SUPER = new ParserErrorCode.con3('INVALID_OPERATOR_FOR_SUPER', 61, "The operator '%s' cannot be used with 'super'");
- static final ParserErrorCode INVALID_UNICODE_ESCAPE = new ParserErrorCode.con3('INVALID_UNICODE_ESCAPE', 62, "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
- static final ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = new ParserErrorCode.con3('LIBRARY_DIRECTIVE_NOT_FIRST', 63, "The library directive must appear before all other directives");
- static final ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER = new ParserErrorCode.con3('LOCAL_FUNCTION_DECLARATION_MODIFIER', 64, "Local function declarations cannot specify any modifier");
- static final ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = new ParserErrorCode.con3('MISSING_ASSIGNABLE_SELECTOR', 65, "Missing selector such as \".<identifier>\" or \"[0]\"");
- static final ParserErrorCode MISSING_CATCH_OR_FINALLY = new ParserErrorCode.con3('MISSING_CATCH_OR_FINALLY', 66, "A try statement must have either a catch or finally clause");
- static final ParserErrorCode MISSING_CLASS_BODY = new ParserErrorCode.con3('MISSING_CLASS_BODY', 67, "A class definition must have a body, even if it is empty");
- static final ParserErrorCode MISSING_CLOSING_PARENTHESIS = new ParserErrorCode.con3('MISSING_CLOSING_PARENTHESIS', 68, "The closing parenthesis is missing");
- static final ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = new ParserErrorCode.con3('MISSING_CONST_FINAL_VAR_OR_TYPE', 69, "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
- static final ParserErrorCode MISSING_EXPRESSION_IN_THROW = new ParserErrorCode.con3('MISSING_EXPRESSION_IN_THROW', 70, "Throw expressions must compute the object to be thrown");
- static final ParserErrorCode MISSING_FUNCTION_BODY = new ParserErrorCode.con3('MISSING_FUNCTION_BODY', 71, "A function body must be provided");
- static final ParserErrorCode MISSING_FUNCTION_PARAMETERS = new ParserErrorCode.con3('MISSING_FUNCTION_PARAMETERS', 72, "Functions must have an explicit list of parameters");
- static final ParserErrorCode MISSING_IDENTIFIER = new ParserErrorCode.con3('MISSING_IDENTIFIER', 73, "Expected an identifier");
- static final ParserErrorCode MISSING_KEYWORD_OPERATOR = new ParserErrorCode.con3('MISSING_KEYWORD_OPERATOR', 74, "Operator declarations must be preceeded by the keyword 'operator'");
- static final ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = new ParserErrorCode.con3('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 75, "Library directives must include a library name");
- static final ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = new ParserErrorCode.con3('MISSING_NAME_IN_PART_OF_DIRECTIVE', 76, "Library directives must include a library name");
- static final ParserErrorCode MISSING_STATEMENT = new ParserErrorCode.con3('MISSING_STATEMENT', 77, "Expected a statement");
- static final ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con3('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 78, "There is no '%s' to close the parameter group");
- static final ParserErrorCode MISSING_TYPEDEF_PARAMETERS = new ParserErrorCode.con3('MISSING_TYPEDEF_PARAMETERS', 79, "Type aliases for functions must have an explicit list of parameters");
- static final ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con3('MISSING_VARIABLE_IN_FOR_EACH', 80, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
- static final ParserErrorCode MIXED_PARAMETER_GROUPS = new ParserErrorCode.con3('MIXED_PARAMETER_GROUPS', 81, "Cannot have both positional and named parameters in a single parameter list");
- static final ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = new ParserErrorCode.con3('MULTIPLE_EXTENDS_CLAUSES', 82, "Each class definition can have at most one extends clause");
- static final ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = new ParserErrorCode.con3('MULTIPLE_IMPLEMENTS_CLAUSES', 83, "Each class definition can have at most one implements clause");
- static final ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = new ParserErrorCode.con3('MULTIPLE_LIBRARY_DIRECTIVES', 84, "Only one library directive may be declared in a file");
- static final ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = new ParserErrorCode.con3('MULTIPLE_NAMED_PARAMETER_GROUPS', 85, "Cannot have multiple groups of named parameters in a single parameter list");
- static final ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = new ParserErrorCode.con3('MULTIPLE_PART_OF_DIRECTIVES', 86, "Only one part-of directive may be declared in a file");
- static final ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = new ParserErrorCode.con3('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 87, "Cannot have multiple groups of positional parameters in a single parameter list");
- static final ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = new ParserErrorCode.con3('MULTIPLE_VARIABLES_IN_FOR_EACH', 88, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
- static final ParserErrorCode MULTIPLE_WITH_CLAUSES = new ParserErrorCode.con3('MULTIPLE_WITH_CLAUSES', 89, "Each class definition can have at most one with clause");
- static final ParserErrorCode NAMED_FUNCTION_EXPRESSION = new ParserErrorCode.con3('NAMED_FUNCTION_EXPRESSION', 90, "Function expressions cannot be named");
- static final ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con3('NAMED_PARAMETER_OUTSIDE_GROUP', 91, "Named parameters must be enclosed in curly braces ('{' and '}')");
- static final ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE = new ParserErrorCode.con3('NATIVE_CLAUSE_IN_NON_SDK_CODE', 92, "Native clause can only be used in the SDK and code that is loaded through native extensions");
- static final ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = new ParserErrorCode.con3('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 93, "Native functions can only be declared in the SDK and code that is loaded through native extensions");
- static final ParserErrorCode NON_CONSTRUCTOR_FACTORY = new ParserErrorCode.con3('NON_CONSTRUCTOR_FACTORY', 94, "Only constructors can be declared to be a 'factory'");
- static final ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = new ParserErrorCode.con3('NON_IDENTIFIER_LIBRARY_NAME', 95, "The name of a library must be an identifier");
- static final ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = new ParserErrorCode.con3('NON_PART_OF_DIRECTIVE_IN_PART', 96, "The part-of directive must be the only directive in a part");
- static final ParserErrorCode NON_USER_DEFINABLE_OPERATOR = new ParserErrorCode.con3('NON_USER_DEFINABLE_OPERATOR', 97, "The operator '%s' is not user definable");
- static final ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = new ParserErrorCode.con3('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 98, "Normal parameters must occur before optional parameters");
- static final ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = new ParserErrorCode.con3('POSITIONAL_AFTER_NAMED_ARGUMENT', 99, "Positional arguments must occur before named arguments");
- static final ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con3('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 100, "Positional parameters must be enclosed in square brackets ('[' and ']')");
- static final ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR = new ParserErrorCode.con3('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR', 101, "Only factory constructor can specify '=' redirection.");
- static final ParserErrorCode STATIC_AFTER_CONST = new ParserErrorCode.con3('STATIC_AFTER_CONST', 102, "The modifier 'static' should be before the modifier 'const'");
- static final ParserErrorCode STATIC_AFTER_FINAL = new ParserErrorCode.con3('STATIC_AFTER_FINAL', 103, "The modifier 'static' should be before the modifier 'final'");
- static final ParserErrorCode STATIC_AFTER_VAR = new ParserErrorCode.con3('STATIC_AFTER_VAR', 104, "The modifier 'static' should be before the modifier 'var'");
- static final ParserErrorCode STATIC_CONSTRUCTOR = new ParserErrorCode.con3('STATIC_CONSTRUCTOR', 105, "Constructors cannot be static");
- static final ParserErrorCode STATIC_GETTER_WITHOUT_BODY = new ParserErrorCode.con3('STATIC_GETTER_WITHOUT_BODY', 106, "A 'static' getter must have a body");
- static final ParserErrorCode STATIC_OPERATOR = new ParserErrorCode.con3('STATIC_OPERATOR', 107, "Operators cannot be static");
- static final ParserErrorCode STATIC_SETTER_WITHOUT_BODY = new ParserErrorCode.con3('STATIC_SETTER_WITHOUT_BODY', 108, "A 'static' setter must have a body");
- static final ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = new ParserErrorCode.con3('STATIC_TOP_LEVEL_DECLARATION', 109, "Top-level declarations cannot be declared to be 'static'");
- static final ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = new ParserErrorCode.con3('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 110, "The 'default' case should be the last case in a switch statement");
- static final ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = new ParserErrorCode.con3('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 111, "The 'default' case can only be declared once");
- static final ParserErrorCode TOP_LEVEL_OPERATOR = new ParserErrorCode.con3('TOP_LEVEL_OPERATOR', 112, "Operators must be declared within a class");
- static final ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con3('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 113, "There is no '%s' to open a parameter group");
- static final ParserErrorCode UNEXPECTED_TOKEN = new ParserErrorCode.con3('UNEXPECTED_TOKEN', 114, "Unexpected token '%s'");
- static final ParserErrorCode WITH_BEFORE_EXTENDS = new ParserErrorCode.con3('WITH_BEFORE_EXTENDS', 115, "The extends clause must be before the with clause");
- static final ParserErrorCode WITH_WITHOUT_EXTENDS = new ParserErrorCode.con3('WITH_WITHOUT_EXTENDS', 116, "The with clause cannot be used without an extends clause");
- static final ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = new ParserErrorCode.con3('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 117, "The default value of a named parameter should be preceeded by ':'");
- static final ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = new ParserErrorCode.con3('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 118, "The default value of a positional parameter should be preceeded by '='");
- static final ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con3('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 119, "Expected '%s' to close parameter group");
- static final ParserErrorCode VAR_AND_TYPE = new ParserErrorCode.con3('VAR_AND_TYPE', 120, "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
- static final ParserErrorCode VAR_AS_TYPE_NAME = new ParserErrorCode.con3('VAR_AS_TYPE_NAME', 121, "The keyword 'var' cannot be used as a type name");
- static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con3('VAR_CLASS', 122, "Classes cannot be declared to be 'var'");
- static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con3('VAR_RETURN_TYPE', 123, "The return type cannot be 'var'");
- static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con3('VAR_TYPEDEF', 124, "Type aliases cannot be declared to be 'var'");
- static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con3('VOID_PARAMETER', 125, "Parameters cannot have a type of 'void'");
- static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con3('VOID_VARIABLE', 126, "Variables cannot have a type of 'void'");
+ static final ParserErrorCode GETTER_IN_FUNCTION = new ParserErrorCode.con3('GETTER_IN_FUNCTION', 51, "Getters cannot be defined within methods or functions");
+ static final ParserErrorCode GETTER_WITH_PARAMETERS = new ParserErrorCode.con3('GETTER_WITH_PARAMETERS', 52, "Getter should be declared without a parameter list");
+ static final ParserErrorCode ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE = new ParserErrorCode.con3('ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE', 53, "Illegal assignment to non-assignable expression");
+ static final ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS = new ParserErrorCode.con3('IMPLEMENTS_BEFORE_EXTENDS', 54, "The extends clause must be before the implements clause");
+ static final ParserErrorCode IMPLEMENTS_BEFORE_WITH = new ParserErrorCode.con3('IMPLEMENTS_BEFORE_WITH', 55, "The with clause must be before the implements clause");
+ static final ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new ParserErrorCode.con3('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 56, "Import directives must preceed part directives");
+ static final ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con3('INITIALIZED_VARIABLE_IN_FOR_EACH', 57, "The loop variable in a for-each loop cannot be initialized");
+ static final ParserErrorCode INVALID_CODE_POINT = new ParserErrorCode.con3('INVALID_CODE_POINT', 58, "The escape sequence '%s' is not a valid code point");
+ static final ParserErrorCode INVALID_COMMENT_REFERENCE = new ParserErrorCode.con3('INVALID_COMMENT_REFERENCE', 59, "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
+ static final ParserErrorCode INVALID_HEX_ESCAPE = new ParserErrorCode.con3('INVALID_HEX_ESCAPE', 60, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
+ static final ParserErrorCode INVALID_OPERATOR = new ParserErrorCode.con3('INVALID_OPERATOR', 61, "The string '%s' is not a valid operator");
+ static final ParserErrorCode INVALID_OPERATOR_FOR_SUPER = new ParserErrorCode.con3('INVALID_OPERATOR_FOR_SUPER', 62, "The operator '%s' cannot be used with 'super'");
+ static final ParserErrorCode INVALID_UNICODE_ESCAPE = new ParserErrorCode.con3('INVALID_UNICODE_ESCAPE', 63, "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
+ static final ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = new ParserErrorCode.con3('LIBRARY_DIRECTIVE_NOT_FIRST', 64, "The library directive must appear before all other directives");
+ static final ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER = new ParserErrorCode.con3('LOCAL_FUNCTION_DECLARATION_MODIFIER', 65, "Local function declarations cannot specify any modifier");
+ static final ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = new ParserErrorCode.con3('MISSING_ASSIGNABLE_SELECTOR', 66, "Missing selector such as \".<identifier>\" or \"[0]\"");
+ static final ParserErrorCode MISSING_CATCH_OR_FINALLY = new ParserErrorCode.con3('MISSING_CATCH_OR_FINALLY', 67, "A try statement must have either a catch or finally clause");
+ static final ParserErrorCode MISSING_CLASS_BODY = new ParserErrorCode.con3('MISSING_CLASS_BODY', 68, "A class definition must have a body, even if it is empty");
+ static final ParserErrorCode MISSING_CLOSING_PARENTHESIS = new ParserErrorCode.con3('MISSING_CLOSING_PARENTHESIS', 69, "The closing parenthesis is missing");
+ static final ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = new ParserErrorCode.con3('MISSING_CONST_FINAL_VAR_OR_TYPE', 70, "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
+ static final ParserErrorCode MISSING_EXPRESSION_IN_THROW = new ParserErrorCode.con3('MISSING_EXPRESSION_IN_THROW', 71, "Throw expressions must compute the object to be thrown");
+ static final ParserErrorCode MISSING_FUNCTION_BODY = new ParserErrorCode.con3('MISSING_FUNCTION_BODY', 72, "A function body must be provided");
+ static final ParserErrorCode MISSING_FUNCTION_PARAMETERS = new ParserErrorCode.con3('MISSING_FUNCTION_PARAMETERS', 73, "Functions must have an explicit list of parameters");
+ static final ParserErrorCode MISSING_IDENTIFIER = new ParserErrorCode.con3('MISSING_IDENTIFIER', 74, "Expected an identifier");
+ static final ParserErrorCode MISSING_KEYWORD_OPERATOR = new ParserErrorCode.con3('MISSING_KEYWORD_OPERATOR', 75, "Operator declarations must be preceeded by the keyword 'operator'");
+ static final ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = new ParserErrorCode.con3('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 76, "Library directives must include a library name");
+ static final ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = new ParserErrorCode.con3('MISSING_NAME_IN_PART_OF_DIRECTIVE', 77, "Library directives must include a library name");
+ static final ParserErrorCode MISSING_STATEMENT = new ParserErrorCode.con3('MISSING_STATEMENT', 78, "Expected a statement");
+ static final ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con3('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 79, "There is no '%s' to close the parameter group");
+ static final ParserErrorCode MISSING_TYPEDEF_PARAMETERS = new ParserErrorCode.con3('MISSING_TYPEDEF_PARAMETERS', 80, "Type aliases for functions must have an explicit list of parameters");
+ static final ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con3('MISSING_VARIABLE_IN_FOR_EACH', 81, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
+ static final ParserErrorCode MIXED_PARAMETER_GROUPS = new ParserErrorCode.con3('MIXED_PARAMETER_GROUPS', 82, "Cannot have both positional and named parameters in a single parameter list");
+ static final ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = new ParserErrorCode.con3('MULTIPLE_EXTENDS_CLAUSES', 83, "Each class definition can have at most one extends clause");
+ static final ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = new ParserErrorCode.con3('MULTIPLE_IMPLEMENTS_CLAUSES', 84, "Each class definition can have at most one implements clause");
+ static final ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = new ParserErrorCode.con3('MULTIPLE_LIBRARY_DIRECTIVES', 85, "Only one library directive may be declared in a file");
+ static final ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = new ParserErrorCode.con3('MULTIPLE_NAMED_PARAMETER_GROUPS', 86, "Cannot have multiple groups of named parameters in a single parameter list");
+ static final ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = new ParserErrorCode.con3('MULTIPLE_PART_OF_DIRECTIVES', 87, "Only one part-of directive may be declared in a file");
+ static final ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = new ParserErrorCode.con3('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 88, "Cannot have multiple groups of positional parameters in a single parameter list");
+ static final ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = new ParserErrorCode.con3('MULTIPLE_VARIABLES_IN_FOR_EACH', 89, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
+ static final ParserErrorCode MULTIPLE_WITH_CLAUSES = new ParserErrorCode.con3('MULTIPLE_WITH_CLAUSES', 90, "Each class definition can have at most one with clause");
+ static final ParserErrorCode NAMED_FUNCTION_EXPRESSION = new ParserErrorCode.con3('NAMED_FUNCTION_EXPRESSION', 91, "Function expressions cannot be named");
+ static final ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con3('NAMED_PARAMETER_OUTSIDE_GROUP', 92, "Named parameters must be enclosed in curly braces ('{' and '}')");
+ static final ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE = new ParserErrorCode.con3('NATIVE_CLAUSE_IN_NON_SDK_CODE', 93, "Native clause can only be used in the SDK and code that is loaded through native extensions");
+ static final ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = new ParserErrorCode.con3('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 94, "Native functions can only be declared in the SDK and code that is loaded through native extensions");
+ static final ParserErrorCode NON_CONSTRUCTOR_FACTORY = new ParserErrorCode.con3('NON_CONSTRUCTOR_FACTORY', 95, "Only constructors can be declared to be a 'factory'");
+ static final ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = new ParserErrorCode.con3('NON_IDENTIFIER_LIBRARY_NAME', 96, "The name of a library must be an identifier");
+ static final ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = new ParserErrorCode.con3('NON_PART_OF_DIRECTIVE_IN_PART', 97, "The part-of directive must be the only directive in a part");
+ static final ParserErrorCode NON_USER_DEFINABLE_OPERATOR = new ParserErrorCode.con3('NON_USER_DEFINABLE_OPERATOR', 98, "The operator '%s' is not user definable");
+ static final ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = new ParserErrorCode.con3('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 99, "Normal parameters must occur before optional parameters");
+ static final ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = new ParserErrorCode.con3('POSITIONAL_AFTER_NAMED_ARGUMENT', 100, "Positional arguments must occur before named arguments");
+ static final ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con3('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 101, "Positional parameters must be enclosed in square brackets ('[' and ']')");
+ static final ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR = new ParserErrorCode.con3('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR', 102, "Only factory constructor can specify '=' redirection.");
+ static final ParserErrorCode SETTER_IN_FUNCTION = new ParserErrorCode.con3('SETTER_IN_FUNCTION', 103, "Setters cannot be defined within methods or functions");
+ static final ParserErrorCode STATIC_AFTER_CONST = new ParserErrorCode.con3('STATIC_AFTER_CONST', 104, "The modifier 'static' should be before the modifier 'const'");
+ static final ParserErrorCode STATIC_AFTER_FINAL = new ParserErrorCode.con3('STATIC_AFTER_FINAL', 105, "The modifier 'static' should be before the modifier 'final'");
+ static final ParserErrorCode STATIC_AFTER_VAR = new ParserErrorCode.con3('STATIC_AFTER_VAR', 106, "The modifier 'static' should be before the modifier 'var'");
+ static final ParserErrorCode STATIC_CONSTRUCTOR = new ParserErrorCode.con3('STATIC_CONSTRUCTOR', 107, "Constructors cannot be static");
+ static final ParserErrorCode STATIC_GETTER_WITHOUT_BODY = new ParserErrorCode.con3('STATIC_GETTER_WITHOUT_BODY', 108, "A 'static' getter must have a body");
+ static final ParserErrorCode STATIC_OPERATOR = new ParserErrorCode.con3('STATIC_OPERATOR', 109, "Operators cannot be static");
+ static final ParserErrorCode STATIC_SETTER_WITHOUT_BODY = new ParserErrorCode.con3('STATIC_SETTER_WITHOUT_BODY', 110, "A 'static' setter must have a body");
+ static final ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = new ParserErrorCode.con3('STATIC_TOP_LEVEL_DECLARATION', 111, "Top-level declarations cannot be declared to be 'static'");
+ static final ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = new ParserErrorCode.con3('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 112, "The 'default' case should be the last case in a switch statement");
+ static final ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = new ParserErrorCode.con3('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 113, "The 'default' case can only be declared once");
+ static final ParserErrorCode TOP_LEVEL_OPERATOR = new ParserErrorCode.con3('TOP_LEVEL_OPERATOR', 114, "Operators must be declared within a class");
+ static final ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con3('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 115, "There is no '%s' to open a parameter group");
+ static final ParserErrorCode UNEXPECTED_TOKEN = new ParserErrorCode.con3('UNEXPECTED_TOKEN', 116, "Unexpected token '%s'");
+ static final ParserErrorCode WITH_BEFORE_EXTENDS = new ParserErrorCode.con3('WITH_BEFORE_EXTENDS', 117, "The extends clause must be before the with clause");
+ static final ParserErrorCode WITH_WITHOUT_EXTENDS = new ParserErrorCode.con3('WITH_WITHOUT_EXTENDS', 118, "The with clause cannot be used without an extends clause");
+ static final ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = new ParserErrorCode.con3('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 119, "The default value of a named parameter should be preceeded by ':'");
+ static final ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = new ParserErrorCode.con3('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 120, "The default value of a positional parameter should be preceeded by '='");
+ static final ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = new ParserErrorCode.con3('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 121, "Expected '%s' to close parameter group");
+ static final ParserErrorCode VAR_AND_TYPE = new ParserErrorCode.con3('VAR_AND_TYPE', 122, "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
+ static final ParserErrorCode VAR_AS_TYPE_NAME = new ParserErrorCode.con3('VAR_AS_TYPE_NAME', 123, "The keyword 'var' cannot be used as a type name");
+ static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con3('VAR_CLASS', 124, "Classes cannot be declared to be 'var'");
+ static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con3('VAR_RETURN_TYPE', 125, "The return type cannot be 'var'");
+ static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con3('VAR_TYPEDEF', 126, "Type aliases cannot be declared to be 'var'");
+ static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con3('VOID_PARAMETER', 127, "Parameters cannot have a type of 'void'");
+ static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con3('VOID_VARIABLE', 128, "Variables cannot have a type of 'void'");
static final List<ParserErrorCode> values = [
ABSTRACT_CLASS_MEMBER,
ABSTRACT_STATIC_METHOD,
@@ -5779,6 +5843,7 @@
FINAL_METHOD,
FINAL_TYPEDEF,
FUNCTION_TYPED_PARAMETER_VAR,
+ GETTER_IN_FUNCTION,
GETTER_WITH_PARAMETERS,
ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE,
IMPLEMENTS_BEFORE_EXTENDS,
@@ -5830,6 +5895,7 @@
POSITIONAL_AFTER_NAMED_ARGUMENT,
POSITIONAL_PARAMETER_OUTSIDE_GROUP,
REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR,
+ SETTER_IN_FUNCTION,
STATIC_AFTER_CONST,
STATIC_AFTER_FINAL,
STATIC_AFTER_VAR,
@@ -6210,8 +6276,13 @@
return null;
}
Object visitForEachStatement(ForEachStatement node) {
+ DeclaredIdentifier loopVariable = node.loopVariable;
_writer.print("for (");
- visit(node.loopVariable);
+ if (loopVariable == null) {
+ visit(node.identifier);
+ } else {
+ visit(loopVariable);
+ }
_writer.print(" in ");
visit(node.iterator);
_writer.print(") ");
diff --git a/pkg/analyzer_experimental/lib/src/generated/resolver.dart b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
index 06238d0..c38a954 100644
--- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
@@ -8,6 +8,7 @@
import 'source.dart';
import 'error.dart';
import 'scanner.dart' as sc;
+import 'utilities_general.dart';
import 'utilities_dart.dart';
import 'ast.dart';
import 'parser.dart' show Parser, ParserErrorCode;
@@ -33,6 +34,7 @@
* @throws AnalysisException if the analysis could not be performed
*/
CompilationUnitElementImpl buildCompilationUnit(Source source2, CompilationUnit unit) {
+ TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
if (unit == null) {
return null;
}
@@ -47,6 +49,7 @@
element.types = holder.types;
element.topLevelVariables = holder.topLevelVariables;
unit.element = element;
+ timeCounter.stop();
return element;
}
}
@@ -125,8 +128,8 @@
visitChildren(holder, node);
SimpleIdentifier className = node.name;
ClassElementImpl element = new ClassElementImpl(className);
- List<TypeVariableElement> typeVariables = holder.typeVariables;
- List<Type2> typeArguments = createTypeVariableTypes(typeVariables);
+ List<TypeParameterElement> typeParameters = holder.typeParameters;
+ List<Type2> typeArguments = createTypeParameterTypes(typeParameters);
InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
interfaceType.typeArguments = typeArguments;
element.type = interfaceType;
@@ -139,7 +142,7 @@
element.constructors = constructors;
element.fields = holder.fields;
element.methods = holder.methods;
- element.typeVariables = typeVariables;
+ element.typeParameters = typeParameters;
element.validMixin = _isValidMixin;
for (FunctionTypeImpl functionType in _functionTypesToFix) {
functionType.typeArguments = typeArguments;
@@ -158,9 +161,9 @@
ClassElementImpl element = new ClassElementImpl(className);
element.abstract = node.abstractKeyword != null;
element.typedef = true;
- List<TypeVariableElement> typeVariables = holder.typeVariables;
- element.typeVariables = typeVariables;
- List<Type2> typeArguments = createTypeVariableTypes(typeVariables);
+ List<TypeParameterElement> typeParameters = holder.typeParameters;
+ element.typeParameters = typeParameters;
+ List<Type2> typeArguments = createTypeParameterTypes(typeParameters);
InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
interfaceType.typeArguments = typeArguments;
element.type = interfaceType;
@@ -244,10 +247,7 @@
if (defaultValue != null) {
parameter.setDefaultValueRange(defaultValue.offset, defaultValue.length);
}
- FunctionBody body = getFunctionBody(node);
- if (body != null) {
- parameter.setVisibleRange(body.offset, body.length);
- }
+ setParameterVisibleRange(node, parameter);
_currentHolder.addParameter(parameter);
parameterName.staticElement = parameter;
node.parameter.accept(this);
@@ -316,23 +316,24 @@
return null;
}
String propertyName = propertyNameNode.name;
- FieldElementImpl field = _currentHolder.getField(propertyName) as FieldElementImpl;
- if (field == null) {
- field = new FieldElementImpl.con2(node.name.name);
- field.final2 = true;
- field.static = true;
- _currentHolder.addField(field);
+ TopLevelVariableElementImpl variable = _currentHolder.getTopLevelVariable(propertyName) as TopLevelVariableElementImpl;
+ if (variable == null) {
+ variable = new TopLevelVariableElementImpl.con2(node.name.name);
+ variable.final2 = true;
+ variable.synthetic = true;
+ _currentHolder.addTopLevelVariable(variable);
}
if (matches(property, sc.Keyword.GET)) {
PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(propertyNameNode);
getter.functions = holder.functions;
getter.labels = holder.labels;
getter.localVariables = holder.localVariables;
- getter.variable = field;
+ getter.variable = variable;
getter.getter = true;
getter.static = true;
- field.getter = getter;
+ variable.getter = getter;
_currentHolder.addAccessor(getter);
+ expression.element = getter;
propertyNameNode.staticElement = getter;
} else {
PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(propertyNameNode);
@@ -340,12 +341,13 @@
setter.labels = holder.labels;
setter.localVariables = holder.localVariables;
setter.parameters = holder.parameters;
- setter.variable = field;
+ setter.variable = variable;
setter.setter = true;
setter.static = true;
- field.setter = setter;
- field.final2 = false;
+ variable.setter = setter;
+ variable.final2 = false;
_currentHolder.addAccessor(setter);
+ expression.element = setter;
propertyNameNode.staticElement = setter;
}
}
@@ -390,12 +392,12 @@
visitChildren(holder, node);
SimpleIdentifier aliasName = node.name;
List<ParameterElement> parameters = holder.parameters;
- List<TypeVariableElement> typeVariables = holder.typeVariables;
+ List<TypeParameterElement> typeParameters = holder.typeParameters;
FunctionTypeAliasElementImpl element = new FunctionTypeAliasElementImpl(aliasName);
element.parameters = parameters;
- element.typeVariables = typeVariables;
+ element.typeParameters = typeParameters;
FunctionTypeImpl type = new FunctionTypeImpl.con2(element);
- type.typeArguments = createTypeVariableTypes(typeVariables);
+ type.typeArguments = createTypeParameterTypes(typeParameters);
element.type = type;
_currentHolder.addTypeAlias(element);
aliasName.staticElement = element;
@@ -407,6 +409,7 @@
SimpleIdentifier parameterName = node.identifier;
ParameterElementImpl parameter = new ParameterElementImpl.con1(parameterName);
parameter.parameterKind = node.kind;
+ setParameterVisibleRange(node, parameter);
_currentHolder.addParameter(parameter);
parameterName.staticElement = parameter;
}
@@ -460,6 +463,7 @@
field = new FieldElementImpl.con2(node.name.name);
field.final2 = true;
field.static = isStatic;
+ field.synthetic = true;
_currentHolder.addField(field);
}
if (matches(property, sc.Keyword.GET)) {
@@ -500,6 +504,7 @@
parameter.const3 = node.isConst;
parameter.final2 = node.isFinal;
parameter.parameterKind = node.kind;
+ setParameterVisibleRange(node, parameter);
_currentHolder.addParameter(parameter);
parameterName.staticElement = parameter;
}
@@ -529,11 +534,11 @@
}
Object visitTypeParameter(TypeParameter node) {
SimpleIdentifier parameterName = node.name;
- TypeVariableElementImpl element = new TypeVariableElementImpl(parameterName);
- TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
- element.type = type;
- _currentHolder.addTypeVariable(element);
- parameterName.staticElement = element;
+ TypeParameterElementImpl typeParameter = new TypeParameterElementImpl(parameterName);
+ TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typeParameter);
+ typeParameter.type = typeParameterType;
+ _currentHolder.addTypeParameter(typeParameter);
+ parameterName.staticElement = typeParameter;
return super.visitTypeParameter(node);
}
Object visitVariableDeclaration(VariableDeclaration node) {
@@ -641,20 +646,20 @@
}
/**
- * Create the types associated with the given type variables, setting the type of each type
- * variable, and return an array of types corresponding to the given variables.
+ * Create the types associated with the given type parameters, setting the type of each type
+ * parameter, and return an array of types corresponding to the given parameters.
*
- * @param typeVariables the type variables for which types are to be created
- * @return
+ * @param typeParameters the type parameters for which types are to be created
+ * @return an array of types corresponding to the given parameters
*/
- List<Type2> createTypeVariableTypes(List<TypeVariableElement> typeVariables) {
- int typeVariableCount = typeVariables.length;
- List<Type2> typeArguments = new List<Type2>(typeVariableCount);
- for (int i = 0; i < typeVariableCount; i++) {
- TypeVariableElementImpl typeVariable = typeVariables[i] as TypeVariableElementImpl;
- TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable);
- typeVariable.type = typeArgument;
- typeArguments[i] = typeArgument;
+ List<Type2> createTypeParameterTypes(List<TypeParameterElement> typeParameters) {
+ int typeParameterCount = typeParameters.length;
+ List<Type2> typeArguments = new List<Type2>(typeParameterCount);
+ for (int i = 0; i < typeParameterCount; i++) {
+ TypeParameterElementImpl typeParameter = typeParameters[i] as TypeParameterElementImpl;
+ TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typeParameter);
+ typeParameter.type = typeParameterType;
+ typeArguments[i] = typeParameterType;
}
return typeArguments;
}
@@ -669,7 +674,9 @@
FunctionBody getFunctionBody(FormalParameter node) {
ASTNode parent = node.parent;
while (parent != null) {
- if (parent is FunctionExpression) {
+ if (parent is ConstructorDeclaration) {
+ return ((parent as ConstructorDeclaration)).body;
+ } else if (parent is FunctionExpression) {
return ((parent as FunctionExpression)).body;
} else if (parent is MethodDeclaration) {
return ((parent as MethodDeclaration)).body;
@@ -689,6 +696,16 @@
bool matches(sc.Token token, sc.Keyword keyword2) => token != null && identical(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).keyword, keyword2);
/**
+ * Sets the visible source range for formal parameter.
+ */
+ void setParameterVisibleRange(FormalParameter node, ParameterElementImpl element) {
+ FunctionBody body = getFunctionBody(node);
+ if (body != null) {
+ element.setVisibleRange(body.offset, body.length);
+ }
+ }
+
+ /**
* Make the given holder be the current holder while visiting the given node.
*
* @param holder the holder that will gather elements that are built while visiting the children
@@ -739,10 +756,10 @@
List<VariableElement> _localVariables;
List<MethodElement> _methods;
List<ParameterElement> _parameters;
- List<VariableElement> _topLevelVariables;
+ List<TopLevelVariableElement> _topLevelVariables;
List<ClassElement> _types;
List<FunctionTypeAliasElement> _typeAliases;
- List<TypeVariableElement> _typeVariables;
+ List<TypeParameterElement> _typeParameters;
void addAccessor(PropertyAccessorElement element) {
if (_accessors == null) {
_accessors = new List<PropertyAccessorElement>();
@@ -793,7 +810,7 @@
}
void addTopLevelVariable(TopLevelVariableElement element) {
if (_topLevelVariables == null) {
- _topLevelVariables = new List<VariableElement>();
+ _topLevelVariables = new List<TopLevelVariableElement>();
}
_topLevelVariables.add(element);
}
@@ -809,11 +826,11 @@
}
_typeAliases.add(element);
}
- void addTypeVariable(TypeVariableElement element) {
- if (_typeVariables == null) {
- _typeVariables = new List<TypeVariableElement>();
+ void addTypeParameter(TypeParameterElement element) {
+ if (_typeParameters == null) {
+ _typeParameters = new List<TypeParameterElement>();
}
- _typeVariables.add(element);
+ _typeParameters.add(element);
}
List<PropertyAccessorElement> get accessors {
if (_accessors == null) {
@@ -890,6 +907,17 @@
_parameters = null;
return result;
}
+ TopLevelVariableElement getTopLevelVariable(String variableName) {
+ if (_topLevelVariables == null) {
+ return null;
+ }
+ for (TopLevelVariableElement variable in _topLevelVariables) {
+ if (variable.name == variableName) {
+ return variable;
+ }
+ }
+ return null;
+ }
List<TopLevelVariableElement> get topLevelVariables {
if (_topLevelVariables == null) {
return TopLevelVariableElementImpl.EMPTY_ARRAY;
@@ -906,6 +934,14 @@
_typeAliases = null;
return result;
}
+ List<TypeParameterElement> get typeParameters {
+ if (_typeParameters == null) {
+ return TypeParameterElementImpl.EMPTY_ARRAY;
+ }
+ List<TypeParameterElement> result = new List.from(_typeParameters);
+ _typeParameters = null;
+ return result;
+ }
List<ClassElement> get types {
if (_types == null) {
return ClassElementImpl.EMPTY_ARRAY;
@@ -914,14 +950,6 @@
_types = null;
return result;
}
- List<TypeVariableElement> get typeVariables {
- if (_typeVariables == null) {
- return TypeVariableElementImpl.EMPTY_ARRAY;
- }
- List<TypeVariableElement> result = new List.from(_typeVariables);
- _typeVariables = null;
- return result;
- }
void validate() {
JavaStringBuilder builder = new JavaStringBuilder();
if (_accessors != null) {
@@ -998,12 +1026,12 @@
builder.append(_typeAliases.length);
builder.append(" type aliases");
}
- if (_typeVariables != null) {
+ if (_typeParameters != null) {
if (builder.length > 0) {
builder.append("; ");
}
- builder.append(_typeVariables.length);
- builder.append(" type variables");
+ builder.append(_typeParameters.length);
+ builder.append(" type parameters");
}
if (builder.length > 0) {
AnalysisEngine.instance.logger.logError("Failed to capture elements: ${builder.toString()}");
@@ -1258,6 +1286,332 @@
}
}
/**
+ * Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
+ * violations of Dart best practices.
+ *
+ * @coverage dart.engine.resolver
+ */
+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 _OBJECT_TYPE_NAME = "Object";
+ static String _SETTER = "setter";
+ static String _TO_INT_METHOD_NAME = "toInt";
+
+ /**
+ * Given a parenthesized expression, this returns the parent (or recursively grand-parent) of the
+ * expression that is a parenthesized expression, but whose parent is not a parenthesized
+ * expression.
+ *
+ * For example given the code `(((e)))`: `(e) -> (((e)))`.
+ *
+ * @param parenthesizedExpression some expression whose parent is a parenthesized expression
+ * @return the first parent or grand-parent that is a parenthesized expression, that does not have
+ * a parenthesized expression parent
+ */
+ static ParenthesizedExpression wrapParenthesizedExpression(ParenthesizedExpression parenthesizedExpression) {
+ if (parenthesizedExpression.parent is ParenthesizedExpression) {
+ return wrapParenthesizedExpression(parenthesizedExpression.parent as ParenthesizedExpression);
+ }
+ return parenthesizedExpression;
+ }
+
+ /**
+ * The class containing the AST nodes being visited, or `null` if we are not in the scope of
+ * a class.
+ */
+ ClassElement _enclosingClass;
+
+ /**
+ * The error reporter by which errors will be reported.
+ */
+ ErrorReporter _errorReporter;
+
+ /**
+ * Create a new instance of the [BestPracticesVerifier].
+ *
+ * @param errorReporter the error reporter
+ */
+ BestPracticesVerifier(ErrorReporter errorReporter) {
+ this._errorReporter = errorReporter;
+ }
+ Object visitAsExpression(AsExpression node) {
+ checkForUnnecessaryCast(node);
+ return super.visitAsExpression(node);
+ }
+ Object visitBinaryExpression(BinaryExpression node) {
+ checkForDivisionOptimizationHint(node);
+ return super.visitBinaryExpression(node);
+ }
+ Object visitClassDeclaration(ClassDeclaration node) {
+ ClassElement outerClass = _enclosingClass;
+ try {
+ _enclosingClass = node.element;
+ return super.visitClassDeclaration(node);
+ } finally {
+ _enclosingClass = outerClass;
+ }
+ }
+ Object visitIsExpression(IsExpression node) {
+ checkAllTypeChecks(node);
+ return super.visitIsExpression(node);
+ }
+ Object visitMethodDeclaration(MethodDeclaration node) {
+ checkForOverridingPrivateMember(node);
+ return super.visitMethodDeclaration(node);
+ }
+
+ /**
+ * Check for the passed is expression for the unnecessary type check hint codes as well as null
+ * checks expressed using an is expression.
+ *
+ * @param node the is expression to check
+ * @return `true` if and only if a hint code is generated on the passed node
+ * @see HintCode#TYPE_CHECK_IS_NOT_NULL
+ * @see HintCode#TYPE_CHECK_IS_NULL
+ * @see HintCode#UNNECESSARY_TYPE_CHECK_TRUE
+ * @see HintCode#UNNECESSARY_TYPE_CHECK_FALSE
+ */
+ bool checkAllTypeChecks(IsExpression node) {
+ Expression expression = node.expression;
+ TypeName typeName = node.type;
+ Type2 lhsType = expression.staticType;
+ Type2 rhsType = typeName.type;
+ if (lhsType == null || rhsType == null) {
+ return false;
+ }
+ String rhsNameStr = typeName.name.name;
+ if ((rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax)) {
+ if (node.notOperator == null) {
+ _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
+ } else {
+ _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node, []);
+ }
+ return true;
+ }
+ Element rhsElement = rhsType.element;
+ LibraryElement libraryElement = rhsElement != null ? rhsElement.library : null;
+ if (libraryElement != null && libraryElement.isDartCore) {
+ if ((rhsType.isObject && rhsNameStr == _OBJECT_TYPE_NAME) || (expression is NullLiteral && rhsNameStr == _NULL_TYPE_NAME)) {
+ if (node.notOperator == null) {
+ _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
+ } else {
+ _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node, []);
+ }
+ return true;
+ } else if (rhsNameStr == _NULL_TYPE_NAME) {
+ if (node.notOperator == null) {
+ _errorReporter.reportError2(HintCode.TYPE_CHECK_IS_NULL, node, []);
+ } else {
+ _errorReporter.reportError2(HintCode.TYPE_CHECK_IS_NOT_NULL, node, []);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check for the passed binary expression for the [HintCode#DIVISION_OPTIMIZATION].
+ *
+ * @param node the binary expression to check
+ * @return `true` if and only if a hint code is generated on the passed node
+ * @see HintCode#DIVISION_OPTIMIZATION
+ */
+ bool checkForDivisionOptimizationHint(BinaryExpression node) {
+ if (node.operator.type != sc.TokenType.SLASH) {
+ return false;
+ }
+ MethodElement methodElement = node.bestElement;
+ if (methodElement == null) {
+ return false;
+ }
+ LibraryElement libraryElement = methodElement.library;
+ if (libraryElement != null && !libraryElement.isDartCore) {
+ return false;
+ }
+ if (node.parent is ParenthesizedExpression) {
+ ParenthesizedExpression parenthesizedExpression = wrapParenthesizedExpression(node.parent as ParenthesizedExpression);
+ if (parenthesizedExpression.parent is MethodInvocation) {
+ MethodInvocation methodInvocation = parenthesizedExpression.parent as MethodInvocation;
+ if (_TO_INT_METHOD_NAME == methodInvocation.methodName.name && methodInvocation.argumentList.arguments.isEmpty) {
+ _errorReporter.reportError2(HintCode.DIVISION_OPTIMIZATION, methodInvocation, []);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check for the passed class declaration for the
+ * [HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
+ *
+ * @param node the class declaration to check
+ * @return `true` if and only if a hint code is generated on the passed node
+ * @see HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE
+ */
+ bool checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
+ ClassElement classElement = node.element;
+ if (classElement == null) {
+ return false;
+ }
+ MethodElement equalsOperatorMethodElement = classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
+ if (equalsOperatorMethodElement != null) {
+ PropertyAccessorElement hashCodeElement = classElement.getGetter(_HASHCODE_GETTER_NAME);
+ if (hashCodeElement == null) {
+ _errorReporter.reportError2(HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE, node.name, [classElement.displayName]);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check for the passed class declaration for the
+ * [HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
+ *
+ * @param node the class 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 (_enclosingClass == null) {
+ return false;
+ }
+ if (!Identifier.isPrivateName(node.name.name)) {
+ return false;
+ }
+ ExecutableElement executableElement = node.element;
+ if (executableElement == null) {
+ return false;
+ }
+ 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.reportError2(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
+ memberType,
+ executableElement.displayName,
+ classElement.displayName]);
+ return true;
+ }
+ } else {
+ MethodElement overriddenMethod = classElement.getMethod(elementName);
+ if (overriddenMethod != null) {
+ _errorReporter.reportError2(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
+ * @return `true` if and only if a hint code is generated on the passed node
+ * @see HintCode#UNNECESSARY_CAST
+ */
+ bool checkForUnnecessaryCast(AsExpression node) {
+ Expression expression = node.expression;
+ TypeName typeName = node.type;
+ Type2 lhsType = expression.staticType;
+ Type2 rhsType = typeName.type;
+ if (lhsType != null && rhsType != null && !lhsType.isDynamic && !rhsType.isDynamic && lhsType.isSubtypeOf(rhsType)) {
+ _errorReporter.reportError2(HintCode.UNNECESSARY_CAST, node, []);
+ return true;
+ }
+ return false;
+ }
+}
+/**
+ * Instances of the class `Dart2JSVerifier` traverse an AST structure looking for hints for
+ * code that will be compiled to JS, such as [HintCode#IS_DOUBLE].
+ *
+ * @coverage dart.engine.resolver
+ */
+class Dart2JSVerifier extends RecursiveASTVisitor<Object> {
+
+ /**
+ * The error reporter by which errors will be reported.
+ */
+ ErrorReporter _errorReporter;
+
+ /**
+ * The name of the `double` type.
+ */
+ static String _DOUBLE_TYPE_NAME = "double";
+
+ /**
+ * Create a new instance of the [Dart2JSVerifier].
+ *
+ * @param errorReporter the error reporter
+ */
+ Dart2JSVerifier(ErrorReporter errorReporter) {
+ this._errorReporter = errorReporter;
+ }
+ Object visitIsExpression(IsExpression node) {
+ checkForIsDoubleHints(node);
+ return super.visitIsExpression(node);
+ }
+
+ /**
+ * Check for instances of `x is double`, `x is int`, `x is! double` and
+ * `x is! int`.
+ *
+ * @param node the is expression to check
+ * @return `true` if and only if a hint code is generated on the passed node
+ * @see HintCode#IS_DOUBLE
+ * @see HintCode#IS_INT
+ * @see HintCode#IS_NOT_DOUBLE
+ * @see HintCode#IS_NOT_INT
+ */
+ bool checkForIsDoubleHints(IsExpression node) {
+ TypeName typeName = node.type;
+ Type2 type = typeName.type;
+ if (type != null && type.element != null) {
+ Element element = type.element;
+ String typeNameStr = element.name;
+ LibraryElement libraryElement = element.library;
+ if (typeNameStr == _DOUBLE_TYPE_NAME && libraryElement != null && libraryElement.isDartCore) {
+ if (node.notOperator == null) {
+ _errorReporter.reportError2(HintCode.IS_DOUBLE, node, []);
+ } else {
+ _errorReporter.reportError2(HintCode.IS_NOT_DOUBLE, node, []);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+}
+/**
* Instances of the class `DeadCodeVerifier` traverse an AST structure looking for cases of
* [HintCode#DEAD_CODE].
*
@@ -1284,16 +1638,18 @@
bool isBarBar = identical(operator.type, sc.TokenType.BAR_BAR);
if (isAmpAmp || isBarBar) {
Expression lhsCondition = node.leftOperand;
- ValidResult lhsResult = getConstantBooleanValue(lhsCondition);
- if (lhsResult != null) {
- if (identical(lhsResult, ValidResult.RESULT_TRUE) && isBarBar) {
- _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, []);
- safelyVisit(lhsCondition);
- return null;
- } else if (identical(lhsResult, ValidResult.RESULT_FALSE) && isAmpAmp) {
- _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, []);
- safelyVisit(lhsCondition);
- return null;
+ if (!isDebugConstant(lhsCondition)) {
+ ValidResult lhsResult = getConstantBooleanValue(lhsCondition);
+ if (lhsResult != null) {
+ if (identical(lhsResult, ValidResult.RESULT_TRUE) && isBarBar) {
+ _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, []);
+ safelyVisit(lhsCondition);
+ return null;
+ } else if (identical(lhsResult, ValidResult.RESULT_FALSE) && isAmpAmp) {
+ _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, []);
+ safelyVisit(lhsCondition);
+ return null;
+ }
}
}
}
@@ -1325,35 +1681,41 @@
}
Object visitConditionalExpression(ConditionalExpression node) {
Expression conditionExpression = node.condition;
- ValidResult result = getConstantBooleanValue(conditionExpression);
- if (result != null) {
- if (identical(result, ValidResult.RESULT_TRUE)) {
- _errorReporter.reportError2(HintCode.DEAD_CODE, node.elseExpression, []);
- safelyVisit(node.thenExpression);
- return null;
- } else {
- _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenExpression, []);
- safelyVisit(node.elseExpression);
- return null;
+ safelyVisit(conditionExpression);
+ if (!isDebugConstant(conditionExpression)) {
+ ValidResult result = getConstantBooleanValue(conditionExpression);
+ if (result != null) {
+ if (identical(result, ValidResult.RESULT_TRUE)) {
+ _errorReporter.reportError2(HintCode.DEAD_CODE, node.elseExpression, []);
+ safelyVisit(node.thenExpression);
+ return null;
+ } else {
+ _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenExpression, []);
+ safelyVisit(node.elseExpression);
+ return null;
+ }
}
}
return super.visitConditionalExpression(node);
}
Object visitIfStatement(IfStatement node) {
Expression conditionExpression = node.condition;
- ValidResult result = getConstantBooleanValue(conditionExpression);
- if (result != null) {
- if (identical(result, ValidResult.RESULT_TRUE)) {
- Statement elseStatement = node.elseStatement;
- if (elseStatement != null) {
- _errorReporter.reportError2(HintCode.DEAD_CODE, elseStatement, []);
- safelyVisit(node.thenStatement);
+ safelyVisit(conditionExpression);
+ if (!isDebugConstant(conditionExpression)) {
+ ValidResult result = getConstantBooleanValue(conditionExpression);
+ if (result != null) {
+ if (identical(result, ValidResult.RESULT_TRUE)) {
+ Statement elseStatement = node.elseStatement;
+ if (elseStatement != null) {
+ _errorReporter.reportError2(HintCode.DEAD_CODE, elseStatement, []);
+ safelyVisit(node.thenStatement);
+ return null;
+ }
+ } else {
+ _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenStatement, []);
+ safelyVisit(node.elseStatement);
return null;
}
- } else {
- _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenStatement, []);
- safelyVisit(node.elseStatement);
- return null;
}
}
return super.visitIfStatement(node);
@@ -1410,11 +1772,13 @@
Object visitWhileStatement(WhileStatement node) {
Expression conditionExpression = node.condition;
safelyVisit(conditionExpression);
- ValidResult result = getConstantBooleanValue(conditionExpression);
- if (result != null) {
- if (identical(result, ValidResult.RESULT_FALSE)) {
- _errorReporter.reportError2(HintCode.DEAD_CODE, node.body, []);
- return null;
+ if (!isDebugConstant(conditionExpression)) {
+ ValidResult result = getConstantBooleanValue(conditionExpression);
+ if (result != null) {
+ if (identical(result, ValidResult.RESULT_FALSE)) {
+ _errorReporter.reportError2(HintCode.DEAD_CODE, node.body, []);
+ return null;
+ }
}
}
safelyVisit(node.body);
@@ -1438,15 +1802,31 @@
} else {
return ValidResult.RESULT_FALSE;
}
- } else {
- EvaluationResultImpl result = expression.accept(new ConstantVisitor());
- if (identical(result, ValidResult.RESULT_TRUE)) {
- return ValidResult.RESULT_TRUE;
- } else if (identical(result, ValidResult.RESULT_FALSE)) {
- return ValidResult.RESULT_FALSE;
- }
- return null;
}
+ return null;
+ }
+
+ /**
+ * Return `true` if and only if the passed expression is resolved to a constant variable.
+ *
+ * @param expression some conditional expression
+ * @return `true` if and only if the passed expression is resolved to a constant variable
+ */
+ bool isDebugConstant(Expression expression) {
+ Element element = null;
+ if (expression is Identifier) {
+ Identifier identifier = expression as Identifier;
+ element = identifier.staticElement;
+ } else if (expression is PropertyAccess) {
+ PropertyAccess propertyAccess = expression as PropertyAccess;
+ element = propertyAccess.propertyName.staticElement;
+ }
+ if (element is PropertyAccessorElement) {
+ PropertyAccessorElement pae = element as PropertyAccessorElement;
+ PropertyInducingElement variable = pae.variable;
+ return variable != null && variable.isConst;
+ }
+ return false;
}
/**
@@ -1472,15 +1852,17 @@
AnalysisContext _context;
AnalysisErrorListener _errorListener;
ImportsVerifier _importsVerifier;
- DeadCodeVerifier _deadCodeVerifier;
+ bool _enableDart2JSHints = false;
HintGenerator(List<CompilationUnit> compilationUnits, AnalysisContext context, AnalysisErrorListener errorListener) {
this._compilationUnits = compilationUnits;
this._context = context;
this._errorListener = errorListener;
LibraryElement library = compilationUnits[0].element.library;
_importsVerifier = new ImportsVerifier(library);
+ _enableDart2JSHints = context.analysisOptions.dart2jsHint;
}
void generateForLibrary() {
+ TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.hints.start();
for (int i = 0; i < _compilationUnits.length; i++) {
CompilationUnitElement element = _compilationUnits[i].element;
if (element != null) {
@@ -1493,13 +1875,19 @@
}
}
}
- _importsVerifier.generateUnusedImportHints(new ErrorReporter(_errorListener, _compilationUnits[0].element.source));
+ ErrorReporter definingCompilationUnitErrorReporter = new ErrorReporter(_errorListener, _compilationUnits[0].element.source);
+ _importsVerifier.generateDuplicateImportHints(definingCompilationUnitErrorReporter);
+ _importsVerifier.generateUnusedImportHints(definingCompilationUnitErrorReporter);
+ timeCounter.stop();
}
void generateForCompilationUnit(CompilationUnit unit, Source source) {
ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
_importsVerifier.visitCompilationUnit(unit);
- _deadCodeVerifier = new DeadCodeVerifier(errorReporter);
- _deadCodeVerifier.visitCompilationUnit(unit);
+ new DeadCodeVerifier(errorReporter).visitCompilationUnit(unit);
+ if (_enableDart2JSHints) {
+ new Dart2JSVerifier(errorReporter).visitCompilationUnit(unit);
+ }
+ new BestPracticesVerifier(errorReporter).visitCompilationUnit(unit);
}
}
/**
@@ -1538,6 +1926,12 @@
List<ImportDirective> _unusedImports;
/**
+ * After the list of [unusedImports] has been computed, this list is a proper subset of the
+ * unused imports that are listed more than once.
+ */
+ List<ImportDirective> _duplicateImports;
+
+ /**
* This is a map between the set of [LibraryElement]s that the current library imports, and
* a list of [ImportDirective]s that imports the library. In cases where the current library
* imports a library with a single directive (such as `import lib1.dart;`), the library
@@ -1574,12 +1968,27 @@
ImportsVerifier(LibraryElement library) {
this._currentLibrary = library;
this._unusedImports = new List<ImportDirective>();
+ this._duplicateImports = new List<ImportDirective>();
this._libraryMap = new Map<LibraryElement, List<ImportDirective>>();
this._namespaceMap = new Map<ImportDirective, Namespace>();
this._prefixElementMap = new Map<PrefixElement, ImportDirective>();
}
/**
+ * Any time after the defining compilation unit has been visited by this visitor, this method can
+ * be called to report an [HintCode#DUPLICATE_IMPORT] hint for each of the import directives
+ * in the [duplicateImports] list.
+ *
+ * @param errorReporter the error reporter to report the set of [HintCode#DUPLICATE_IMPORT]
+ * hints to
+ */
+ void generateDuplicateImportHints(ErrorReporter errorReporter) {
+ for (ImportDirective duplicateImport in _duplicateImports) {
+ errorReporter.reportError2(HintCode.DUPLICATE_IMPORT, duplicateImport.uri, []);
+ }
+ }
+
+ /**
* After all of the compilation units have been visited by this visitor, this method can be called
* to report an [HintCode#UNUSED_IMPORT] hint for each of the import directives in the
* [unusedImports] list.
@@ -1589,6 +1998,14 @@
*/
void generateUnusedImportHints(ErrorReporter errorReporter) {
for (ImportDirective unusedImport in _unusedImports) {
+ Element element = unusedImport.element;
+ if (element is ImportElement) {
+ ImportElement importElement = element as ImportElement;
+ LibraryElement libraryElement = importElement.importedLibrary;
+ if (libraryElement != null && libraryElement.isDartCore) {
+ continue;
+ }
+ }
errorReporter.reportError2(HintCode.UNUSED_IMPORT, unusedImport.uri, []);
}
}
@@ -1620,6 +2037,22 @@
if (_unusedImports.isEmpty) {
return null;
}
+ if (_unusedImports.length > 1) {
+ List<ImportDirective> importDirectiveArray = new List.from(_unusedImports);
+ importDirectiveArray.sort(ImportDirective.COMPARATOR);
+ ImportDirective currentDirective = importDirectiveArray[0];
+ for (int i = 1; i < importDirectiveArray.length; i++) {
+ ImportDirective nextDirective = importDirectiveArray[i];
+ if (ImportDirective.COMPARATOR(currentDirective, nextDirective) == 0) {
+ if (currentDirective.offset < nextDirective.offset) {
+ _duplicateImports.add(nextDirective);
+ } else {
+ _duplicateImports.add(currentDirective);
+ }
+ }
+ currentDirective = nextDirective;
+ }
+ }
return super.visitCompilationUnit(node);
}
Object visitExportDirective(ExportDirective node) => null;
@@ -2179,9 +2612,9 @@
Object visitTypeParameter(TypeParameter node) {
SimpleIdentifier parameterName = node.name;
if (_enclosingClass != null) {
- find3(_enclosingClass.typeVariables, parameterName);
+ find3(_enclosingClass.typeParameters, parameterName);
} else if (_enclosingAlias != null) {
- find3(_enclosingAlias.typeVariables, parameterName);
+ find3(_enclosingAlias.typeParameters, parameterName);
}
return super.visitTypeParameter(node);
}
@@ -2214,26 +2647,6 @@
}
/**
- * Append the value of the given string literal to the given string builder.
- *
- * @param builder the builder to which the string's value is to be appended
- * @param literal the string literal whose value is to be appended to the builder
- * @throws IllegalArgumentException if the string is not a constant string without any string
- * interpolation
- */
- void appendStringValue(JavaStringBuilder builder, StringLiteral literal) {
- if (literal is SimpleStringLiteral) {
- builder.append(((literal as SimpleStringLiteral)).value);
- } else if (literal is AdjacentStrings) {
- for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings) {
- appendStringValue(builder, stringLiteral);
- }
- } else {
- throw new IllegalArgumentException();
- }
- }
-
- /**
* Return the element for the part with the given source, or `null` if there is no element
* for the given source.
*
@@ -2384,13 +2797,7 @@
if (literal is StringInterpolation) {
return null;
}
- JavaStringBuilder builder = new JavaStringBuilder();
- try {
- appendStringValue(builder, literal);
- } on IllegalArgumentException catch (exception) {
- return null;
- }
- return builder.toString().trim();
+ return literal.stringValue;
}
}
/**
@@ -3042,7 +3449,6 @@
name.staticElement = element;
}
node.staticElement = element;
- node.element = element;
ArgumentList argumentList = node.argumentList;
List<ParameterElement> parameters = resolveArgumentsToParameters(false, argumentList, element);
if (parameters != null) {
@@ -3117,7 +3523,6 @@
name.staticElement = element;
}
node.staticElement = element;
- node.element = element;
ArgumentList argumentList = node.argumentList;
List<ParameterElement> parameters = resolveArgumentsToParameters(isInConstConstructor, argumentList, element);
if (parameters != null) {
@@ -3134,9 +3539,9 @@
Object visitTypeParameter(TypeParameter node) {
TypeName bound = node.bound;
if (bound != null) {
- TypeVariableElementImpl variable = node.name.staticElement as TypeVariableElementImpl;
- if (variable != null) {
- variable.bound = bound.type;
+ TypeParameterElementImpl typeParameter = node.name.staticElement as TypeParameterElementImpl;
+ if (typeParameter != null) {
+ typeParameter.bound = bound.type;
}
}
setMetadata(node.element, node);
@@ -3331,7 +3736,7 @@
if (element == null) {
element = importedElement;
} else {
- element = new MultiplyDefinedElementImpl(definingLibrary.context, element, importedElement);
+ element = new MultiplyDefinedElementImpl.con1(definingLibrary.context, element, importedElement);
}
}
}
@@ -3374,7 +3779,7 @@
* @return the type of the given expression
*/
Type2 getPropagatedType(Expression expression) {
- Type2 propagatedType = resolveTypeVariable(expression.propagatedType);
+ Type2 propagatedType = resolveTypeParameter(expression.propagatedType);
if (propagatedType is FunctionType) {
propagatedType = _resolver.typeProvider.functionType;
}
@@ -3391,7 +3796,7 @@
if (expression is NullLiteral) {
return _resolver.typeProvider.objectType;
}
- Type2 staticType = resolveTypeVariable(expression.staticType);
+ Type2 staticType = resolveTypeParameter(expression.staticType);
if (staticType is FunctionType) {
staticType = _resolver.typeProvider.functionType;
}
@@ -3488,7 +3893,7 @@
* @return the element representing the getter that was found
*/
PropertyAccessorElement lookUpGetter(Expression target, Type2 type, String getterName) {
- type = resolveTypeVariable(type);
+ type = resolveTypeParameter(type);
if (type is InterfaceType) {
InterfaceType interfaceType = type as InterfaceType;
PropertyAccessorElement accessor;
@@ -3558,7 +3963,7 @@
* @return the element representing the method or getter that was found
*/
ExecutableElement lookupGetterOrMethod(Type2 type, String memberName) {
- type = resolveTypeVariable(type);
+ type = resolveTypeParameter(type);
if (type is InterfaceType) {
InterfaceType interfaceType = type as InterfaceType;
ExecutableElement member = interfaceType.lookUpMethod(memberName, _resolver.definingLibrary);
@@ -3671,7 +4076,7 @@
* @return the element representing the method that was found
*/
MethodElement lookUpMethod(Expression target, Type2 type, String methodName) {
- type = resolveTypeVariable(type);
+ type = resolveTypeParameter(type);
if (type is InterfaceType) {
InterfaceType interfaceType = type as InterfaceType;
MethodElement method;
@@ -3741,7 +4146,7 @@
* @return the element representing the setter that was found
*/
PropertyAccessorElement lookUpSetter(Expression target, Type2 type, String setterName) {
- type = resolveTypeVariable(type);
+ type = resolveTypeParameter(type);
if (type is InterfaceType) {
InterfaceType interfaceType = type as InterfaceType;
PropertyAccessorElement accessor;
@@ -4167,16 +4572,16 @@
}
/**
- * If the given type is a type variable, resolve it to the type that should be used when looking
+ * If the given type is a type parameter, resolve it to the type that should be used when looking
* up members. Otherwise, return the original type.
*
- * @param type the type that is to be resolved if it is a type variable
- * @return the type that should be used in place of the argument if it is a type variable, or the
- * original argument if it isn't a type variable
+ * @param type the type that is to be resolved if it is a type parameter
+ * @return the type that should be used in place of the argument if it is a type parameter, or the
+ * original argument if it isn't a type parameter
*/
- Type2 resolveTypeVariable(Type2 type) {
- if (type is TypeVariableType) {
- Type2 bound = ((type as TypeVariableType)).element.bound;
+ Type2 resolveTypeParameter(Type2 type) {
+ if (type is TypeParameterType) {
+ Type2 bound = ((type as TypeParameterType)).element.bound;
if (bound == null) {
return _resolver.typeProvider.objectType;
}
@@ -5262,12 +5667,6 @@
InternalAnalysisContext analysisContext;
/**
- * A flag indicating whether analysis is to generate hint results (e.g. type inference based
- * information and pub best practices).
- */
- bool _enableHints = false;
-
- /**
* The listener to which analysis errors will be reported, this error listener is either
* references [recordingErrorListener], or it unions the passed
* [AnalysisErrorListener] with the [recordingErrorListener].
@@ -5308,7 +5707,6 @@
this.analysisContext = analysisContext;
this.errorListener = new RecordingErrorListener();
_coreLibrarySource = analysisContext.sourceFactory.forUri(DartSdk.DART_CORE);
- _enableHints = analysisContext.analysisOptions.hint;
}
/**
@@ -5598,12 +5996,14 @@
* @throws AnalysisException if any of the type hierarchies could not be resolved
*/
void buildTypeHierarchies() {
+ TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
for (Library library in resolvedLibraries) {
for (Source source in library.compilationUnitSources) {
TypeResolverVisitor visitor = new TypeResolverVisitor.con1(library, source, _typeProvider);
library.getAST(source).accept(visitor);
}
}
+ timeCounter.stop();
}
/**
@@ -5816,6 +6216,7 @@
* Compute a value for all of the constants in the libraries being analyzed.
*/
void performConstantEvaluation() {
+ TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
ConstantValueComputer computer = new ConstantValueComputer();
for (Library library in resolvedLibraries) {
for (Source source in library.compilationUnitSources) {
@@ -5830,6 +6231,7 @@
}
}
computer.computeValues();
+ timeCounter.stop();
}
/**
@@ -5852,6 +6254,7 @@
* the library cannot be analyzed
*/
void resolveReferencesAndTypes2(Library library) {
+ TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
for (Source source in library.compilationUnitSources) {
ResolverVisitor visitor = new ResolverVisitor.con1(library, source, _typeProvider);
library.getAST(source).accept(visitor);
@@ -5861,6 +6264,7 @@
}
}
}
+ timeCounter.stop();
}
/**
@@ -5906,6 +6310,7 @@
* the library cannot be analyzed
*/
void runAdditionalAnalyses2(Library library) {
+ TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.errors.start();
for (Source source in library.compilationUnitSources) {
ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
CompilationUnit unit = library.getAST(source);
@@ -5914,10 +6319,7 @@
ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.libraryElement, _typeProvider, library.inheritanceManager);
unit.accept(errorVerifier);
}
- if (_enableHints) {
- HintGenerator hintGenerator = new HintGenerator(library.compilationUnits, analysisContext, errorListener);
- hintGenerator.generateForLibrary();
- }
+ timeCounter.stop();
}
}
/**
@@ -6569,7 +6971,9 @@
Expression iterator = node.iterator;
safelyVisit(iterator);
DeclaredIdentifier loopVariable = node.loopVariable;
+ SimpleIdentifier identifier = node.identifier;
safelyVisit(loopVariable);
+ safelyVisit(identifier);
Statement body = node.body;
if (body != null) {
try {
@@ -6581,6 +6985,13 @@
override2(loopElement, iteratorElementType);
recordPropagatedType(loopVariable.identifier, iteratorElementType);
}
+ } else if (identifier != null && iterator != null) {
+ Element identifierElement = identifier.staticElement;
+ if (identifierElement is VariableElement) {
+ Type2 iteratorElementType = getIteratorElementType(iterator);
+ override2(identifierElement as VariableElement, iteratorElementType);
+ recordPropagatedType(identifier, iteratorElementType);
+ }
}
visitStatementInScope(body);
} finally {
@@ -7186,6 +7597,7 @@
* @param node the statement to be visited
*/
void visitForEachStatementInScope(ForEachStatement node) {
+ safelyVisit(node.identifier);
safelyVisit(node.iterator);
safelyVisit(node.loopVariable);
visitStatementInScope(node.body);
@@ -7752,20 +8164,17 @@
*/
Object visitInstanceCreationExpression(InstanceCreationExpression node) {
recordStaticType(node, node.constructorName.type.type);
- ConstructorElement element = node.element;
+ ConstructorElement element = node.staticElement;
if (element != null && "Element" == element.enclosingElement.name) {
- String constructorName = element.name;
- if ("tag" == constructorName) {
- LibraryElement library = element.library;
- if (isHtmlLibrary(library)) {
+ LibraryElement library = element.library;
+ if (isHtmlLibrary(library)) {
+ String constructorName = element.name;
+ if ("tag" == constructorName) {
Type2 returnType = getFirstArgumentAsType2(library, node.argumentList, _HTML_ELEMENT_TO_CLASS_MAP);
if (returnType != null) {
recordPropagatedType2(node, returnType);
}
- }
- } else {
- LibraryElement library = element.library;
- if (isHtmlLibrary(library)) {
+ } else {
Type2 returnType = getElementNameAsType(library, constructorName, _HTML_ELEMENT_TO_CLASS_MAP);
if (returnType != null) {
recordPropagatedType2(node, returnType);
@@ -8141,8 +8550,8 @@
staticType = getType(staticElement as PropertyAccessorElement, node.prefix.staticType);
} else if (staticElement is ExecutableElement) {
staticType = ((staticElement as ExecutableElement)).type;
- } else if (staticElement is TypeVariableElement) {
- staticType = ((staticElement as TypeVariableElement)).type;
+ } else if (staticElement is TypeParameterElement) {
+ staticType = ((staticElement as TypeParameterElement)).type;
} else if (staticElement is VariableElement) {
staticType = ((staticElement as VariableElement)).type;
}
@@ -8164,8 +8573,8 @@
propagatedType = getType(propagatedElement as PropertyAccessorElement, node.prefix.staticType);
} else if (propagatedElement is ExecutableElement) {
propagatedType = ((propagatedElement as ExecutableElement)).type;
- } else if (propagatedElement is TypeVariableElement) {
- propagatedType = ((propagatedElement as TypeVariableElement)).type;
+ } else if (propagatedElement is TypeParameterElement) {
+ propagatedType = ((propagatedElement as TypeParameterElement)).type;
} else if (propagatedElement is VariableElement) {
propagatedType = ((propagatedElement as VariableElement)).type;
}
@@ -8340,8 +8749,8 @@
staticType = getType(element as PropertyAccessorElement, null);
} else if (element is ExecutableElement) {
staticType = ((element as ExecutableElement)).type;
- } else if (element is TypeVariableElement) {
- staticType = ((element as TypeVariableElement)).type;
+ } else if (element is TypeParameterElement) {
+ staticType = ((element as TypeParameterElement)).type;
} else if (element is VariableElement) {
staticType = ((element as VariableElement)).type;
} else if (element is PrefixElement) {
@@ -8466,7 +8875,7 @@
}
if (body is BlockFunctionBody) {
List<Type2> result = [null];
- body.accept(new GeneralizingASTVisitor_8(result));
+ body.accept(new GeneralizingASTVisitor_7(result));
return result[0];
}
return null;
@@ -8685,13 +9094,13 @@
return _dynamicType;
}
Type2 returnType = functionType.returnType;
- if (returnType is TypeVariableType && context is InterfaceType) {
+ if (returnType is TypeParameterType && context is InterfaceType) {
InterfaceType interfaceTypeContext = context as InterfaceType;
- List<TypeVariableElement> parameterElements = interfaceTypeContext.element != null ? interfaceTypeContext.element.typeVariables : null;
- if (parameterElements != null) {
- for (int i = 0; i < parameterElements.length; i++) {
- TypeVariableElement varElt = parameterElements[i];
- if (returnType.name == varElt.name) {
+ List<TypeParameterElement> typeParameterElements = interfaceTypeContext.element != null ? interfaceTypeContext.element.typeParameters : null;
+ if (typeParameterElements != null) {
+ for (int i = 0; i < typeParameterElements.length; i++) {
+ TypeParameterElement typeParameterElement = typeParameterElements[i];
+ if (returnType.name == typeParameterElement.name) {
return interfaceTypeContext.typeArguments[i];
}
}
@@ -8809,16 +9218,18 @@
if (identical(operator, sc.TokenType.AMPERSAND_AMPERSAND) || identical(operator, sc.TokenType.BAR_BAR) || identical(operator, sc.TokenType.EQ_EQ) || identical(operator, sc.TokenType.BANG_EQ)) {
return _typeProvider.boolType;
}
- if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.TokenType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator, sc.TokenType.STAR)) {
- Type2 doubleType = _typeProvider.doubleType;
- if (identical(getStaticType(node.leftOperand), _typeProvider.intType) && identical(getStaticType(node.rightOperand), doubleType)) {
- return doubleType;
+ Type2 intType = _typeProvider.intType;
+ if (getStaticType(node.leftOperand) == intType) {
+ if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.TokenType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator, sc.TokenType.STAR)) {
+ Type2 doubleType = _typeProvider.doubleType;
+ if (getStaticType(node.rightOperand) == doubleType) {
+ return doubleType;
+ }
}
- }
- if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.TokenType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator, sc.TokenType.STAR) || identical(operator, sc.TokenType.TILDE_SLASH)) {
- Type2 intType = _typeProvider.intType;
- if (identical(getStaticType(node.leftOperand), intType) && identical(getStaticType(node.rightOperand), intType)) {
- staticType = intType;
+ if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.TokenType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator, sc.TokenType.STAR) || identical(operator, sc.TokenType.TILDE_SLASH)) {
+ if (getStaticType(node.rightOperand) == intType) {
+ staticType = intType;
+ }
}
}
return staticType;
@@ -8826,9 +9237,9 @@
get thisType_J2DAccessor => _thisType;
set thisType_J2DAccessor(__v) => _thisType = __v;
}
-class GeneralizingASTVisitor_8 extends GeneralizingASTVisitor<Object> {
+class GeneralizingASTVisitor_7 extends GeneralizingASTVisitor<Object> {
List<Type2> result;
- GeneralizingASTVisitor_8(this.result) : super();
+ GeneralizingASTVisitor_7(this.result) : super();
Object visitExpression(Expression node) => null;
Object visitReturnStatement(ReturnStatement node) {
Type2 type;
@@ -9626,9 +10037,9 @@
} else if (element is FunctionTypeAliasElement) {
setElement(typeName, element);
type = ((element as FunctionTypeAliasElement)).type;
- } else if (element is TypeVariableElement) {
+ } else if (element is TypeParameterElement) {
setElement(typeName, element);
- type = ((element as TypeVariableElement)).type;
+ type = ((element as TypeParameterElement)).type;
if (argumentList != null) {
}
} else if (element is MultiplyDefinedElement) {
@@ -10111,7 +10522,7 @@
FunctionTypeImpl type = new FunctionTypeImpl.con2(aliasElement);
ClassElement definingClass = element.getAncestor(ClassElement);
if (definingClass != null) {
- aliasElement.shareTypeVariables(definingClass.typeVariables);
+ aliasElement.shareTypeParameters(definingClass.typeParameters);
type.typeArguments = definingClass.type.typeArguments;
} else {
FunctionTypeAliasElement alias = element.getAncestor(FunctionTypeAliasElement);
@@ -10119,10 +10530,10 @@
alias = alias.getAncestor(FunctionTypeAliasElement);
}
if (alias != null) {
- aliasElement.typeVariables = alias.typeVariables;
+ aliasElement.typeParameters = alias.typeParameters;
type.typeArguments = alias.type.typeArguments;
} else {
- type.typeArguments = TypeVariableTypeImpl.EMPTY_ARRAY;
+ type.typeArguments = TypeImpl.EMPTY_ARRAY;
}
}
element.type = type;
@@ -10177,8 +10588,8 @@
*/
void defineTypeParameters(ClassElement typeElement) {
Scope parameterScope = enclosingScope;
- for (TypeVariableElement parameter in typeElement.typeVariables) {
- parameterScope.define(parameter);
+ for (TypeParameterElement typeParameter in typeElement.typeParameters) {
+ parameterScope.define(typeParameter);
}
}
}
@@ -10290,7 +10701,7 @@
* @param typeElement the element representing the type alias represented by this scope
*/
FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) {
- defineTypeVariables(typeElement);
+ defineTypeParameters(typeElement);
defineParameters(typeElement);
}
@@ -10306,14 +10717,14 @@
}
/**
- * Define the type variables for the function type alias.
+ * Define the type parameters for the function type alias.
*
* @param typeElement the element representing the type represented by this scope
*/
- void defineTypeVariables(FunctionTypeAliasElement typeElement) {
- Scope typeVariableScope = enclosingScope;
- for (TypeVariableElement typeVariable in typeElement.typeVariables) {
- typeVariableScope.define(typeVariable);
+ void defineTypeParameters(FunctionTypeAliasElement typeElement) {
+ Scope typeParameterScope = enclosingScope;
+ for (TypeParameterElement typeParameter in typeElement.typeParameters) {
+ typeParameterScope.define(typeParameter);
}
}
}
@@ -10453,12 +10864,15 @@
if (element != null) {
if (foundElement == null) {
foundElement = element;
- } else {
- foundElement = new MultiplyDefinedElementImpl(_definingLibrary.context, foundElement, element);
+ } else if (foundElement != element) {
+ foundElement = new MultiplyDefinedElementImpl.con1(_definingLibrary.context, foundElement, element);
}
}
}
if (foundElement is MultiplyDefinedElementImpl) {
+ foundElement = removeSdkElements(foundElement as MultiplyDefinedElementImpl);
+ }
+ if (foundElement is MultiplyDefinedElementImpl) {
String foundEltName = foundElement.displayName;
String libName1 = "", libName2 = "";
List<Element> conflictingMembers = ((foundElement as MultiplyDefinedElementImpl)).conflictingElements;
@@ -10492,6 +10906,32 @@
_importedNamespaces.add(builder.createImportNamespace(element));
}
}
+
+ /**
+ * Given a collection of elements that a single name could all be mapped to, remove from the list
+ * all of the names defined in the SDK. Return the element(s) that remain.
+ *
+ * @param foundElement the element encapsulating the collection of elements
+ * @return all of the elements that are not defined in the SDK
+ */
+ Element removeSdkElements(MultiplyDefinedElementImpl foundElement) {
+ List<Element> conflictingMembers = foundElement.conflictingElements;
+ int length = conflictingMembers.length;
+ int to = 0;
+ for (Element member in conflictingMembers) {
+ if (!member.library.isInSdk) {
+ conflictingMembers[to++] = member;
+ }
+ }
+ if (to == length) {
+ return foundElement;
+ } else if (to == 1) {
+ return conflictingMembers[0];
+ }
+ List<Element> remaining = new List<Element>(to);
+ JavaSystem.arraycopy(conflictingMembers, 0, remaining, 0, to);
+ return new MultiplyDefinedElementImpl.con2(_definingLibrary.context, remaining);
+ }
}
/**
* Instances of the class `LibraryScope` implement a scope containing all of the names defined
@@ -11156,16 +11596,6 @@
}
/**
- * Return `true` if the given value is the result of evaluating an expression whose value is
- * a valid key in a const map literal. Keys in const map literals must be either a string, number,
- * boolean, list, map, or null.
- *
- * @param value
- * @return `true` if the given value is a valid key in a const map literal
- */
- bool isValidConstMapKey(Object value) => true;
-
- /**
* If the given result represents one or more errors, report those errors. Except for special
* cases, use the given error code rather than the one reported in the error.
*
@@ -11261,7 +11691,7 @@
* @param expression the expression to validate
*/
void validateInitializerExpression(List<ParameterElement> parameterElements, Expression expression) {
- EvaluationResultImpl result = expression.accept(new ConstantVisitor_12(this, parameterElements));
+ EvaluationResultImpl result = expression.accept(new ConstantVisitor_11(this, parameterElements));
reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER);
}
@@ -11306,10 +11736,10 @@
}
}
}
-class ConstantVisitor_12 extends ConstantVisitor {
+class ConstantVisitor_11 extends ConstantVisitor {
final ConstantVerifier ConstantVerifier_this;
List<ParameterElement> parameterElements;
- ConstantVisitor_12(this.ConstantVerifier_this, this.parameterElements) : super();
+ ConstantVisitor_11(this.ConstantVerifier_this, this.parameterElements) : super();
EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) {
Element element = node.staticElement;
for (ParameterElement parameterElement in parameterElements) {
@@ -11985,7 +12415,7 @@
return super.visitTypeName(node);
}
Object visitTypeParameter(TypeParameter node) {
- checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME);
+ checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
return super.visitTypeParameter(node);
}
Object visitVariableDeclaration(VariableDeclaration node) {
@@ -12094,7 +12524,10 @@
for (MapEntry<FieldElement, INIT_STATE> entry in getMapEntrySet(fieldElementsMap)) {
if (identical(entry.getValue(), INIT_STATE.NOT_INIT)) {
FieldElement fieldElement = entry.getKey();
- if (fieldElement.isFinal || fieldElement.isConst) {
+ if (fieldElement.isConst) {
+ _errorReporter.reportError2(CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
+ foundError = true;
+ } else if (fieldElement.isFinal) {
_errorReporter.reportError2(StaticWarningCode.FINAL_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
foundError = true;
}
@@ -12178,7 +12611,7 @@
List<Type2> overriddenPositionalPT = overriddenFT.optionalParameterTypes;
Map<String, Type2> overridingNamedPT = overridingFT.namedParameterTypes;
Map<String, Type2> overriddenNamedPT = overriddenFT.namedParameterTypes;
- if (overridingNormalPT.length != overriddenNormalPT.length) {
+ if (overridingNormalPT.length > overriddenNormalPT.length) {
_errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
overriddenNormalPT.length,
overriddenExecutable.enclosingElement.displayName]);
@@ -12710,11 +13143,11 @@
* @param errorCode if the passed identifier is a keyword then this error code is created on the
* identifier, the error code will be one of
* [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME],
- * [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME] or
+ * [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME] or
* [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]
* @return `true` if and only if an error code is generated on the passed node
* @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME
- * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME
+ * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME
* @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME
*/
bool checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode errorCode) {
@@ -13240,7 +13673,7 @@
if (name == null) {
return false;
}
- if (name.staticElement is TypeVariableElement) {
+ if (name.staticElement is TypeParameterElement) {
_errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name, []);
}
TypeArgumentList typeArguments = typeName.typeArguments;
@@ -13575,7 +14008,8 @@
*
* @param node the class declaration to test
* @return `true` if and only if an error code is generated on the passed node
- * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED
+ * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED
+ * @see StaticWarningCode#FINAL_NOT_INITIALIZED
*/
bool checkForFinalNotInitialized(ClassDeclaration node) {
NodeList<ClassMember> classMembers = node.members;
@@ -13603,18 +14037,23 @@
*
* @param node the class declaration to test
* @return `true` if and only if an error code is generated on the passed node
- * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED
+ * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED
+ * @see StaticWarningCode#FINAL_NOT_INITIALIZED
*/
bool checkForFinalNotInitialized2(VariableDeclarationList node) {
if (_isInNativeClass) {
return false;
}
bool foundError = false;
- if (!node.isSynthetic && (node.isConst || node.isFinal)) {
+ if (!node.isSynthetic) {
NodeList<VariableDeclaration> variables = node.variables;
for (VariableDeclaration variable in variables) {
if (variable.initializer == null) {
- _errorReporter.reportError2(StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [variable.name.name]);
+ if (node.isConst) {
+ _errorReporter.reportError2(CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, [variable.name.name]);
+ } else if (node.isFinal) {
+ _errorReporter.reportError2(StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [variable.name.name]);
+ }
foundError = true;
}
}
@@ -13961,7 +14400,7 @@
bool checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> arguments, ErrorCode errorCode) {
bool foundError = false;
for (TypeName typeName in arguments) {
- if (typeName.type is TypeVariableType) {
+ if (typeName.type is TypeParameterType) {
_errorReporter.reportError2(errorCode, typeName, [typeName.name]);
foundError = true;
}
@@ -14924,14 +15363,14 @@
if (node.typeArguments == null) {
return false;
}
- List<TypeVariableElement> boundingElts = null;
+ List<TypeParameterElement> boundingElts = null;
Type2 type = node.type;
if (type == null) {
return false;
}
Element element = type.element;
if (element is ClassElement) {
- boundingElts = ((element as ClassElement)).typeVariables;
+ boundingElts = ((element as ClassElement)).typeParameters;
} else {
return false;
}
@@ -14969,7 +15408,7 @@
bool checkForTypeParameterReferencedByStatic(TypeName node) {
if (_isInStaticMethod || _isInStaticVariableDeclaration) {
Type2 type = node.type;
- if (type is TypeVariableType) {
+ if (type is TypeParameterType) {
_errorReporter.reportError2(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node, []);
return true;
}
@@ -15038,7 +15477,7 @@
*/
bool checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name2) {
Element element = name2.staticElement;
- if (element == null || element is TypeVariableElement) {
+ if (element == null || element is TypeParameterElement) {
return false;
}
Element enclosingElement = element.enclosingElement;
@@ -15227,7 +15666,7 @@
/**
* @return <code>true</code> if given [Element] has direct or indirect reference to itself
- * form anywhere except [ClassElement] or type variable bounds.
+ * from anywhere except [ClassElement] or type parameter bounds.
*/
bool hasTypedefSelfReference(Element target) {
Set<Element> checked = new Set<Element>();
@@ -15253,7 +15692,7 @@
break;
}
}
- current.accept(new GeneralizingElementVisitor_13(target, toCheck));
+ current.accept(new GeneralizingElementVisitor_12(target, toCheck));
javaSetAdd(checked, current);
}
}
@@ -15432,10 +15871,10 @@
INIT_IN_INITIALIZERS];
INIT_STATE(String name, int ordinal) : super(name, ordinal);
}
-class GeneralizingElementVisitor_13 extends GeneralizingElementVisitor<Object> {
+class GeneralizingElementVisitor_12 extends GeneralizingElementVisitor<Object> {
Element target;
List<Element> toCheck;
- GeneralizingElementVisitor_13(this.target, this.toCheck) : super();
+ GeneralizingElementVisitor_12(this.target, this.toCheck) : super();
bool _inClass = false;
Object visitClassElement(ClassElement element) {
addTypeToCheck(element.supertype);
@@ -15464,7 +15903,7 @@
addTypeToCheck(element.type);
return super.visitParameterElement(element);
}
- Object visitTypeVariableElement(TypeVariableElement element) => null;
+ Object visitTypeParameterElement(TypeParameterElement element) => null;
Object visitVariableElement(VariableElement element) {
addTypeToCheck(element.type);
return super.visitVariableElement(element);
diff --git a/pkg/analyzer_experimental/lib/src/generated/scanner.dart b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
index 677d4fb..67ffec0 100644
--- a/pkg/analyzer_experimental/lib/src/generated/scanner.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
@@ -920,9 +920,6 @@
appendToken2(TokenType.PERIOD, offset - 1);
return bigSwitch(next);
}
- if (next == 0x64 || next == 0x44) {
- next = advance();
- }
appendStringToken(TokenType.DOUBLE, getString(start, next < 0 ? 0 : -1));
return next;
}
@@ -1173,9 +1170,6 @@
continue;
} else if (next == 0x2E) {
return tokenizeFractionPart(advance(), start);
- } else if (next == 0x64 || next == 0x44) {
- appendStringToken(TokenType.DOUBLE, getString(start, 0));
- return advance();
} else if (next == 0x65 || next == 0x45) {
return tokenizeFractionPart(next, start);
} else {
diff --git a/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart b/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart
index a4e79e1..7abbe9a 100644
--- a/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart
@@ -199,11 +199,7 @@
this.directory = sdkDirectory.getAbsoluteFile();
initializeSdk();
initializeLibraryMap();
- if (AnalysisEngine.instance.useExperimentalContext) {
- _analysisContext = new AnalysisContextImpl2();
- } else {
- _analysisContext = new AnalysisContextImpl();
- }
+ _analysisContext = new AnalysisContextImpl();
_analysisContext.sourceFactory = new SourceFactory.con2([new DartUriResolver(this)]);
List<String> uris = this.uris;
ChangeSet changeSet = new ChangeSet();
@@ -224,7 +220,7 @@
this.directory = sdkDirectory.getAbsoluteFile();
initializeSdk();
initializeLibraryMap();
- _analysisContext = new AnalysisContextImpl2();
+ _analysisContext = new AnalysisContextImpl();
_analysisContext.sourceFactory = new SourceFactory.con2([new DartUriResolver(this)]);
List<String> uris = this.uris;
ChangeSet changeSet = new ChangeSet();
@@ -469,7 +465,7 @@
*/
LibraryMap readFrom(JavaFile librariesFile, String libraryFileContents) {
List<bool> foundError = [false];
- AnalysisErrorListener errorListener = new AnalysisErrorListener_9(foundError);
+ AnalysisErrorListener errorListener = new AnalysisErrorListener_8(foundError);
Source source = new FileBasedSource.con2(null, librariesFile, UriKind.FILE_URI);
StringScanner scanner = new StringScanner(source, libraryFileContents, errorListener);
Parser parser = new Parser(source, errorListener);
@@ -561,9 +557,9 @@
return null;
}
}
-class AnalysisErrorListener_9 implements AnalysisErrorListener {
+class AnalysisErrorListener_8 implements AnalysisErrorListener {
List<bool> foundError;
- AnalysisErrorListener_9(this.foundError);
+ AnalysisErrorListener_8(this.foundError);
void onError(AnalysisError error) {
foundError[0] = true;
}
diff --git a/pkg/analyzer_experimental/lib/src/generated/source.dart b/pkg/analyzer_experimental/lib/src/generated/source.dart
index 659f631..8fbc1c4 100644
--- a/pkg/analyzer_experimental/lib/src/generated/source.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/source.dart
@@ -441,24 +441,15 @@
static final UriKind FILE_URI = new UriKind('FILE_URI', 1, 0x66);
/**
+ * A 'package:' URI referencing source package itself.
+ */
+ static final UriKind PACKAGE_SELF_URI = new UriKind('PACKAGE_SELF_URI', 2, 0x73);
+
+ /**
* A 'package:' URI.
*/
- static final UriKind PACKAGE_URI = new UriKind('PACKAGE_URI', 2, 0x70);
- static final List<UriKind> values = [DART_URI, FILE_URI, PACKAGE_URI];
-
- /**
- * The single character encoding used to identify this kind of URI.
- */
- int encoding = 0;
-
- /**
- * Initialize a newly created URI kind to have the given encoding.
- *
- * @param encoding the single character encoding used to identify this kind of URI.
- */
- UriKind(String name, int ordinal, int encoding) : super(name, ordinal) {
- this.encoding = encoding;
- }
+ static final UriKind PACKAGE_URI = new UriKind('PACKAGE_URI', 3, 0x70);
+ static final List<UriKind> values = [DART_URI, FILE_URI, PACKAGE_SELF_URI, PACKAGE_URI];
/**
* Return the URI kind represented by the given encoding, or `null` if there is no kind with
@@ -473,6 +464,8 @@
return DART_URI;
} else if (encoding == 0x66) {
return FILE_URI;
+ } else if (encoding == 0x73) {
+ return PACKAGE_SELF_URI;
} else if (encoding == 0x70) {
return PACKAGE_URI;
}
@@ -480,6 +473,20 @@
}
return null;
}
+
+ /**
+ * The single character encoding used to identify this kind of URI.
+ */
+ int encoding = 0;
+
+ /**
+ * Initialize a newly created URI kind to have the given encoding.
+ *
+ * @param encoding the single character encoding used to identify this kind of URI.
+ */
+ UriKind(String name, int ordinal, int encoding) : super(name, ordinal) {
+ this.encoding = encoding;
+ }
}
/**
* A source range defines an [Element]'s source coordinates relative to its [Source].
diff --git a/pkg/analyzer_experimental/lib/src/generated/source_io.dart b/pkg/analyzer_experimental/lib/src/generated/source_io.dart
index 76bfcd2..8c11927 100644
--- a/pkg/analyzer_experimental/lib/src/generated/source_io.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/source_io.dart
@@ -66,14 +66,12 @@
bool operator ==(Object object) => object != null && this.runtimeType == object.runtimeType && file == ((object as FileBasedSource)).file;
bool exists() => _contentCache.getContents(this) != null || (file.exists() && !file.isDirectory());
void getContents(Source_ContentReceiver receiver) {
- {
- String contents = _contentCache.getContents(this);
- if (contents != null) {
- receiver.accept2(contents, _contentCache.getModificationStamp(this));
- return;
- }
+ String contents = _contentCache.getContents(this);
+ if (contents != null) {
+ receiver.accept2(contents, _contentCache.getModificationStamp(this));
+ return;
}
- receiver.accept2(file.readAsStringSync(), file.lastModified());
+ getContentsFromFile(receiver);
}
String get encoding {
if (_encoding == null) {
@@ -107,6 +105,22 @@
}
return file.getAbsolutePath();
}
+
+ /**
+ * Get the contents of underlying file and pass it to the given receiver. Exactly one of the
+ * methods defined on the receiver will be invoked unless an exception is thrown. The method that
+ * will be invoked depends on which of the possible representations of the contents is the most
+ * efficient. Whichever method is invoked, it will be invoked before this method returns.
+ *
+ * @param receiver the content receiver to which the content of this source will be passed
+ * @throws Exception if the contents of this source could not be accessed
+ * @see #getContents(com.google.dart.engine.source.Source.ContentReceiver)
+ */
+ void getContentsFromFile(Source_ContentReceiver receiver) {
+ {
+ }
+ receiver.accept2(file.readAsStringSync(), file.lastModified());
+ }
}
/**
* Instances of the class `PackageUriResolver` resolve `package` URI's in the context of
@@ -157,7 +171,7 @@
this._packagesDirectories = packagesDirectories;
}
Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) {
- if (identical(kind, UriKind.PACKAGE_URI)) {
+ if (identical(kind, UriKind.PACKAGE_SELF_URI) || identical(kind, UriKind.PACKAGE_URI)) {
return new FileBasedSource.con2(contentCache, new JavaFile.fromUri(uri), kind);
}
return null;
@@ -188,7 +202,9 @@
for (JavaFile packagesDirectory in _packagesDirectories) {
JavaFile resolvedFile = new JavaFile.relative(packagesDirectory, path);
if (resolvedFile.exists()) {
- return new FileBasedSource.con2(contentCache, getCanonicalFile(packagesDirectory, pkgName, relPath), UriKind.PACKAGE_URI);
+ JavaFile canonicalFile = getCanonicalFile(packagesDirectory, pkgName, relPath);
+ UriKind uriKind = isSelfReference(packagesDirectory, canonicalFile) ? UriKind.PACKAGE_SELF_URI : UriKind.PACKAGE_URI;
+ return new FileBasedSource.con2(contentCache, canonicalFile, uriKind);
}
}
return new FileBasedSource.con2(contentCache, getCanonicalFile(_packagesDirectories[0], pkgName, relPath), UriKind.PACKAGE_URI);
@@ -238,6 +254,17 @@
}
return new JavaFile.relative(pkgDir, relPath.replaceAll('/', new String.fromCharCode(JavaFile.separatorChar)));
}
+
+ /**
+ * @return `true` if "file" was found in "packagesDir", and it is part of the "lib" folder
+ * of the application that contains in this "packagesDir".
+ */
+ bool isSelfReference(JavaFile packagesDir, JavaFile file) {
+ JavaFile rootDir = packagesDir.getParentFile();
+ String rootPath = rootDir.getAbsolutePath();
+ String filePath = file.getAbsolutePath();
+ return filePath.startsWith("${rootPath}/lib");
+ }
}
/**
* Instances of the class [DirectoryBasedSourceContainer] represent a source container that
diff --git a/pkg/analyzer_experimental/lib/src/generated/utilities_general.dart b/pkg/analyzer_experimental/lib/src/generated/utilities_general.dart
new file mode 100644
index 0000000..8175055
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/generated/utilities_general.dart
@@ -0,0 +1,34 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+library engine.utilities.general;
+import 'java_core.dart';
+/**
+ * Helper for measuring how much time is spent doing some operation.
+ */
+class TimeCounter {
+ int result = 0;
+
+ /**
+ * Starts counting time.
+ *
+ * @return the [TimeCounterHandle] that should be used to stop counting.
+ */
+ TimeCounter_TimeCounterHandle start() => new TimeCounter_TimeCounterHandle(this);
+}
+/**
+ * The handle object that should be used to stop and update counter.
+ */
+class TimeCounter_TimeCounterHandle {
+ final TimeCounter TimeCounter_this;
+ int _startTime = JavaSystem.currentTimeMillis();
+ TimeCounter_TimeCounterHandle(this.TimeCounter_this);
+
+ /**
+ * Stops counting time and updates counter.
+ */
+ void stop() {
+ {
+ TimeCounter_this.result += JavaSystem.currentTimeMillis() - _startTime;
+ }
+ }
+}
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
index 04f0e2b..032d5e7 100644
--- a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
@@ -93,6 +93,8 @@
final int length;
Selection(this.offset, this.length);
+
+ String toString() => 'Selection (offset: $offset, length: $length)';
}
/// Formatted source.
@@ -128,14 +130,14 @@
var node = parse(kind, startToken);
checkForErrors();
- var formatter = new SourceVisitor(options, lineInfo);
+ var formatter = new SourceVisitor(options, lineInfo, selection);
node.accept(formatter);
var formattedSource = formatter.writer.toString();
checkTokenStreams(startToken, tokenize(formattedSource));
- return new FormattedSource(formattedSource);
+ return new FormattedSource(formattedSource, formatter.selection);
}
checkTokenStreams(Token t1, Token t2) =>
@@ -309,10 +311,16 @@
/// Used for matching EOL comments
final twoSlashes = new RegExp(r'//[^/]');
+
+ /// Original pre-format selection information (may be null).
+ final Selection preSelection;
+
+ /// Post format selection information.
+ Selection selection;
/// Initialize a newly created visitor to write source code representing
/// the visited nodes to the given [writer].
- SourceVisitor(FormatterOptions options, this.lineInfo) :
+ SourceVisitor(FormatterOptions options, this.lineInfo, this.preSelection) :
writer = new SourceWriter(indentCount: options.initialIndentationLevel,
lineSeparator: options.lineSeparator);
@@ -1209,6 +1217,7 @@
if (precededBy != null) {
precededBy();
}
+ checkForSelectionUpdate(token);
append(token.lexeme);
if (followedBy != null) {
followedBy();
@@ -1216,6 +1225,19 @@
previousToken = token;
}
}
+
+ checkForSelectionUpdate(Token token) {
+ // Cache the first token on or AFTER the selection offset
+ if (preSelection != null && selection == null) {
+ // Check for overshots
+ var overshot = token.offset - preSelection.offset;
+ if (overshot >= 0) {
+ //TODO(pquitslund): update length (may need truncating)
+ selection = new Selection(writer.toString().length - overshot,
+ preSelection.length);
+ }
+ }
+ }
commaSeperator() {
comma();
diff --git a/pkg/analyzer_experimental/test/generated/ast_test.dart b/pkg/analyzer_experimental/test/generated/ast_test.dart
index a8d31ed..36380ec 100644
--- a/pkg/analyzer_experimental/test/generated/ast_test.dart
+++ b/pkg/analyzer_experimental/test/generated/ast_test.dart
@@ -239,7 +239,8 @@
static AssignmentExpression assignmentExpression(Expression leftHandSide, TokenType operator, Expression rightHandSide) => new AssignmentExpression.full(leftHandSide, TokenFactory.token3(operator), rightHandSide);
static BinaryExpression binaryExpression(Expression leftOperand, TokenType operator, Expression rightOperand) => new BinaryExpression.full(leftOperand, TokenFactory.token3(operator), rightOperand);
static Block block(List<Statement> statements) => new Block.full(TokenFactory.token3(TokenType.OPEN_CURLY_BRACKET), list(statements), TokenFactory.token3(TokenType.CLOSE_CURLY_BRACKET));
- static BlockFunctionBody blockFunctionBody(List<Statement> statements) => new BlockFunctionBody.full(block(statements));
+ static BlockFunctionBody blockFunctionBody(Block block) => new BlockFunctionBody.full(block);
+ static BlockFunctionBody blockFunctionBody2(List<Statement> statements) => new BlockFunctionBody.full(block(statements));
static BooleanLiteral booleanLiteral(bool value) => new BooleanLiteral.full(value ? TokenFactory.token(Keyword.TRUE) : TokenFactory.token(Keyword.FALSE), value);
static BreakStatement breakStatement() => new BreakStatement.full(TokenFactory.token(Keyword.BREAK), null, TokenFactory.token3(TokenType.SEMICOLON));
static BreakStatement breakStatement2(String label) => new BreakStatement.full(TokenFactory.token(Keyword.BREAK), identifier3(label), TokenFactory.token3(TokenType.SEMICOLON));
@@ -287,13 +288,13 @@
static FieldFormalParameter fieldFormalParameter(Keyword keyword, TypeName type, String identifier) => new FieldFormalParameter.full(null, null, keyword == null ? null : TokenFactory.token(keyword), type, TokenFactory.token(Keyword.THIS), TokenFactory.token3(TokenType.PERIOD), identifier3(identifier), null);
static FieldFormalParameter fieldFormalParameter2(Keyword keyword, TypeName type, String identifier, FormalParameterList parameterList) => new FieldFormalParameter.full(null, null, keyword == null ? null : TokenFactory.token(keyword), type, TokenFactory.token(Keyword.THIS), TokenFactory.token3(TokenType.PERIOD), identifier3(identifier), parameterList);
static FieldFormalParameter fieldFormalParameter3(String identifier) => fieldFormalParameter(null, null, identifier);
- static ForEachStatement forEachStatement(DeclaredIdentifier loopVariable, Expression iterator, Statement body) => new ForEachStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), loopVariable, TokenFactory.token(Keyword.IN), iterator, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
+ static ForEachStatement forEachStatement(DeclaredIdentifier loopVariable, Expression iterator, Statement body) => new ForEachStatement.con1_full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), loopVariable, TokenFactory.token(Keyword.IN), iterator, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
static FormalParameterList formalParameterList(List<FormalParameter> parameters) => new FormalParameterList.full(TokenFactory.token3(TokenType.OPEN_PAREN), list(parameters), null, null, TokenFactory.token3(TokenType.CLOSE_PAREN));
static ForStatement forStatement(Expression initialization, Expression condition, List<Expression> updaters, Statement body) => new ForStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), null, initialization, TokenFactory.token3(TokenType.SEMICOLON), condition, TokenFactory.token3(TokenType.SEMICOLON), updaters, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
static ForStatement forStatement2(VariableDeclarationList variableList, Expression condition, List<Expression> updaters, Statement body) => new ForStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), variableList, null, TokenFactory.token3(TokenType.SEMICOLON), condition, TokenFactory.token3(TokenType.SEMICOLON), updaters, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
static FunctionDeclaration functionDeclaration(TypeName type, Keyword keyword, String name, FunctionExpression functionExpression) => new FunctionDeclaration.full(null, null, null, type, keyword == null ? null : TokenFactory.token(keyword), identifier3(name), functionExpression);
static FunctionDeclarationStatement functionDeclarationStatement(TypeName type, Keyword keyword, String name, FunctionExpression functionExpression) => new FunctionDeclarationStatement.full(functionDeclaration(type, keyword, name, functionExpression));
- static FunctionExpression functionExpression() => new FunctionExpression.full(formalParameterList([]), blockFunctionBody([]));
+ static FunctionExpression functionExpression() => new FunctionExpression.full(formalParameterList([]), blockFunctionBody2([]));
static FunctionExpression functionExpression2(FormalParameterList parameters, FunctionBody body) => new FunctionExpression.full(parameters, body);
static FunctionExpressionInvocation functionExpressionInvocation(Expression function, List<Expression> arguments) => new FunctionExpressionInvocation.full(function, argumentList(arguments));
static FunctionTypedFormalParameter functionTypedFormalParameter(TypeName returnType, String identifier, List<FormalParameter> parameters) => new FunctionTypedFormalParameter.full(null, null, returnType, identifier3(identifier), formalParameterList(parameters));
@@ -774,7 +775,7 @@
"}"]);
CompilationUnit unit = ParserTestCase.parseCompilationUnit(source, []);
List<ASTNode> nodes = new List<ASTNode>();
- BreadthFirstVisitor<Object> visitor = new BreadthFirstVisitor_18(nodes);
+ BreadthFirstVisitor<Object> visitor = new BreadthFirstVisitor_17(nodes);
visitor.visitAllNodes(unit);
EngineTestCase.assertSize(59, nodes);
EngineTestCase.assertInstanceOf(CompilationUnit, nodes[0]);
@@ -792,9 +793,9 @@
});
}
}
-class BreadthFirstVisitor_18 extends BreadthFirstVisitor<Object> {
+class BreadthFirstVisitor_17 extends BreadthFirstVisitor<Object> {
List<ASTNode> nodes;
- BreadthFirstVisitor_18(this.nodes) : super();
+ BreadthFirstVisitor_17(this.nodes) : super();
Object visitNode(ASTNode node) {
nodes.add(node);
return super.visitNode(node);
@@ -825,7 +826,7 @@
Object value = getConstantValue("?");
JUnitTestCase.assertEquals(null, value);
}
- void fail_identifier_typeVariable() {
+ void fail_identifier_typeParameter() {
Object value = getConstantValue("?");
JUnitTestCase.assertEquals(null, value);
}
@@ -1294,7 +1295,7 @@
assertSource("{break; break;}", ASTFactory.block([ASTFactory.breakStatement(), ASTFactory.breakStatement()]));
}
void test_visitBlockFunctionBody() {
- assertSource("{}", ASTFactory.blockFunctionBody([]));
+ assertSource("{}", ASTFactory.blockFunctionBody2([]));
}
void test_visitBooleanLiteral_false() {
assertSource("false", ASTFactory.booleanLiteral(false));
@@ -1440,29 +1441,29 @@
assertSource("a ? b : c", ASTFactory.conditionalExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"), ASTFactory.identifier3("c")));
}
void test_visitConstructorDeclaration_const() {
- assertSource("const C() {}", ASTFactory.constructorDeclaration2(Keyword.CONST, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody([])));
+ assertSource("const C() {}", ASTFactory.constructorDeclaration2(Keyword.CONST, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody2([])));
}
void test_visitConstructorDeclaration_external() {
assertSource("external C();", ASTFactory.constructorDeclaration(ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), null));
}
void test_visitConstructorDeclaration_minimal() {
- assertSource("C() {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody([])));
+ assertSource("C() {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody2([])));
}
void test_visitConstructorDeclaration_multipleInitializers() {
assertSource("C() : a = b, c = d {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([
(ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer),
- ASTFactory.constructorFieldInitializer(false, "c", ASTFactory.identifier3("d"))]), ASTFactory.blockFunctionBody([])));
+ ASTFactory.constructorFieldInitializer(false, "c", ASTFactory.identifier3("d"))]), ASTFactory.blockFunctionBody2([])));
}
void test_visitConstructorDeclaration_multipleParameters() {
assertSource("C(var a, var b) {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([
ASTFactory.simpleFormalParameter(Keyword.VAR, "a"),
- ASTFactory.simpleFormalParameter(Keyword.VAR, "b")]), null, ASTFactory.blockFunctionBody([])));
+ ASTFactory.simpleFormalParameter(Keyword.VAR, "b")]), null, ASTFactory.blockFunctionBody2([])));
}
void test_visitConstructorDeclaration_named() {
- assertSource("C.m() {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), "m", ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody([])));
+ assertSource("C.m() {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), "m", ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody2([])));
}
void test_visitConstructorDeclaration_singleInitializer() {
- assertSource("C() : a = b {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([(ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer)]), ASTFactory.blockFunctionBody([])));
+ assertSource("C() : a = b {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([(ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer)]), ASTFactory.blockFunctionBody2([])));
}
void test_visitConstructorFieldInitializer_withoutThis() {
assertSource("a = b", ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")));
@@ -1815,39 +1816,39 @@
assertSource("external T m();", ASTFactory.methodDeclaration(null, ASTFactory.typeName4("T", []), null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([])));
}
void test_visitMethodDeclaration_getter() {
- assertSource("get m {}", ASTFactory.methodDeclaration2(null, null, Keyword.GET, null, ASTFactory.identifier3("m"), null, ASTFactory.blockFunctionBody([])));
+ assertSource("get m {}", ASTFactory.methodDeclaration2(null, null, Keyword.GET, null, ASTFactory.identifier3("m"), null, ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_getter_returnType() {
- assertSource("T get m {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName4("T", []), Keyword.GET, null, ASTFactory.identifier3("m"), null, ASTFactory.blockFunctionBody([])));
+ assertSource("T get m {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName4("T", []), Keyword.GET, null, ASTFactory.identifier3("m"), null, ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_getter_seturnType() {
- assertSource("T set m(var v) {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName4("T", []), Keyword.SET, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter(Keyword.VAR, "v")]), ASTFactory.blockFunctionBody([])));
+ assertSource("T set m(var v) {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName4("T", []), Keyword.SET, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter(Keyword.VAR, "v")]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_minimal() {
- assertSource("m() {}", ASTFactory.methodDeclaration2(null, null, null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+ assertSource("m() {}", ASTFactory.methodDeclaration2(null, null, null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_multipleParameters() {
assertSource("m(var a, var b) {}", ASTFactory.methodDeclaration2(null, null, null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([
ASTFactory.simpleFormalParameter(Keyword.VAR, "a"),
- ASTFactory.simpleFormalParameter(Keyword.VAR, "b")]), ASTFactory.blockFunctionBody([])));
+ ASTFactory.simpleFormalParameter(Keyword.VAR, "b")]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_operator() {
- assertSource("operator +() {}", ASTFactory.methodDeclaration2(null, null, null, Keyword.OPERATOR, ASTFactory.identifier3("+"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+ assertSource("operator +() {}", ASTFactory.methodDeclaration2(null, null, null, Keyword.OPERATOR, ASTFactory.identifier3("+"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_operator_returnType() {
- assertSource("T operator +() {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName4("T", []), null, Keyword.OPERATOR, ASTFactory.identifier3("+"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+ assertSource("T operator +() {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName4("T", []), null, Keyword.OPERATOR, ASTFactory.identifier3("+"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_returnType() {
- assertSource("T m() {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName4("T", []), null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+ assertSource("T m() {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName4("T", []), null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_setter() {
- assertSource("set m(var v) {}", ASTFactory.methodDeclaration2(null, null, Keyword.SET, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter(Keyword.VAR, "v")]), ASTFactory.blockFunctionBody([])));
+ assertSource("set m(var v) {}", ASTFactory.methodDeclaration2(null, null, Keyword.SET, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter(Keyword.VAR, "v")]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_static() {
- assertSource("static m() {}", ASTFactory.methodDeclaration2(Keyword.STATIC, null, null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+ assertSource("static m() {}", ASTFactory.methodDeclaration2(Keyword.STATIC, null, null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodDeclaration_static_returnType() {
- assertSource("static T m() {}", ASTFactory.methodDeclaration2(Keyword.STATIC, ASTFactory.typeName4("T", []), null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+ assertSource("static T m() {}", ASTFactory.methodDeclaration2(Keyword.STATIC, ASTFactory.typeName4("T", []), null, null, ASTFactory.identifier3("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody2([])));
}
void test_visitMethodInvocation_noTarget() {
assertSource("m()", ASTFactory.methodInvocation2("m", []));
diff --git a/pkg/analyzer_experimental/test/generated/element_test.dart b/pkg/analyzer_experimental/test/generated/element_test.dart
index 2674d10..d2571ca 100644
--- a/pkg/analyzer_experimental/test/generated/element_test.dart
+++ b/pkg/analyzer_experimental/test/generated/element_test.dart
@@ -204,6 +204,70 @@
});
}
}
+class TypeParameterTypeImplTest extends EngineTestCase {
+ void fail_isMoreSpecificThan_typeArguments_object() {
+ TypeParameterElementImpl element = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
+ TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+ JUnitTestCase.assertTrue(type.isMoreSpecificThan(ElementFactory.object.type));
+ }
+ void fail_isMoreSpecificThan_typeArguments_self() {
+ TypeParameterElementImpl element = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
+ TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+ JUnitTestCase.assertTrue(type.isMoreSpecificThan(type));
+ }
+ void test_creation() {
+ JUnitTestCase.assertNotNull(new TypeParameterTypeImpl(new TypeParameterElementImpl(ASTFactory.identifier3("E"))));
+ }
+ void test_getElement() {
+ TypeParameterElementImpl element = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
+ TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+ JUnitTestCase.assertEquals(element, type.element);
+ }
+ void test_isMoreSpecificThan_typeArguments_upperBound() {
+ ClassElementImpl classS = ElementFactory.classElement2("A", []);
+ TypeParameterElementImpl typeParameterT = new TypeParameterElementImpl(ASTFactory.identifier3("T"));
+ typeParameterT.bound = classS.type;
+ TypeParameterTypeImpl typeParameterTypeT = new TypeParameterTypeImpl(typeParameterT);
+ JUnitTestCase.assertTrue(typeParameterTypeT.isMoreSpecificThan(classS.type));
+ }
+ void test_substitute_equal() {
+ TypeParameterElementImpl element = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
+ TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+ InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("A")));
+ TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(element);
+ JUnitTestCase.assertSame(argument, type.substitute2(<Type2> [argument], <Type2> [parameter]));
+ }
+ void test_substitute_notEqual() {
+ TypeParameterTypeImpl type = new TypeParameterTypeImpl(new TypeParameterElementImpl(ASTFactory.identifier3("E")));
+ InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("A")));
+ TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(new TypeParameterElementImpl(ASTFactory.identifier3("F")));
+ JUnitTestCase.assertSame(type, type.substitute2(<Type2> [argument], <Type2> [parameter]));
+ }
+ static dartSuite() {
+ _ut.group('TypeParameterTypeImplTest', () {
+ _ut.test('test_creation', () {
+ final __test = new TypeParameterTypeImplTest();
+ runJUnitTest(__test, __test.test_creation);
+ });
+ _ut.test('test_getElement', () {
+ final __test = new TypeParameterTypeImplTest();
+ runJUnitTest(__test, __test.test_getElement);
+ });
+ _ut.test('test_isMoreSpecificThan_typeArguments_upperBound', () {
+ final __test = new TypeParameterTypeImplTest();
+ runJUnitTest(__test, __test.test_isMoreSpecificThan_typeArguments_upperBound);
+ });
+ _ut.test('test_substitute_equal', () {
+ final __test = new TypeParameterTypeImplTest();
+ runJUnitTest(__test, __test.test_substitute_equal);
+ });
+ _ut.test('test_substitute_notEqual', () {
+ final __test = new TypeParameterTypeImplTest();
+ runJUnitTest(__test, __test.test_substitute_notEqual);
+ });
+ });
+ }
+}
class InterfaceTypeImplTest extends EngineTestCase {
/**
@@ -1176,9 +1240,9 @@
}
void test_substitute_equal() {
ClassElementImpl classA = ElementFactory.classElement2("A", []);
- TypeVariableElementImpl parameterElement = new TypeVariableElementImpl(ASTFactory.identifier3("E"));
+ TypeParameterElementImpl parameterElement = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(classA);
- TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(parameterElement);
+ TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(parameterElement);
type.typeArguments = <Type2> [parameter];
InterfaceType argumentType = ElementFactory.classElement2("B", []).type;
InterfaceType result = type.substitute2(<Type2> [argumentType], <Type2> [parameter]);
@@ -1199,12 +1263,12 @@
}
void test_substitute_notEqual() {
ClassElementImpl classA = ElementFactory.classElement2("A", []);
- TypeVariableElementImpl parameterElement = new TypeVariableElementImpl(ASTFactory.identifier3("E"));
+ TypeParameterElementImpl parameterElement = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(classA);
- TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(parameterElement);
+ TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(parameterElement);
type.typeArguments = <Type2> [parameter];
InterfaceType argumentType = ElementFactory.classElement2("B", []).type;
- TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier3("F")));
+ TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(new TypeParameterElementImpl(ASTFactory.identifier3("F")));
InterfaceType result = type.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
JUnitTestCase.assertEquals(classA, result.element);
List<Type2> resultArguments = result.typeArguments;
@@ -1612,70 +1676,6 @@
});
}
}
-class TypeVariableTypeImplTest extends EngineTestCase {
- void fail_isMoreSpecificThan_typeArguments_object() {
- TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier3("E"));
- TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
- JUnitTestCase.assertTrue(type.isMoreSpecificThan(ElementFactory.object.type));
- }
- void fail_isMoreSpecificThan_typeArguments_self() {
- TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier3("E"));
- TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
- JUnitTestCase.assertTrue(type.isMoreSpecificThan(type));
- }
- void test_creation() {
- JUnitTestCase.assertNotNull(new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier3("E"))));
- }
- void test_getElement() {
- TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier3("E"));
- TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
- JUnitTestCase.assertEquals(element, type.element);
- }
- void test_isMoreSpecificThan_typeArguments_upperBound() {
- ClassElementImpl classS = ElementFactory.classElement2("A", []);
- TypeVariableElementImpl typeVarT = new TypeVariableElementImpl(ASTFactory.identifier3("T"));
- typeVarT.bound = classS.type;
- TypeVariableTypeImpl typeVarTypeT = new TypeVariableTypeImpl(typeVarT);
- JUnitTestCase.assertTrue(typeVarTypeT.isMoreSpecificThan(classS.type));
- }
- void test_substitute_equal() {
- TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier3("E"));
- TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
- InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("A")));
- TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(element);
- JUnitTestCase.assertSame(argument, type.substitute2(<Type2> [argument], <Type2> [parameter]));
- }
- void test_substitute_notEqual() {
- TypeVariableTypeImpl type = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier3("E")));
- InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("A")));
- TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier3("F")));
- JUnitTestCase.assertSame(type, type.substitute2(<Type2> [argument], <Type2> [parameter]));
- }
- static dartSuite() {
- _ut.group('TypeVariableTypeImplTest', () {
- _ut.test('test_creation', () {
- final __test = new TypeVariableTypeImplTest();
- runJUnitTest(__test, __test.test_creation);
- });
- _ut.test('test_getElement', () {
- final __test = new TypeVariableTypeImplTest();
- runJUnitTest(__test, __test.test_getElement);
- });
- _ut.test('test_isMoreSpecificThan_typeArguments_upperBound', () {
- final __test = new TypeVariableTypeImplTest();
- runJUnitTest(__test, __test.test_isMoreSpecificThan_typeArguments_upperBound);
- });
- _ut.test('test_substitute_equal', () {
- final __test = new TypeVariableTypeImplTest();
- runJUnitTest(__test, __test.test_substitute_equal);
- });
- _ut.test('test_substitute_notEqual', () {
- final __test = new TypeVariableTypeImplTest();
- runJUnitTest(__test, __test.test_substitute_notEqual);
- });
- });
- }
-}
/**
* The class `ElementFactory` defines utility methods used to create elements for testing
* purposes. The elements that are created are complete in the sense that as much of the element
@@ -1694,16 +1694,16 @@
element.type = type;
int count = parameterNames.length;
if (count > 0) {
- List<TypeVariableElementImpl> typeVariables = new List<TypeVariableElementImpl>(count);
- List<TypeVariableTypeImpl> typeArguments = new List<TypeVariableTypeImpl>(count);
+ List<TypeParameterElementImpl> typeParameters = new List<TypeParameterElementImpl>(count);
+ List<TypeParameterTypeImpl> typeParameterTypes = new List<TypeParameterTypeImpl>(count);
for (int i = 0; i < count; i++) {
- TypeVariableElementImpl variable = new TypeVariableElementImpl(ASTFactory.identifier3(parameterNames[i]));
- typeVariables[i] = variable;
- typeArguments[i] = new TypeVariableTypeImpl(variable);
- variable.type = typeArguments[i];
+ TypeParameterElementImpl typeParameter = new TypeParameterElementImpl(ASTFactory.identifier3(parameterNames[i]));
+ typeParameters[i] = typeParameter;
+ typeParameterTypes[i] = new TypeParameterTypeImpl(typeParameter);
+ typeParameter.type = typeParameterTypes[i];
}
- element.typeVariables = typeVariables;
- type.typeArguments = typeArguments;
+ element.typeParameters = typeParameters;
+ type.typeArguments = typeParameterTypes;
}
return element;
}
@@ -1845,7 +1845,7 @@
return spec;
}
static LibraryElementImpl library(AnalysisContext context, String libraryName) {
- String fileName = "${libraryName}.dart";
+ String fileName = "/${libraryName}.dart";
FileBasedSource source = new FileBasedSource.con1(context.sourceFactory.contentCache, FileUtilities2.createFile(fileName));
CompilationUnitElementImpl unit = new CompilationUnitElementImpl(fileName);
unit.source = source;
@@ -2382,7 +2382,7 @@
}
void test_isSubtypeOf_baseCase_classFunction() {
ClassElementImpl functionElement = ElementFactory.classElement2("Function", []);
- InterfaceTypeImpl functionType = new InterfaceTypeImpl_25(functionElement);
+ InterfaceTypeImpl functionType = new InterfaceTypeImpl_22(functionElement);
FunctionType f = ElementFactory.functionElement("f").type;
JUnitTestCase.assertTrue(f.isSubtypeOf(functionType));
}
@@ -2569,12 +2569,12 @@
TestTypeProvider provider = new TestTypeProvider();
InterfaceType boolType = provider.boolType;
InterfaceType stringType = provider.stringType;
- TypeVariableElementImpl variableB = new TypeVariableElementImpl(ASTFactory.identifier3("B"));
- variableB.bound = boolType;
- TypeVariableTypeImpl typeB = new TypeVariableTypeImpl(variableB);
- TypeVariableElementImpl variableS = new TypeVariableElementImpl(ASTFactory.identifier3("S"));
- variableS.bound = stringType;
- TypeVariableTypeImpl typeS = new TypeVariableTypeImpl(variableS);
+ TypeParameterElementImpl parameterB = new TypeParameterElementImpl(ASTFactory.identifier3("B"));
+ parameterB.bound = boolType;
+ TypeParameterTypeImpl typeB = new TypeParameterTypeImpl(parameterB);
+ TypeParameterElementImpl parameterS = new TypeParameterElementImpl(ASTFactory.identifier3("S"));
+ parameterS.bound = stringType;
+ TypeParameterTypeImpl typeS = new TypeParameterTypeImpl(parameterS);
FunctionElementImpl functionAliasElement = new FunctionElementImpl.con1(ASTFactory.identifier3("func"));
functionAliasElement.parameters = <ParameterElement> [
ElementFactory.requiredParameter2("a", typeB),
@@ -2610,7 +2610,7 @@
MethodElementImpl methodElement = new MethodElementImpl.con1(ASTFactory.identifier3("m"));
enclosingClass.methods = <MethodElement> [methodElement];
FunctionTypeImpl type = new FunctionTypeImpl.con1(methodElement);
- Type2 expectedType = enclosingClass.typeVariables[0].type;
+ Type2 expectedType = enclosingClass.typeParameters[0].type;
type.typeArguments = <Type2> [expectedType];
List<Type2> arguments = type.typeArguments;
EngineTestCase.assertLength(1, arguments);
@@ -2618,7 +2618,7 @@
}
void test_substitute2_equal() {
ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
- TypeVariableType parameterType = definingClass.typeVariables[0].type;
+ TypeParameterType parameterType = definingClass.typeParameters[0].type;
MethodElementImpl functionElement = new MethodElementImpl.con1(ASTFactory.identifier3("m"));
String namedParameterName = "c";
functionElement.parameters = <ParameterElement> [
@@ -2656,7 +2656,7 @@
functionElement.returnType = returnType;
FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier3("D")));
- TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier3("E")));
+ TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(new TypeParameterElementImpl(ASTFactory.identifier3("E")));
FunctionType result = functionType.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
JUnitTestCase.assertEquals(returnType, result.returnType);
List<Type2> normalParameters = result.normalParameterTypes;
@@ -2846,15 +2846,15 @@
});
}
}
-class InterfaceTypeImpl_25 extends InterfaceTypeImpl {
- InterfaceTypeImpl_25(ClassElement arg0) : super.con1(arg0);
+class InterfaceTypeImpl_22 extends InterfaceTypeImpl {
+ InterfaceTypeImpl_22(ClassElement arg0) : super.con1(arg0);
bool get isDartCoreFunction => true;
}
main() {
ElementKindTest.dartSuite();
FunctionTypeImplTest.dartSuite();
InterfaceTypeImplTest.dartSuite();
- TypeVariableTypeImplTest.dartSuite();
+ TypeParameterTypeImplTest.dartSuite();
ClassElementImplTest.dartSuite();
ElementLocationImplTest.dartSuite();
ElementImplTest.dartSuite();
diff --git a/pkg/analyzer_experimental/test/generated/parser_test.dart b/pkg/analyzer_experimental/test/generated/parser_test.dart
index 0a7adad..35644e7 100644
--- a/pkg/analyzer_experimental/test/generated/parser_test.dart
+++ b/pkg/analyzer_experimental/test/generated/parser_test.dart
@@ -1928,7 +1928,8 @@
ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (element in list) {}", []);
JUnitTestCase.assertNotNull(statement.forKeyword);
JUnitTestCase.assertNotNull(statement.leftParenthesis);
- JUnitTestCase.assertNotNull(statement.loopVariable);
+ JUnitTestCase.assertNull(statement.loopVariable);
+ JUnitTestCase.assertNotNull(statement.identifier);
JUnitTestCase.assertNotNull(statement.inKeyword);
JUnitTestCase.assertNotNull(statement.iterator);
JUnitTestCase.assertNotNull(statement.rightParenthesis);
@@ -1940,6 +1941,7 @@
JUnitTestCase.assertNotNull(statement.leftParenthesis);
JUnitTestCase.assertNotNull(statement.loopVariable);
EngineTestCase.assertSize(1, statement.loopVariable.metadata);
+ JUnitTestCase.assertNull(statement.identifier);
JUnitTestCase.assertNotNull(statement.inKeyword);
JUnitTestCase.assertNotNull(statement.iterator);
JUnitTestCase.assertNotNull(statement.rightParenthesis);
@@ -1950,6 +1952,7 @@
JUnitTestCase.assertNotNull(statement.forKeyword);
JUnitTestCase.assertNotNull(statement.leftParenthesis);
JUnitTestCase.assertNotNull(statement.loopVariable);
+ JUnitTestCase.assertNull(statement.identifier);
JUnitTestCase.assertNotNull(statement.inKeyword);
JUnitTestCase.assertNotNull(statement.iterator);
JUnitTestCase.assertNotNull(statement.rightParenthesis);
@@ -1960,6 +1963,7 @@
JUnitTestCase.assertNotNull(statement.forKeyword);
JUnitTestCase.assertNotNull(statement.leftParenthesis);
JUnitTestCase.assertNotNull(statement.loopVariable);
+ JUnitTestCase.assertNull(statement.identifier);
JUnitTestCase.assertNotNull(statement.inKeyword);
JUnitTestCase.assertNotNull(statement.iterator);
JUnitTestCase.assertNotNull(statement.rightParenthesis);
@@ -3775,7 +3779,7 @@
* @throws Exception if the method could not be invoked or throws an exception
*/
String computeStringValue(String lexeme, bool first, bool last) {
- AnalysisErrorListener listener = new AnalysisErrorListener_26();
+ AnalysisErrorListener listener = new AnalysisErrorListener_23();
Parser parser = new Parser(null, listener);
return invokeParserMethodImpl(parser, "computeStringValue", <Object> [lexeme, first, last], null) as String;
}
@@ -6003,7 +6007,7 @@
});
}
}
-class AnalysisErrorListener_26 implements AnalysisErrorListener {
+class AnalysisErrorListener_23 implements AnalysisErrorListener {
void onError(AnalysisError event) {
JUnitTestCase.fail("Unexpected compilation error: ${event.message} (${event.offset}, ${event.length})");
}
@@ -7917,6 +7921,12 @@
void test_functionTypedParameter_var() {
ParserTestCase.parseCompilationUnit("void f(var x()) {}", [ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR]);
}
+ void test_getterInFunction_block() {
+ ParserTestCase.parseStatement("get x { return _x; }", [ParserErrorCode.GETTER_IN_FUNCTION]);
+ }
+ void test_getterInFunction_expression() {
+ ParserTestCase.parseStatement("get x => _x;", [ParserErrorCode.GETTER_IN_FUNCTION]);
+ }
void test_getterWithParameters() {
ParserTestCase.parse4("parseClassMember", <Object> ["C"], "int get x() {}", [ParserErrorCode.GETTER_WITH_PARAMETERS]);
}
@@ -8207,6 +8217,12 @@
void test_redirectionInNonFactoryConstructor() {
ParserTestCase.parse4("parseClassMember", <Object> ["C"], "C() = D;", [ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR]);
}
+ void test_setterInFunction_block() {
+ ParserTestCase.parseStatement("set x(v) {_x = v;}", [ParserErrorCode.SETTER_IN_FUNCTION]);
+ }
+ void test_setterInFunction_expression() {
+ ParserTestCase.parseStatement("set x(v) => _x = v;", [ParserErrorCode.SETTER_IN_FUNCTION]);
+ }
void test_staticAfterConst() {
ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final static int f;", [ParserErrorCode.STATIC_AFTER_FINAL]);
}
@@ -8734,6 +8750,14 @@
final __test = new ErrorParserTest();
runJUnitTest(__test, __test.test_functionTypedParameter_var);
});
+ _ut.test('test_getterInFunction_block', () {
+ final __test = new ErrorParserTest();
+ runJUnitTest(__test, __test.test_getterInFunction_block);
+ });
+ _ut.test('test_getterInFunction_expression', () {
+ final __test = new ErrorParserTest();
+ runJUnitTest(__test, __test.test_getterInFunction_expression);
+ });
_ut.test('test_getterWithParameters', () {
final __test = new ErrorParserTest();
runJUnitTest(__test, __test.test_getterWithParameters);
@@ -9098,6 +9122,14 @@
final __test = new ErrorParserTest();
runJUnitTest(__test, __test.test_redirectionInNonFactoryConstructor);
});
+ _ut.test('test_setterInFunction_block', () {
+ final __test = new ErrorParserTest();
+ runJUnitTest(__test, __test.test_setterInFunction_block);
+ });
+ _ut.test('test_setterInFunction_expression', () {
+ final __test = new ErrorParserTest();
+ runJUnitTest(__test, __test.test_setterInFunction_expression);
+ });
_ut.test('test_staticAfterConst', () {
final __test = new ErrorParserTest();
runJUnitTest(__test, __test.test_staticAfterConst);
@@ -9303,6 +9335,7 @@
'ensureAssignable_1': new MethodTrampoline(1, (Parser target, arg0) => target.ensureAssignable(arg0)),
'expect_1': new MethodTrampoline(1, (Parser target, arg0) => target.expect(arg0)),
'findRange_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.findRange(arg0, arg1)),
+ 'gatherTodoComments_1': new MethodTrampoline(1, (Parser target, arg0) => target.gatherTodoComments(arg0)),
'getCodeBlockRanges_1': new MethodTrampoline(1, (Parser target, arg0) => target.getCodeBlockRanges(arg0)),
'getEndToken_1': new MethodTrampoline(1, (Parser target, arg0) => target.getEndToken(arg0)),
'hasReturnTypeInTypeAlias_0': new MethodTrampoline(0, (Parser target) => target.hasReturnTypeInTypeAlias()),
@@ -9436,6 +9469,7 @@
'peek_1': new MethodTrampoline(1, (Parser target, arg0) => target.peek2(arg0)),
'reportError_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.reportError(arg0, arg1, arg2)),
'reportError_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.reportError8(arg0, arg1)),
+ 'scrapeTodoComment_1': new MethodTrampoline(1, (Parser target, arg0) => target.scrapeTodoComment(arg0)),
'skipFinalConstVarOrType_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipFinalConstVarOrType(arg0)),
'skipFormalParameterList_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipFormalParameterList(arg0)),
'skipPastMatchingToken_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipPastMatchingToken(arg0)),
diff --git a/pkg/analyzer_experimental/test/generated/resolver_test.dart b/pkg/analyzer_experimental/test/generated/resolver_test.dart
index bd7948d..0e21d4b 100644
--- a/pkg/analyzer_experimental/test/generated/resolver_test.dart
+++ b/pkg/analyzer_experimental/test/generated/resolver_test.dart
@@ -28,7 +28,7 @@
"}"]);
Source source = addSource(code);
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
Type2 dynamicType = typeProvider.dynamicType;
@@ -57,7 +57,7 @@
" }",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -77,7 +77,7 @@
" return p;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -91,7 +91,7 @@
void test_assignment() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var v;", " v = 0;", " return v;", "}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
@@ -103,7 +103,7 @@
void test_assignment_afterInitializer() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var v = 0;", " v = 1.0;", " return v;", "}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
@@ -121,7 +121,7 @@
"}"]);
Source source = addSource(code);
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
InterfaceType stringType = typeProvider.stringType;
@@ -147,7 +147,7 @@
"}"]);
Source source = addSource(code);
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
Type2 intType = typeProvider.intType;
@@ -174,7 +174,7 @@
"}"]);
Source source = addSource(code);
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
Type2 intType = typeProvider.intType;
@@ -196,7 +196,7 @@
"}"]);
Source source = addSource(code);
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
Type2 intType = typeProvider.intType;
@@ -219,7 +219,7 @@
"}"]);
Source source = addSource(code);
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
Type2 stringType = typeProvider.stringType;
@@ -242,7 +242,7 @@
"}"]);
Source source = addSource(code);
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FormalParameter p1 = EngineTestCase.findNode(unit, code, "p1) {", SimpleFormalParameter);
@@ -255,7 +255,7 @@
void test_initializer() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var v = 0;", " return v;", "}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
@@ -291,7 +291,7 @@
" return (p is A) ? p : null;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -314,7 +314,7 @@
" }",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -330,14 +330,14 @@
Source source = addSource(EngineTestCase.createSource([
"class A {}",
"A f(A p) {",
- " if (p is Object) {",
+ " if (p is String) {",
" return p;",
" } else {",
" return null;",
" }",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
@@ -358,7 +358,7 @@
" }",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -378,7 +378,7 @@
" return p;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -401,7 +401,7 @@
" return p;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -424,7 +424,7 @@
" }",
"}"]));
LibraryElement library = resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_METHOD]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
BlockFunctionBody body = function.functionExpression.body as BlockFunctionBody;
@@ -442,7 +442,7 @@
" }",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -461,7 +461,7 @@
" return (p is! A) ? null : p;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -484,7 +484,7 @@
" }",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -507,7 +507,7 @@
" }",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -527,7 +527,7 @@
" return p;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -548,7 +548,7 @@
" return p;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
@@ -562,7 +562,7 @@
void test_listLiteral_different() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var v = [0, '1', 2];", " return v[2];", "}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
@@ -574,7 +574,7 @@
void test_listLiteral_same() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var v = [0, 1, 2];", " return v[2];", "}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
@@ -590,7 +590,7 @@
" return v;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
@@ -611,7 +611,7 @@
" return v;",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
@@ -635,9 +635,9 @@
}
void test_propagatedReturnType_function_moreSpecificStaticReturnType() {
String code = EngineTestCase.createSource([
- "int f() => (42 as Object);",
+ "int f(v) => (v as num);",
"main() {",
- " var v = f();",
+ " var v = f(3);",
"}"]);
check_propagatedReturnType(code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -692,7 +692,7 @@
" return [v1, v2, v3, v4, v5, v6, v7, m1, b1, b2, b3];",
"}"]));
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
FunctionDeclaration main = unit.declarations[0] as FunctionDeclaration;
@@ -719,7 +719,7 @@
void check_propagatedReturnType(String code, Type2 expectedStaticType, Type2 expectedPropagatedType) {
Source source = addSource(code);
LibraryElement library = resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
SimpleIdentifier identifier = EngineTestCase.findNode(unit, code, "v = ", SimpleIdentifier);
@@ -888,7 +888,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class M {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_ambiguousExport_combinators_hide() {
@@ -899,7 +899,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library L1;", "class A {}", "class B {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library L2;", "class B {}", "class C {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_ambiguousExport_combinators_show() {
@@ -910,25 +910,25 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library L1;", "class A {}", "class B {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library L2;", "class B {}", "class C {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_argumentDefinitionTestNonParameter_formalParameter() {
Source source = addSource(EngineTestCase.createSource(["f(var v) {", " return ?v;", "}"]));
resolve(source);
- assertErrors([ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST]);
+ assertErrors(source, [ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST]);
verify([source]);
}
void test_argumentDefinitionTestNonParameter_namedParameter() {
Source source = addSource(EngineTestCase.createSource(["f({var v : 0}) {", " return ?v;", "}"]));
resolve(source);
- assertErrors([ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST]);
+ assertErrors(source, [ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST]);
verify([source]);
}
void test_argumentDefinitionTestNonParameter_optionalParameter() {
Source source = addSource(EngineTestCase.createSource(["f([var v]) {", " return ?v;", "}"]));
resolve(source);
- assertErrors([ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST]);
+ assertErrors(source, [ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST]);
verify([source]);
}
void test_argumentTypeNotAssignable_classWithCall_Function() {
@@ -945,7 +945,7 @@
" caller(new CallMeBack());",
" }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_functionParameter_generic() {
@@ -956,13 +956,13 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_typedef_generic() {
Source source = addSource(EngineTestCase.createSource(["typedef A<T>(T p);", "f(A<int> a) {", " a(1);", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_argumentTypeNotAssignable_Object_Function() {
@@ -972,7 +972,7 @@
"}",
"process(Object x) {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_argumentTypeNotAssignable_typedef_local() {
@@ -984,7 +984,7 @@
" a(1, '2');",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_argumentTypeNotAssignable_typedef_parameter() {
@@ -994,13 +994,13 @@
" a(1, '2');",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_assignmentToFinal_prefixNegate() {
Source source = addSource(EngineTestCase.createSource(["f() {", " final x = 0;", " -x;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_assignmentToFinals_importWithPrefix() {
@@ -1012,7 +1012,7 @@
"}"]));
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "bool x = false;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_breakWithoutLabelInSwitch() {
@@ -1026,13 +1026,13 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_builtInIdentifierAsType_dynamic() {
Source source = addSource(EngineTestCase.createSource(["f() {", " dynamic x;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_caseBlockNotTerminated() {
@@ -1058,7 +1058,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_caseBlockNotTerminated_lastCase() {
@@ -1070,7 +1070,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_caseExpressionTypeImplementsEquals_int() {
@@ -1082,7 +1082,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_caseExpressionTypeImplementsEquals_Object() {
@@ -1099,7 +1099,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_caseExpressionTypeImplementsEquals_String() {
@@ -1111,13 +1111,13 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_concreteClassWithAbstractMember() {
Source source = addSource(EngineTestCase.createSource(["abstract class A {", " m();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_conflictingInstanceGetterAndSuperclassMember_instance() {
@@ -1129,7 +1129,7 @@
" get v => 1;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_conflictingStaticGetterAndInstanceSetter_thisClass() {
@@ -1139,7 +1139,7 @@
" static set x(int p) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_conflictingStaticSetterAndInstanceMember_thisClass_method() {
@@ -1149,7 +1149,7 @@
" static set x(int p) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constConstructorWithNonConstSuper_redirectingFactory() {
@@ -1164,13 +1164,13 @@
" const factory C() = B;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constConstructorWithNonFinalField_finalInstanceVar() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final int x = 0;", " const A();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constConstructorWithNonFinalField_mixin() {
@@ -1182,13 +1182,13 @@
" const B();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constConstructorWithNonFinalField_static() {
Source source = addSource(EngineTestCase.createSource(["class A {", " static int x;", " const A();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constConstructorWithNonFinalField_syntheticField() {
@@ -1199,14 +1199,14 @@
" get x {return 0;}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constEval_propertyExtraction_fieldStatic_targetType() {
addSource2("/math.dart", EngineTestCase.createSource(["library math;", "const PI = 3.14;"]));
Source source = addSource(EngineTestCase.createSource(["import 'math.dart' as math;", "const C = math.PI;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constEval_propertyExtraction_methodStatic_targetType() {
@@ -1217,7 +1217,7 @@
"}",
"const C = A.m;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constEvalTypeBoolNumString_equal() {
@@ -1246,7 +1246,7 @@
" const B.n2(num p) : v = null == p;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constEvalTypeBoolNumString_notEqual() {
@@ -1275,7 +1275,19 @@
" const B.n2(num p) : v = null != p;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_constNotInitialized_field() {
+ Source source = addSource(EngineTestCase.createSource(["class A {", " static const int x = 0;", "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_constNotInitialized_local() {
+ Source source = addSource(EngineTestCase.createSource(["main() {", " const int x = 0;", "}"]));
+ resolve(source);
+ assertNoErrors(source);
verify([source]);
}
void test_constWithNonConstantArgument_literals() {
@@ -1285,7 +1297,7 @@
"}",
"f() { return const A(true, 0, 1.0, '2'); }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constWithTypeParameters_direct() {
@@ -1295,7 +1307,7 @@
" const A();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constWithUndefinedConstructor() {
@@ -1307,7 +1319,7 @@
" return const A.name();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_constWithUndefinedConstructorDefault() {
@@ -1319,25 +1331,25 @@
" return const A();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_defaultValueInFunctionTypeAlias() {
Source source = addSource(EngineTestCase.createSource(["typedef F([x]);"]));
resolve(source);
- assertErrors([]);
+ assertNoErrors(source);
verify([source]);
}
void test_defaultValueInFunctionTypedParameter_named() {
Source source = addSource(EngineTestCase.createSource(["f(g({p})) {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_defaultValueInFunctionTypedParameter_optional() {
Source source = addSource(EngineTestCase.createSource(["f(g([p])) {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_duplicateDefinition_emptyName() {
@@ -1347,45 +1359,45 @@
" 'b' : () {}",
"};"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_duplicateDefinition_getter() {
Source source = addSource(EngineTestCase.createSource(["bool get a => true;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_dynamicIdentifier() {
Source source = addSource(EngineTestCase.createSource(["main() {", " var v = dynamic;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_exportOfNonLibrary_libraryDeclared() {
Source source = addSource(EngineTestCase.createSource(["library L;", "export 'lib1.dart';"]));
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_exportOfNonLibrary_libraryNotDeclared() {
Source source = addSource(EngineTestCase.createSource(["library L;", "export 'lib1.dart';"]));
addSource2("/lib1.dart", EngineTestCase.createSource([""]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_extraPositionalArguments_function() {
Source source = addSource(EngineTestCase.createSource(["f(p1, p2) {}", "main() {", " f(1, 2);", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_extraPositionalArguments_Function() {
Source source = addSource(EngineTestCase.createSource(["f(Function a) {", " a(1, 2);", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_extraPositionalArguments_typedef_local() {
@@ -1397,13 +1409,13 @@
" a(1, 2);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_extraPositionalArguments_typedef_parameter() {
Source source = addSource(EngineTestCase.createSource(["typedef A(p1, p2);", "f(A a) {", " a(1, 2);", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_fieldInitializedByMultipleInitializers() {
@@ -1414,31 +1426,31 @@
" A() : x = 0, y = 0 {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_fieldInitializedInInitializerAndDeclaration_fieldNotFinal() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x = 0;", " A() : x = 1 {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_fieldInitializedInInitializerAndDeclaration_finalFieldNotSet() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final int x;", " A() : x = 1 {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_fieldInitializerOutsideConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A(this.x) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_fieldInitializerOutsideConstructor_defaultParameters() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A([this.x]) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_fieldInitializerRedirectingConstructor_super() {
@@ -1451,31 +1463,31 @@
" B(this.x) : super();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_finalInitializedInDeclarationAndConstructor_initializer() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final x;", " A() : x = 1 {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_finalInitializedInDeclarationAndConstructor_initializingFormal() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final x;", " A(this.x) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_finalNotInitialized_atDeclaration() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final int x = 0;", " A() {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_finalNotInitialized_fieldFormal() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final int x = 0;", " A() {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_finalNotInitialized_functionTypedFieldFormal() {
@@ -1485,7 +1497,7 @@
" A(int this.x(int p)) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_finalNotInitialized_hasNativeClause_hasConstructor() {
@@ -1495,19 +1507,19 @@
" A() {}",
"}"]));
resolve(source);
- assertErrors([ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
+ assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
verify([source]);
}
void test_finalNotInitialized_hasNativeClause_noConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A native 'something' {", " final int x;", "}"]));
resolve(source);
- assertErrors([ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
+ assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
verify([source]);
}
void test_finalNotInitialized_initializer() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final int x;", " A() : x = 0 {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_finalNotInitialized_redirectingConstructor() {
@@ -1518,7 +1530,7 @@
" A.named() : this (42);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_constructorName() {
@@ -1531,7 +1543,7 @@
" B() : v = new A.named();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_prefixedIdentifier() {
@@ -1544,7 +1556,7 @@
" B(A a) : v = a.f;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_qualifiedMethodInvocation() {
@@ -1557,7 +1569,7 @@
" B() : v = new A().f();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_qualifiedPropertyAccess() {
@@ -1570,7 +1582,7 @@
" B() : v = new A().f;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_staticField_thisClass() {
@@ -1581,7 +1593,7 @@
" static var f;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_staticGetter() {
@@ -1592,7 +1604,7 @@
" static get f => 42;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_staticMethod() {
@@ -1603,7 +1615,7 @@
" static f() => 42;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_topLevelField() {
@@ -1614,7 +1626,7 @@
"}",
"var f = 42;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_topLevelFunction() {
@@ -1625,7 +1637,7 @@
"}",
"f() => 42;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_implicitThisReferenceInInitializer_topLevelGetter() {
@@ -1636,13 +1648,13 @@
"}",
"get f => 42;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
- void test_implicitThisReferenceInInitializer_typeVariable() {
+ void test_implicitThisReferenceInInitializer_typeParameter() {
Source source = addSource(EngineTestCase.createSource(["class A<T> {", " var v;", " A(p) : v = (p is T);", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_importDuplicatedLibraryName() {
@@ -1652,21 +1664,24 @@
"import 'lib.dart';"]));
addSource2("/lib.dart", "library lib;");
resolve(source);
- assertErrors([HintCode.UNUSED_IMPORT, HintCode.UNUSED_IMPORT]);
+ assertErrors(source, [
+ HintCode.UNUSED_IMPORT,
+ HintCode.UNUSED_IMPORT,
+ HintCode.DUPLICATE_IMPORT]);
verify([source]);
}
void test_importOfNonLibrary_libraryDeclared() {
Source source = addSource(EngineTestCase.createSource(["library lib;", "import 'part.dart';", "A a;"]));
addSource2("/part.dart", EngineTestCase.createSource(["library lib1;", "class A {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_importOfNonLibrary_libraryNotDeclared() {
Source source = addSource(EngineTestCase.createSource(["library lib;", "import 'part.dart';", "A a;"]));
addSource2("/part.dart", EngineTestCase.createSource(["class A {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_inconsistentCaseExpressionTypes() {
@@ -1680,10 +1695,24 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
- void test_inconsistentMethodInheritance_accessors_typeVariables_diamond() {
+ void test_inconsistentMethodInheritance_accessors_typeParameter2() {
+ Source source = addSource(EngineTestCase.createSource([
+ "abstract class A<E> {",
+ " E get x {return 1;}",
+ "}",
+ "class B<E> {",
+ " E get x {return 1;}",
+ "}",
+ "class C<E> extends A<E> implements B<E> {",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_inconsistentMethodInheritance_accessors_typeParameters_diamond() {
Source source = addSource(EngineTestCase.createSource([
"abstract class F<E> extends B<E> {}",
"class D<E> extends F<E> {",
@@ -1698,10 +1727,10 @@
"class A<E> extends B<E> implements D<E> {",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
- void test_inconsistentMethodInheritance_accessors_typeVariables1() {
+ void test_inconsistentMethodInheritance_accessors_typeParameters1() {
Source source = addSource(EngineTestCase.createSource([
"abstract class A<E> {",
" E get x;",
@@ -1713,24 +1742,25 @@
" E get x => 1;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
- void test_inconsistentMethodInheritance_accessors_typeVariables2() {
+ void test_inconsistentMethodInheritance_methods_typeParameter2() {
Source source = addSource(EngineTestCase.createSource([
- "abstract class A<E> {",
- " E get x {return 1;}",
+ "class A<E> {",
+ " x(E e) {}",
"}",
"class B<E> {",
- " E get x {return 1;}",
+ " x(E e) {}",
"}",
"class C<E> extends A<E> implements B<E> {",
+ " x(E e) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
- void test_inconsistentMethodInheritance_methods_typeVariables1() {
+ void test_inconsistentMethodInheritance_methods_typeParameters1() {
Source source = addSource(EngineTestCase.createSource([
"class A<E> {",
" x(E e) {}",
@@ -1742,22 +1772,7 @@
" x(E e) {}",
"}"]));
resolve(source);
- assertNoErrors();
- verify([source]);
- }
- void test_inconsistentMethodInheritance_methods_typeVariables2() {
- Source source = addSource(EngineTestCase.createSource([
- "class A<E> {",
- " x(E e) {}",
- "}",
- "class B<E> {",
- " x(E e) {}",
- "}",
- "class C<E> extends A<E> implements B<E> {",
- " x(E e) {}",
- "}"]));
- resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_inconsistentMethodInheritance_simple() {
@@ -1772,13 +1787,13 @@
" x() {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_initializingFormalForNonExistantField() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A(this.x) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_instanceAccessToStaticMember_fromComment() {
@@ -1790,13 +1805,13 @@
"main() {",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_instanceAccessToStaticMember_topLevel() {
Source source = addSource(EngineTestCase.createSource(["m() {}", "main() {", " m();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_instanceMemberAccessFromStatic_fromComment() {
@@ -1808,20 +1823,20 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidAnnotation_constantVariable() {
Source source = addSource(EngineTestCase.createSource(["const C = 0;", "@C", "main() {", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidAnnotation_importWithPrefix_constantVariable() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "const C = 0;"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as p;", "@p.C", "main() {", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidAnnotation_importWithPrefix_constConstructor() {
@@ -1836,13 +1851,13 @@
"main() {",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidAssignment() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var x;", " var y;", " x = y;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidAssignment_compoundAssignment() {
@@ -1858,31 +1873,31 @@
" b += 3;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidAssignment_defaultValue_named() {
Source source = addSource(EngineTestCase.createSource(["f({String x: '0'}) {", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidAssignment_defaultValue_optional() {
Source source = addSource(EngineTestCase.createSource(["f([String x = '0']) {", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidAssignment_toDynamic() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var g;", " g = () => 0;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidFactoryNameNotAClass() {
Source source = addSource(EngineTestCase.createSource(["class A {", " factory A() {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidMethodOverrideNamedParamType() {
@@ -1894,7 +1909,7 @@
" m({int a, int b}) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideDifferentDefaultValues_named() {
@@ -1906,7 +1921,7 @@
" m({int p : 0}) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideDifferentDefaultValues_positional() {
@@ -1918,7 +1933,7 @@
" m([int p = 0]) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideDifferentDefaultValues_positional_changedOrder() {
@@ -1930,7 +1945,7 @@
" m([int b = 0, String a = '0']) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideNamed_unorderedNamedParameter() {
@@ -1942,7 +1957,31 @@
" m({b, a}) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_invalidOverrideRequired_less() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {",
+ " m(a, b) {}",
+ "}",
+ "class B extends A {",
+ " m(a) {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_invalidOverrideRequired_same() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {",
+ " m(a) {}",
+ "}",
+ "class B extends A {",
+ " m(a) {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideReturnType_returnType_interface() {
@@ -1954,7 +1993,7 @@
" int m() { return 1; }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideReturnType_returnType_interface2() {
@@ -1968,7 +2007,7 @@
" int m() { return 1; }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideReturnType_returnType_mixin() {
@@ -1980,7 +2019,7 @@
" int m() { return 1; }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideReturnType_returnType_parameterizedTypes() {
@@ -1992,7 +2031,7 @@
" List<dynamic> m() { return new List<dynamic>(); }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideReturnType_returnType_sameType() {
@@ -2004,7 +2043,7 @@
" int m() { return 1; }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideReturnType_returnType_superclass() {
@@ -2016,7 +2055,7 @@
" int m() { return 1; }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideReturnType_returnType_superclass2() {
@@ -2030,7 +2069,7 @@
" int m() { return 1; }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidOverrideReturnType_returnType_void() {
@@ -2042,19 +2081,19 @@
" int m() {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidReferenceToThis_constructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() {", " var v = this;", " }", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidReferenceToThis_instanceMethod() {
Source source = addSource(EngineTestCase.createSource(["class A {", " m() {", " var v = this;", " }", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidTypeArgumentForKey() {
@@ -2065,7 +2104,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidTypeArgumentInConstList() {
@@ -2076,7 +2115,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invalidTypeArgumentInConstMap() {
@@ -2087,7 +2126,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invocationOfNonFunction_dynamic() {
@@ -2101,7 +2140,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invocationOfNonFunction_getter() {
@@ -2114,19 +2153,19 @@
" a.g();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invocationOfNonFunction_localVariable() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var g;", " g();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invocationOfNonFunction_localVariable_dynamic() {
Source source = addSource(EngineTestCase.createSource(["f() {}", "main() {", " var v = f;", " v();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invocationOfNonFunction_localVariable_dynamic2() {
@@ -2138,31 +2177,31 @@
" v();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invocationOfNonFunction_Object() {
Source source = addSource(EngineTestCase.createSource(["main() {", " Object v = null;", " v();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_listElementTypeNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["var v1 = <int> [42];", "var v2 = const <int> [42];"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_mapKeyTypeNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["var v = <String, int > {'a' : 1};"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_memberWithClassName_setter() {
Source source = addSource(EngineTestCase.createSource(["class A {", " set A(v) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_misMatchedGetterAndSetterTypes_instance_sameTypes() {
@@ -2172,37 +2211,37 @@
" set x(int v) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_misMatchedGetterAndSetterTypes_instance_unspecifiedGetter() {
Source source = addSource(EngineTestCase.createSource(["class C {", " get x => 0;", " set x(String v) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_misMatchedGetterAndSetterTypes_instance_unspecifiedSetter() {
Source source = addSource(EngineTestCase.createSource(["class C {", " int get x => 0;", " set x(v) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_misMatchedGetterAndSetterTypes_topLevel_sameTypes() {
Source source = addSource(EngineTestCase.createSource(["int get x => 0;", "set x(int v) {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_misMatchedGetterAndSetterTypes_topLevel_unspecifiedGetter() {
Source source = addSource(EngineTestCase.createSource(["get x => 0;", "set x(String v) {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_misMatchedGetterAndSetterTypes_topLevel_unspecifiedSetter() {
Source source = addSource(EngineTestCase.createSource(["int get x => 0;", "set x(v) {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_mixinDeclaresConstructor() {
@@ -2212,7 +2251,7 @@
"}",
"class B extends Object with A {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_mixinDeclaresConstructor_factory() {
@@ -2222,7 +2261,7 @@
"}",
"class B extends Object with A {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_mixinInheritsFromNotObject_classDeclaration_mixTypedef() {
@@ -2231,7 +2270,7 @@
"typedef B = Object with A;",
"class C extends Object with B {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_mixinInheritsFromNotObject_typedef_mixTypedef() {
@@ -2240,13 +2279,13 @@
"typedef B = Object with A;",
"typedef C = Object with B;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_multipleSuperInitializers_no() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "class B extends A {", " B() {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_multipleSuperInitializers_single() {
@@ -2256,7 +2295,7 @@
" B() : super() {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_newWithAbstractClass_factory() {
@@ -2271,7 +2310,7 @@
" return new A();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_newWithUndefinedConstructor() {
@@ -2283,13 +2322,13 @@
" new A.name();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_newWithUndefinedConstructorDefault() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() {}", "}", "f() {", " new A();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_accessor() {
@@ -2303,7 +2342,7 @@
"class C extends B {",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_method() {
@@ -2317,7 +2356,7 @@
"class C extends B {",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonBoolExpression_functionType() {
@@ -2327,49 +2366,49 @@
" assert(makeAssertion);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonBoolExpression_interfaceType() {
Source source = addSource(EngineTestCase.createSource(["f() {", " assert(true);", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstantDefaultValue_function_named() {
Source source = addSource(EngineTestCase.createSource(["f({x : 2 + 3}) {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstantDefaultValue_function_positional() {
Source source = addSource(EngineTestCase.createSource(["f([x = 2 + 3]) {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstantDefaultValue_inConstructor_named() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A({x : 2 + 3}) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstantDefaultValue_inConstructor_positional() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A([x = 2 + 3]) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstantDefaultValue_method_named() {
Source source = addSource(EngineTestCase.createSource(["class A {", " m({x : 2 + 3}) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstantDefaultValue_method_positional() {
Source source = addSource(EngineTestCase.createSource(["class A {", " m([x = 2 + 3]) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstantValueInInitializer_namedArgument() {
@@ -2382,7 +2421,7 @@
" const B({b}) : super(a: b);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstCaseExpression() {
@@ -2397,25 +2436,25 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstMapAsExpressionStatement_const() {
Source source = addSource(EngineTestCase.createSource(["f() {", " const {'a' : 0, 'b' : 1};", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstMapAsExpressionStatement_notExpressionStatement() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var m = {'a' : 0, 'b' : 1};", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstMapAsExpressionStatement_typeArguments() {
Source source = addSource(EngineTestCase.createSource(["f() {", " <String, int> {'a' : 0, 'b' : 1};", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstValueInInitializer_binary_bool() {
@@ -2428,7 +2467,7 @@
" const A.b2(bool p) : v = true || p;",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_nonConstValueInInitializer_binary_dynamic() {
@@ -2457,7 +2496,7 @@
" const A.j2(p) : v = 5 % p;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_nonConstValueInInitializer_binary_int() {
Source source = addSource(EngineTestCase.createSource([
@@ -2475,7 +2514,7 @@
" const A.e2(int p) : v = 5 << p;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstValueInInitializer_binary_num() {
@@ -2504,7 +2543,7 @@
" const A.j2(num p) : v = 5 % p;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstValueInInitializer_field() {
@@ -2514,7 +2553,7 @@
" const A() : a = 5;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstValueInInitializer_redirecting() {
@@ -2524,7 +2563,7 @@
" const A() : this.named(42);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstValueInInitializer_super() {
@@ -2536,7 +2575,7 @@
" const B() : super(42);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonConstValueInInitializer_unary() {
@@ -2548,7 +2587,7 @@
" const A.c(num p) : v = -p;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonGenerativeConstructor() {
@@ -2561,7 +2600,7 @@
" B() : super.named();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonTypeInCatchClause_isClass() {
@@ -2572,7 +2611,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonTypeInCatchClause_isFunctionTypeAlias() {
@@ -2584,10 +2623,10 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
- void test_nonTypeInCatchClause_isTypeVariable() {
+ void test_nonTypeInCatchClause_isTypeParameter() {
Source source = addSource(EngineTestCase.createSource([
"class A<T> {",
" f() {",
@@ -2597,55 +2636,55 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonTypeInCatchClause_noType() {
Source source = addSource(EngineTestCase.createSource(["f() {", " try {", " } catch (e) {", " }", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonVoidReturnForOperator_no() {
Source source = addSource(EngineTestCase.createSource(["class A {", " operator []=(a, b) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonVoidReturnForOperator_void() {
Source source = addSource(EngineTestCase.createSource(["class A {", " void operator []=(a, b) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonVoidReturnForSetter_function_no() {
Source source = addSource("set x(v) {}");
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonVoidReturnForSetter_function_void() {
Source source = addSource("void set x(v) {}");
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonVoidReturnForSetter_method_no() {
Source source = addSource(EngineTestCase.createSource(["class A {", " set x(v) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_nonVoidReturnForSetter_method_void() {
Source source = addSource(EngineTestCase.createSource(["class A {", " void set x(v) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_optionalParameterInOperator_required() {
Source source = addSource(EngineTestCase.createSource(["class A {", " operator +(p) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_prefixCollidesWithTopLevelMembers() {
@@ -2658,7 +2697,7 @@
"class p4 {}",
"p.A a;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_proxy_annotation_prefixed() {
@@ -2680,7 +2719,7 @@
"const proxy = const _Proxy();",
"class _Proxy { const _Proxy(); }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_proxy_annotation_prefixed2() {
Source source = addSource(EngineTestCase.createSource([
@@ -2703,7 +2742,7 @@
"const proxy = const _Proxy();",
"class _Proxy { const _Proxy(); }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_proxy_annotation_prefixed3() {
Source source = addSource(EngineTestCase.createSource([
@@ -2726,7 +2765,7 @@
"const proxy = const _Proxy();",
"class _Proxy { const _Proxy(); }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_proxy_annotation_simple() {
Source source = addSource(EngineTestCase.createSource([
@@ -2746,7 +2785,7 @@
"const proxy = const _Proxy();",
"class _Proxy { const _Proxy(); }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_recursiveConstructorRedirect() {
Source source = addSource(EngineTestCase.createSource([
@@ -2756,7 +2795,7 @@
" A.c() {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_recursiveFactoryRedirect() {
@@ -2771,7 +2810,7 @@
" factory C() {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_redirectToInvalidFunctionType() {
@@ -2783,7 +2822,7 @@
" factory B(int p) = A;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_redirectToNonConstConstructor() {
@@ -2793,7 +2832,7 @@
" const factory A.b() = A.a;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_referenceToDeclaredVariableInInitializer_constructorName() {
@@ -2805,7 +2844,7 @@
" var x = new A.x();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_referenceToDeclaredVariableInInitializer_methodName() {
@@ -2817,7 +2856,7 @@
" var x = a.x();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_referenceToDeclaredVariableInInitializer_propertyName() {
@@ -2829,7 +2868,7 @@
" var x = a.x;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_rethrowOutsideCatch() {
@@ -2840,13 +2879,13 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_returnInGenerativeConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() { return; }", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_returnOfInvalidType_dynamic() {
@@ -2864,7 +2903,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_returnOfInvalidType_dynamicAsTypeArgument() {
@@ -2875,7 +2914,7 @@
"class A<T> implements I {",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_returnOfInvalidType_subtype() {
@@ -2884,7 +2923,7 @@
"class B extends A {}",
"A f(B b) { return b; }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_returnOfInvalidType_supertype() {
@@ -2893,7 +2932,7 @@
"class B extends A {}",
"B f(A a) { return a; }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_returnOfInvalidType_void() {
@@ -2907,19 +2946,19 @@
"void g2() {}",
""]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_returnWithoutValue_noReturnType() {
Source source = addSource(EngineTestCase.createSource(["f() { return; }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_returnWithoutValue_void() {
Source source = addSource(EngineTestCase.createSource(["void f() { return; }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_staticAccessToInstanceMember_annotation() {
@@ -2931,7 +2970,7 @@
"main() {",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_staticAccessToInstanceMember_method() {
@@ -2944,7 +2983,7 @@
" A.m();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_staticAccessToInstanceMember_propertyAccess_field() {
@@ -2957,7 +2996,7 @@
" A.f = 1;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_staticAccessToInstanceMember_propertyAccess_propertyAccessor() {
@@ -2971,7 +3010,7 @@
" A.f = 1;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_superInInvalidContext() {
@@ -2988,19 +3027,19 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_typeAliasCannotReferenceItself_returnClass_withTypeAlias() {
Source source = addSource(EngineTestCase.createSource(["typedef B A();", "class B {", " A a;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
- void test_typeAliasCannotReferenceItself_typeVariableBounds() {
+ void test_typeAliasCannotReferenceItself_typeParameterBounds() {
Source source = addSource(EngineTestCase.createSource(["typedef A<T extends A>();"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_const() {
@@ -3012,7 +3051,7 @@
"}",
"f() { return const G<B>(); }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_new() {
@@ -3022,25 +3061,25 @@
"class G<E extends A> {}",
"f() { return new G<B>(); }"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_typeArgumentList_0() {
Source source = addSource(EngineTestCase.createSource(["abstract class A<T extends A>{}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_typeArgumentList_1() {
Source source = addSource(EngineTestCase.createSource(["abstract class A<T extends A<A>>{}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_typeArgumentList_20() {
Source source = addSource(EngineTestCase.createSource(["abstract class A<T extends A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A>>>>>>>>>>>>>>>>>>>>>{}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedConstructorInInitializer_explicit_named() {
@@ -3052,7 +3091,7 @@
" B() : super.named();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedConstructorInInitializer_explicit_unnamed() {
@@ -3064,7 +3103,7 @@
" B() : super();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedConstructorInInitializer_hasOptionalParameters() {
@@ -3076,7 +3115,7 @@
" B();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedConstructorInInitializer_implicit() {
@@ -3088,7 +3127,7 @@
" B();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedConstructorInInitializer_implicit_typedef() {
@@ -3099,7 +3138,7 @@
" B();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedConstructorInInitializer_redirecting() {
@@ -3112,7 +3151,7 @@
" Bar.ctor() : super.ctor();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedGetter_typeSubstitution() {
@@ -3126,32 +3165,32 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedIdentifier_hide() {
Source source = addSource(EngineTestCase.createSource(["library L;", "export 'lib1.dart' hide a;"]));
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedIdentifier_show() {
Source source = addSource(EngineTestCase.createSource(["library L;", "export 'lib1.dart' show a;"]));
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedMethod_functionExpression_callMethod() {
Source source = addSource(EngineTestCase.createSource(["main() {", " (() => null).call();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_undefinedMethod_functionExpression_directCall() {
Source source = addSource(EngineTestCase.createSource(["main() {", " (() => null)();", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_undefinedOperator_index() {
Source source = addSource(EngineTestCase.createSource([
@@ -3164,20 +3203,20 @@
" a[0] = 1;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedOperator_tilde() {
Source source = addSource(EngineTestCase.createSource(["const A = 3;", "const B = ~((1 << A) - 1);"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedSetter_importWithPrefix() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "set y(int value) {}"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as x;", "main() {", " x.y = 0;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedSuperMethod_field() {
@@ -3191,7 +3230,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_undefinedSuperMethod_method() {
@@ -3205,13 +3244,13 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_wrongNumberOfParametersForOperator_index() {
Source source = addSource(EngineTestCase.createSource(["class A {", " operator []=(a, b) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_wrongNumberOfParametersForOperator_minus() {
@@ -3238,13 +3277,13 @@
void test_wrongNumberOfParametersForSetter() {
Source source = addSource(EngineTestCase.createSource(["class A {", " set x(a) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void check_wrongNumberOfParametersForOperator(String name, String parameters) {
Source source = addSource(EngineTestCase.createSource(["class A {", " operator ${name}(${parameters}) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
reset();
}
@@ -3389,6 +3428,14 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_constEval_propertyExtraction_methodStatic_targetType);
});
+ _ut.test('test_constNotInitialized_field', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_constNotInitialized_field);
+ });
+ _ut.test('test_constNotInitialized_local', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_constNotInitialized_local);
+ });
_ut.test('test_constWithNonConstantArgument_literals', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_constWithNonConstantArgument_literals);
@@ -3553,9 +3600,9 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_topLevelGetter);
});
- _ut.test('test_implicitThisReferenceInInitializer_typeVariable', () {
+ _ut.test('test_implicitThisReferenceInInitializer_typeParameter', () {
final __test = new NonErrorResolverTest();
- runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_typeVariable);
+ runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_typeParameter);
});
_ut.test('test_importDuplicatedLibraryName', () {
final __test = new NonErrorResolverTest();
@@ -3573,25 +3620,25 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_inconsistentCaseExpressionTypes);
});
- _ut.test('test_inconsistentMethodInheritance_accessors_typeVariables1', () {
+ _ut.test('test_inconsistentMethodInheritance_accessors_typeParameter2', () {
final __test = new NonErrorResolverTest();
- runJUnitTest(__test, __test.test_inconsistentMethodInheritance_accessors_typeVariables1);
+ runJUnitTest(__test, __test.test_inconsistentMethodInheritance_accessors_typeParameter2);
});
- _ut.test('test_inconsistentMethodInheritance_accessors_typeVariables2', () {
+ _ut.test('test_inconsistentMethodInheritance_accessors_typeParameters1', () {
final __test = new NonErrorResolverTest();
- runJUnitTest(__test, __test.test_inconsistentMethodInheritance_accessors_typeVariables2);
+ runJUnitTest(__test, __test.test_inconsistentMethodInheritance_accessors_typeParameters1);
});
- _ut.test('test_inconsistentMethodInheritance_accessors_typeVariables_diamond', () {
+ _ut.test('test_inconsistentMethodInheritance_accessors_typeParameters_diamond', () {
final __test = new NonErrorResolverTest();
- runJUnitTest(__test, __test.test_inconsistentMethodInheritance_accessors_typeVariables_diamond);
+ runJUnitTest(__test, __test.test_inconsistentMethodInheritance_accessors_typeParameters_diamond);
});
- _ut.test('test_inconsistentMethodInheritance_methods_typeVariables1', () {
+ _ut.test('test_inconsistentMethodInheritance_methods_typeParameter2', () {
final __test = new NonErrorResolverTest();
- runJUnitTest(__test, __test.test_inconsistentMethodInheritance_methods_typeVariables1);
+ runJUnitTest(__test, __test.test_inconsistentMethodInheritance_methods_typeParameter2);
});
- _ut.test('test_inconsistentMethodInheritance_methods_typeVariables2', () {
+ _ut.test('test_inconsistentMethodInheritance_methods_typeParameters1', () {
final __test = new NonErrorResolverTest();
- runJUnitTest(__test, __test.test_inconsistentMethodInheritance_methods_typeVariables2);
+ runJUnitTest(__test, __test.test_inconsistentMethodInheritance_methods_typeParameters1);
});
_ut.test('test_inconsistentMethodInheritance_simple', () {
final __test = new NonErrorResolverTest();
@@ -3669,6 +3716,14 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_invalidOverrideNamed_unorderedNamedParameter);
});
+ _ut.test('test_invalidOverrideRequired_less', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_invalidOverrideRequired_less);
+ });
+ _ut.test('test_invalidOverrideRequired_same', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_invalidOverrideRequired_same);
+ });
_ut.test('test_invalidOverrideReturnType_returnType_interface', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_invalidOverrideReturnType_returnType_interface);
@@ -3921,9 +3976,9 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_nonTypeInCatchClause_isFunctionTypeAlias);
});
- _ut.test('test_nonTypeInCatchClause_isTypeVariable', () {
+ _ut.test('test_nonTypeInCatchClause_isTypeParameter', () {
final __test = new NonErrorResolverTest();
- runJUnitTest(__test, __test.test_nonTypeInCatchClause_isTypeVariable);
+ runJUnitTest(__test, __test.test_nonTypeInCatchClause_isTypeParameter);
});
_ut.test('test_nonTypeInCatchClause_noType', () {
final __test = new NonErrorResolverTest();
@@ -4065,9 +4120,9 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_typeAliasCannotReferenceItself_returnClass_withTypeAlias);
});
- _ut.test('test_typeAliasCannotReferenceItself_typeVariableBounds', () {
+ _ut.test('test_typeAliasCannotReferenceItself_typeParameterBounds', () {
final __test = new NonErrorResolverTest();
- runJUnitTest(__test, __test.test_typeAliasCannotReferenceItself_typeVariableBounds);
+ runJUnitTest(__test, __test.test_typeAliasCannotReferenceItself_typeParameterBounds);
});
_ut.test('test_typeArgumentNotMatchingBounds_const', () {
final __test = new NonErrorResolverTest();
@@ -4304,7 +4359,7 @@
void fail_inaccessibleSetter() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INACCESSIBLE_SETTER]);
+ assertErrors(source, [StaticTypeWarningCode.INACCESSIBLE_SETTER]);
verify([source]);
}
void test_inconsistentMethodInheritance_paramCount() {
@@ -4318,7 +4373,7 @@
"class C implements A, B {",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
+ assertErrors(source, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
verify([source]);
}
void test_inconsistentMethodInheritance_paramType() {
@@ -4331,7 +4386,7 @@
"}",
"abstract class C implements A, B {}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
+ assertErrors(source, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
verify([source]);
}
void test_inconsistentMethodInheritance_returnType() {
@@ -4344,7 +4399,7 @@
"}",
"abstract class C implements A, B {}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
+ assertErrors(source, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
verify([source]);
}
void test_instanceAccessToStaticMember_method_invocation() {
@@ -4356,7 +4411,7 @@
" a.m();",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+ assertErrors(source, [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
verify([source]);
}
void test_instanceAccessToStaticMember_method_reference() {
@@ -4368,7 +4423,7 @@
" a.m;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+ assertErrors(source, [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
verify([source]);
}
void test_instanceAccessToStaticMember_propertyAccess_field() {
@@ -4380,7 +4435,7 @@
" a.f;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+ assertErrors(source, [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
verify([source]);
}
void test_instanceAccessToStaticMember_propertyAccess_getter() {
@@ -4392,7 +4447,7 @@
" a.f;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+ assertErrors(source, [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
verify([source]);
}
void test_instanceAccessToStaticMember_propertyAccess_setter() {
@@ -4404,7 +4459,7 @@
" a.f = 42;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+ assertErrors(source, [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
verify([source]);
}
void test_invalidAssignment_compoundAssignment() {
@@ -4420,19 +4475,19 @@
" b += 3;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_invalidAssignment_defaultValue_named() {
Source source = addSource(EngineTestCase.createSource(["f({String x: 0}) {", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_invalidAssignment_defaultValue_optional() {
Source source = addSource(EngineTestCase.createSource(["f([String x = 0]) {", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_invalidAssignment_instanceVariable() {
@@ -4445,13 +4500,13 @@
" a.x = '0';",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_invalidAssignment_localVariable() {
Source source = addSource(EngineTestCase.createSource(["f() {", " int x;", " x = '0';", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_invalidAssignment_staticVariable() {
@@ -4463,30 +4518,30 @@
" A.x = '0';",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_invalidAssignment_topLevelVariableDeclaration() {
Source source = addSource(EngineTestCase.createSource(["int x = 'string';"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_invalidAssignment_variableDeclaration() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x = 'string';", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_invocationOfNonFunction_class() {
Source source = addSource(EngineTestCase.createSource(["class A {", " void m() {", " A();", " }", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+ assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
}
void test_invocationOfNonFunction_localVariable() {
Source source = addSource(EngineTestCase.createSource(["f() {", " int x;", " return x();", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+ assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
verify([source]);
}
void test_invocationOfNonFunction_ordinaryInvocation() {
@@ -4500,7 +4555,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+ assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
}
void test_invocationOfNonFunction_staticInvocation() {
Source source = addSource(EngineTestCase.createSource([
@@ -4511,7 +4566,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+ assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
}
void test_invocationOfNonFunction_superExpression() {
Source source = addSource(EngineTestCase.createSource([
@@ -4524,37 +4579,37 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+ assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
verify([source]);
}
void test_invocationOfNonFunctionExpression_literal() {
Source source = addSource(EngineTestCase.createSource(["f() {", " 3(5);", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION]);
+ assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION]);
verify([source]);
}
void test_nonBoolCondition_conditional() {
Source source = addSource(EngineTestCase.createSource(["f() { return 3 ? 2 : 1; }"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.NON_BOOL_CONDITION]);
+ assertErrors(source, [StaticTypeWarningCode.NON_BOOL_CONDITION]);
verify([source]);
}
void test_nonBoolCondition_do() {
Source source = addSource(EngineTestCase.createSource(["f() {", " do {} while (3);", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.NON_BOOL_CONDITION]);
+ assertErrors(source, [StaticTypeWarningCode.NON_BOOL_CONDITION]);
verify([source]);
}
void test_nonBoolCondition_if() {
Source source = addSource(EngineTestCase.createSource(["f() {", " if (3) return 2; else return 1;", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.NON_BOOL_CONDITION]);
+ assertErrors(source, [StaticTypeWarningCode.NON_BOOL_CONDITION]);
verify([source]);
}
void test_nonBoolCondition_while() {
Source source = addSource(EngineTestCase.createSource(["f() {", " while (3) {}", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.NON_BOOL_CONDITION]);
+ assertErrors(source, [StaticTypeWarningCode.NON_BOOL_CONDITION]);
verify([source]);
}
void test_nonBoolExpression_functionType() {
@@ -4564,37 +4619,37 @@
" assert(makeAssertion);",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
+ assertErrors(source, [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
verify([source]);
}
void test_nonBoolExpression_interfaceType() {
Source source = addSource(EngineTestCase.createSource(["f() {", " assert(0);", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
+ assertErrors(source, [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
verify([source]);
}
void test_nonTypeAsTypeArgument_notAType() {
Source source = addSource(EngineTestCase.createSource(["int A;", "class B<E> {}", "f(B<A> b) {}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
+ assertErrors(source, [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
verify([source]);
}
void test_nonTypeAsTypeArgument_undefinedIdentifier() {
Source source = addSource(EngineTestCase.createSource(["class B<E> {}", "f(B<A> b) {}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
+ assertErrors(source, [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
verify([source]);
}
void test_returnOfInvalidType_expressionFunctionBody_function() {
Source source = addSource(EngineTestCase.createSource(["int f() => '0';"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_expressionFunctionBody_getter() {
Source source = addSource(EngineTestCase.createSource(["int get g => '0';"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_expressionFunctionBody_localFunction() {
@@ -4605,31 +4660,31 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_expressionFunctionBody_method() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int f() => '0';", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_expressionFunctionBody_void() {
Source source = addSource(EngineTestCase.createSource(["void f() => 42;"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_function() {
Source source = addSource(EngineTestCase.createSource(["int f() { return '0'; }"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_getter() {
Source source = addSource(EngineTestCase.createSource(["int get g { return '0'; }"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_localFunction() {
@@ -4640,19 +4695,19 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_method() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int f() { return '0'; }", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_returnOfInvalidType_void() {
Source source = addSource(EngineTestCase.createSource(["void f() { return 42; }"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_classTypeAlias() {
@@ -4663,7 +4718,7 @@
"class G<E extends A> {}",
"typedef D = G<B> with C;"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_extends() {
@@ -4673,7 +4728,7 @@
"class G<E extends A> {}",
"class C extends G<B>{}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_fieldFormalParameter() {
@@ -4686,7 +4741,7 @@
" C(G<B> this.f) {}",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_functionReturnType() {
@@ -4696,7 +4751,7 @@
"class G<E extends A> {}",
"G<B> f() {}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_functionTypeAlias() {
@@ -4706,7 +4761,7 @@
"class G<E extends A> {}",
"typedef G<B> f();"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_functionTypedFormalParameter() {
@@ -4716,7 +4771,7 @@
"class G<E extends A> {}",
"f(G<B> h()) {}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_implements() {
@@ -4726,7 +4781,7 @@
"class G<E extends A> {}",
"class C implements G<B>{}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_is() {
@@ -4736,7 +4791,7 @@
"class G<E extends A> {}",
"var b = 1 is G<B>;"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_methodReturnType() {
@@ -4748,7 +4803,7 @@
" G<B> m() {}",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_new() {
@@ -4758,7 +4813,7 @@
"class G<E extends A> {}",
"f() { return new G<B>(); }"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_new_superTypeOfUpperBound() {
@@ -4769,7 +4824,7 @@
"class G<E extends B> {}",
"f() { return new G<A>(); }"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_parameter() {
@@ -4779,7 +4834,7 @@
"class G<E extends A> {}",
"f(G<B> g) {}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_redirectingConstructor() {
@@ -4791,7 +4846,7 @@
" factory X.name(int x, int y) = X<B>;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_typeArgumentList() {
@@ -4802,7 +4857,7 @@
"class D<E extends A> {}",
"C<D<B>> Var;"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_typeParameter() {
@@ -4813,7 +4868,7 @@
"class G<E extends A> {}",
"class D<F extends G<B>> {}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_variableDeclaration() {
@@ -4823,7 +4878,7 @@
"class G<E extends A> {}",
"G<B> g;"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_typeArgumentNotMatchingBounds_with() {
@@ -4833,23 +4888,23 @@
"class G<E extends A> {}",
"class C extends Object with G<B>{}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_undefinedGetter() {
Source source = addSource(EngineTestCase.createSource(["class T {}", "f(T e) { return e.m; }"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_GETTER]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
void test_undefinedGetter_static() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "var a = A.B;"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_GETTER]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
void test_undefinedMethod() {
Source source = addSource(EngineTestCase.createSource(["class A {", " void m() {", " n();", " }", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_METHOD]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
}
void test_undefinedMethod_ignoreTypePropagation() {
Source source = addSource(EngineTestCase.createSource([
@@ -4864,39 +4919,39 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_METHOD]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
}
void test_undefinedOperator_indexBoth() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", " a[0]++;", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
StaticTypeWarningCode.UNDEFINED_OPERATOR,
StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_undefinedOperator_indexGetter() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", " a[0];", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_undefinedOperator_indexSetter() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", " a[0] = 1;", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_undefinedOperator_plus() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", " a + 1;", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_undefinedSetter() {
Source source = addSource(EngineTestCase.createSource(["class T {}", "f(T e1) { e1.m = 0; }"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_SETTER]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
}
void test_undefinedSetter_static() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "f() { A.B = 0;}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_SETTER]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
}
void test_undefinedSuperMethod() {
Source source = addSource(EngineTestCase.createSource([
@@ -4905,7 +4960,7 @@
" m() { return super.m(); }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
}
void test_unqualifiedReferenceToNonLocalStaticMember_getter() {
Source source = addSource(EngineTestCase.createSource([
@@ -4918,7 +4973,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
+ assertErrors(source, [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
verify([source]);
}
void test_unqualifiedReferenceToNonLocalStaticMember_method() {
@@ -4932,7 +4987,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
+ assertErrors(source, [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
verify([source]);
}
void test_unqualifiedReferenceToNonLocalStaticMember_setter() {
@@ -4946,19 +5001,19 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
+ assertErrors(source, [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
verify([source]);
}
void test_wrongNumberOfTypeArguments_tooFew() {
Source source = addSource(EngineTestCase.createSource(["class A<E, F> {}", "A<A> a = null;"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+ assertErrors(source, [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
verify([source]);
}
void test_wrongNumberOfTypeArguments_tooMany() {
Source source = addSource(EngineTestCase.createSource(["class A<E> {}", "A<A, A> a = null;"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+ assertErrors(source, [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
verify([source]);
}
void test_wrongNumberOfTypeArguments_typeTest_tooFew() {
@@ -4969,7 +5024,7 @@
" return p is C<A>;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+ assertErrors(source, [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
verify([source]);
}
void test_wrongNumberOfTypeArguments_typeTest_tooMany() {
@@ -4980,7 +5035,7 @@
" return p is C<A, A>;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+ assertErrors(source, [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
verify([source]);
}
static dartSuite() {
@@ -5289,64 +5344,82 @@
}
}
class HintCodeTest extends ResolverTestCase {
+ void fail_isInt() {
+ Source source = addSource(EngineTestCase.createSource(["var v = 1 is int;"]));
+ resolve(source);
+ assertErrors(source, [HintCode.IS_INT]);
+ verify([source]);
+ }
+ void fail_isNotInt() {
+ Source source = addSource(EngineTestCase.createSource(["var v = 1 is! int;"]));
+ resolve(source);
+ assertErrors(source, [HintCode.IS_NOT_INT]);
+ verify([source]);
+ }
+ void fail_overrideEqualsButNotHashCode() {
+ Source source = addSource(EngineTestCase.createSource(["class A {", " bool operator ==(x) {}", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
+ verify([source]);
+ }
void test_deadCode_deadBlock_conditionalElse() {
Source source = addSource(EngineTestCase.createSource(["f() {", " true ? 1 : 2;", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_conditionalElse_nested() {
Source source = addSource(EngineTestCase.createSource(["f() {", " true ? true : false && false;", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_conditionalIf() {
Source source = addSource(EngineTestCase.createSource(["f() {", " false ? 1 : 2;", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_conditionalIf_nested() {
Source source = addSource(EngineTestCase.createSource(["f() {", " false ? false && false : true;", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_else() {
Source source = addSource(EngineTestCase.createSource(["f() {", " if(true) {} else {}", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_else_nested() {
Source source = addSource(EngineTestCase.createSource(["f() {", " if(true) {} else {if (false) {}}", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_if() {
Source source = addSource(EngineTestCase.createSource(["f() {", " if(false) {}", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_if_nested() {
Source source = addSource(EngineTestCase.createSource(["f() {", " if(false) {if(false) {}}", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_while() {
Source source = addSource(EngineTestCase.createSource(["f() {", " while(false) {}", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadBlock_while_nested() {
Source source = addSource(EngineTestCase.createSource(["f() {", " while(false) {if(false) {}}", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadCatch_catchFollowingCatch() {
@@ -5356,7 +5429,7 @@
" try {} catch (e) {} catch (e) {}",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
+ assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
verify([source]);
}
void test_deadCode_deadCatch_catchFollowingCatch_nested() {
@@ -5366,7 +5439,7 @@
" try {} catch (e) {} catch (e) {if(false) {}}",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
+ assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
verify([source]);
}
void test_deadCode_deadCatch_catchFollowingCatch_object() {
@@ -5375,7 +5448,7 @@
" try {} on Object catch (e) {} catch (e) {}",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
+ assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
verify([source]);
}
void test_deadCode_deadCatch_catchFollowingCatch_object_nested() {
@@ -5384,7 +5457,7 @@
" try {} on Object catch (e) {} catch (e) {if(false) {}}",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
+ assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
verify([source]);
}
void test_deadCode_deadCatch_onCatchSubtype() {
@@ -5395,7 +5468,7 @@
" try {} on A catch (e) {} on B catch (e) {}",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
+ assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
verify([source]);
}
void test_deadCode_deadCatch_onCatchSubtype_nested() {
@@ -5406,31 +5479,31 @@
" try {} on A catch (e) {} on B catch (e) {if(false) {}}",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
+ assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
verify([source]);
}
void test_deadCode_deadOperandLHS_and() {
Source source = addSource(EngineTestCase.createSource(["f() {", " bool b = false && false;", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadOperandLHS_and_nested() {
Source source = addSource(EngineTestCase.createSource(["f() {", " bool b = false && (false && false);", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadOperandLHS_or() {
Source source = addSource(EngineTestCase.createSource(["f() {", " bool b = true || true;", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_deadOperandLHS_or_nested() {
Source source = addSource(EngineTestCase.createSource(["f() {", " bool b = true || (false && false);", "}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_statementAfterReturn_function() {
@@ -5441,7 +5514,7 @@
" var two = 2;",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_statementAfterReturn_ifStatement() {
@@ -5454,7 +5527,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_statementAfterReturn_method() {
@@ -5467,7 +5540,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_statementAfterReturn_nested() {
@@ -5478,7 +5551,7 @@
" if(false) {}",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
verify([source]);
}
void test_deadCode_statementAfterReturn_twoReturns() {
@@ -5491,15 +5564,202 @@
" var three = 3;",
"}"]));
resolve(source);
- assertErrors([HintCode.DEAD_CODE]);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+ void test_divisionOptimization_double() {
+ Source source = addSource(EngineTestCase.createSource([
+ "f(double x, double y) {",
+ " var v = (x / y).toInt();",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
+ verify([source]);
+ }
+ void test_divisionOptimization_int() {
+ Source source = addSource(EngineTestCase.createSource(["f(int x, int y) {", " var v = (x / y).toInt();", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
+ verify([source]);
+ }
+ void test_divisionOptimization_propagatedType() {
+ Source source = addSource(EngineTestCase.createSource([
+ "f(x, y) {",
+ " x = 1;",
+ " y = 1;",
+ " var v = (x / y).toInt();",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
+ verify([source]);
+ }
+ void test_divisionOptimization_wrappedBinaryExpression() {
+ Source source = addSource(EngineTestCase.createSource([
+ "f(int x, int y) {",
+ " var v = (((x / y))).toInt();",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
+ verify([source]);
+ }
+ void test_duplicateImport() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib1.dart';",
+ "import 'lib1.dart';",
+ "A a;"]));
+ addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
+ verify([source]);
+ }
+ void test_duplicateImport2() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib1.dart';",
+ "import 'lib1.dart';",
+ "import 'lib1.dart';",
+ "A a;"]));
+ addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
+ verify([source]);
+ }
+ void test_duplicateImport3() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib1.dart' as M show A hide B;",
+ "import 'lib1.dart' as M show A hide B;",
+ "M.A a;"]));
+ addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}", "class B {}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.DUPLICATE_IMPORT, HintCode.UNUSED_IMPORT]);
+ verify([source]);
+ }
+ void test_isDouble() {
+ Source source = addSource(EngineTestCase.createSource(["var v = 1 is double;"]));
+ resolve(source);
+ assertErrors(source, [HintCode.IS_DOUBLE]);
+ verify([source]);
+ }
+ void test_isNotDouble() {
+ Source source = addSource(EngineTestCase.createSource(["var v = 1 is! double;"]));
+ resolve(source);
+ assertErrors(source, [HintCode.IS_NOT_DOUBLE]);
+ verify([source]);
+ }
+ void test_overriddingPrivateMember_getter() {
+ Source source = addSource(EngineTestCase.createSource([
+ "import 'lib1.dart';",
+ "class B extends A {",
+ " get _g => 0;",
+ "}"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " get _g => 0;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+ verify([source, source2]);
+ }
+ void test_overriddingPrivateMember_method() {
+ Source source = addSource(EngineTestCase.createSource([
+ "import 'lib1.dart';",
+ "class B extends A {",
+ " _m(int x) => 0;",
+ "}"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " _m(int x) => 0;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+ verify([source, source2]);
+ }
+ void test_overriddingPrivateMember_method2() {
+ Source source = addSource(EngineTestCase.createSource([
+ "import 'lib1.dart';",
+ "class B extends A {}",
+ "class C extends B {",
+ " _m(int x) => 0;",
+ "}"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " _m(int x) => 0;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+ verify([source, source2]);
+ }
+ void test_overriddingPrivateMember_setter() {
+ Source source = addSource(EngineTestCase.createSource([
+ "import 'lib1.dart';",
+ "class B extends A {",
+ " set _s(int x) {}",
+ "}"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " set _s(int x) {}", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+ verify([source, source2]);
+ }
+ void test_typeCheck_type_is_Null() {
+ Source source = addSource(EngineTestCase.createSource(["m(i) {", " bool b = i is Null;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]);
+ verify([source]);
+ }
+ void test_typeCheck_type_not_Null() {
+ Source source = addSource(EngineTestCase.createSource(["m(i) {", " bool b = i is! Null;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
+ verify([source]);
+ }
+ void test_unnecessaryCast_type_supertype() {
+ Source source = addSource(EngineTestCase.createSource(["m(int i) {", " var b = i as Object;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNNECESSARY_CAST]);
+ verify([source]);
+ }
+ void test_unnecessaryCast_type_type() {
+ Source source = addSource(EngineTestCase.createSource(["m(num i) {", " var b = i as num;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNNECESSARY_CAST]);
+ verify([source]);
+ }
+ void test_unnecessaryTypeCheck_null_is_Null() {
+ Source source = addSource(EngineTestCase.createSource(["bool b = null is Null;"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+ verify([source]);
+ }
+ void test_unnecessaryTypeCheck_null_not_Null() {
+ Source source = addSource(EngineTestCase.createSource(["bool b = null is! Null;"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
+ verify([source]);
+ }
+ void test_unnecessaryTypeCheck_type_is_dynamic() {
+ Source source = addSource(EngineTestCase.createSource(["m(i) {", " bool b = i is dynamic;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+ verify([source]);
+ }
+ void test_unnecessaryTypeCheck_type_is_object() {
+ Source source = addSource(EngineTestCase.createSource(["m(i) {", " bool b = i is Object;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+ verify([source]);
+ }
+ void test_unnecessaryTypeCheck_type_not_dynamic() {
+ Source source = addSource(EngineTestCase.createSource(["m(i) {", " bool b = i is! dynamic;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
+ verify([source]);
+ }
+ void test_unnecessaryTypeCheck_type_not_object() {
+ Source source = addSource(EngineTestCase.createSource(["m(i) {", " bool b = i is! Object;", "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
verify([source]);
}
void test_unusedImport() {
Source source = addSource(EngineTestCase.createSource(["library L;", "import 'lib1.dart';"]));
- addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;"]));
resolve(source);
- assertErrors([HintCode.UNUSED_IMPORT]);
- verify([source]);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ verify([source, source2]);
}
void test_unusedImport_as() {
Source source = addSource(EngineTestCase.createSource([
@@ -5507,10 +5767,11 @@
"import 'lib1.dart';",
"import 'lib1.dart' as one;",
"one.A a;"]));
- addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}"]));
resolve(source);
- assertErrors([HintCode.UNUSED_IMPORT]);
- verify([source]);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ verify([source, source2]);
}
void test_unusedImport_hide() {
Source source = addSource(EngineTestCase.createSource([
@@ -5518,10 +5779,11 @@
"import 'lib1.dart';",
"import 'lib1.dart' hide A;",
"A a;"]));
- addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}"]));
resolve(source);
- assertErrors([HintCode.UNUSED_IMPORT]);
- verify([source]);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ verify([source, source2]);
}
void test_unusedImport_show() {
Source source = addSource(EngineTestCase.createSource([
@@ -5529,10 +5791,11 @@
"import 'lib1.dart' show A;",
"import 'lib1.dart' show B;",
"A a;"]));
- addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}", "class B {}"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}", "class B {}"]));
resolve(source);
- assertErrors([HintCode.UNUSED_IMPORT]);
- verify([source]);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ verify([source, source2]);
}
static dartSuite() {
_ut.group('HintCodeTest', () {
@@ -5636,6 +5899,98 @@
final __test = new HintCodeTest();
runJUnitTest(__test, __test.test_deadCode_statementAfterReturn_twoReturns);
});
+ _ut.test('test_divisionOptimization_double', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_divisionOptimization_double);
+ });
+ _ut.test('test_divisionOptimization_int', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_divisionOptimization_int);
+ });
+ _ut.test('test_divisionOptimization_propagatedType', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_divisionOptimization_propagatedType);
+ });
+ _ut.test('test_divisionOptimization_wrappedBinaryExpression', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_divisionOptimization_wrappedBinaryExpression);
+ });
+ _ut.test('test_duplicateImport', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_duplicateImport);
+ });
+ _ut.test('test_duplicateImport2', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_duplicateImport2);
+ });
+ _ut.test('test_duplicateImport3', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_duplicateImport3);
+ });
+ _ut.test('test_isDouble', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_isDouble);
+ });
+ _ut.test('test_isNotDouble', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_isNotDouble);
+ });
+ _ut.test('test_overriddingPrivateMember_getter', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_overriddingPrivateMember_getter);
+ });
+ _ut.test('test_overriddingPrivateMember_method', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_overriddingPrivateMember_method);
+ });
+ _ut.test('test_overriddingPrivateMember_method2', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_overriddingPrivateMember_method2);
+ });
+ _ut.test('test_overriddingPrivateMember_setter', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_overriddingPrivateMember_setter);
+ });
+ _ut.test('test_typeCheck_type_is_Null', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_typeCheck_type_is_Null);
+ });
+ _ut.test('test_typeCheck_type_not_Null', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_typeCheck_type_not_Null);
+ });
+ _ut.test('test_unnecessaryCast_type_supertype', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryCast_type_supertype);
+ });
+ _ut.test('test_unnecessaryCast_type_type', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryCast_type_type);
+ });
+ _ut.test('test_unnecessaryTypeCheck_null_is_Null', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryTypeCheck_null_is_Null);
+ });
+ _ut.test('test_unnecessaryTypeCheck_null_not_Null', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryTypeCheck_null_not_Null);
+ });
+ _ut.test('test_unnecessaryTypeCheck_type_is_dynamic', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryTypeCheck_type_is_dynamic);
+ });
+ _ut.test('test_unnecessaryTypeCheck_type_is_object', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryTypeCheck_type_is_object);
+ });
+ _ut.test('test_unnecessaryTypeCheck_type_not_dynamic', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryTypeCheck_type_not_dynamic);
+ });
+ _ut.test('test_unnecessaryTypeCheck_type_not_object', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryTypeCheck_type_not_object);
+ });
_ut.test('test_unusedImport', () {
final __test = new HintCodeTest();
runJUnitTest(__test, __test.test_unusedImport);
@@ -6039,37 +6394,33 @@
}
/**
- * Assert that the number of errors that have been gathered matches the number of errors that are
- * given and that they have the expected error codes. The order in which the errors were gathered
- * is ignored.
+ * Assert that the number of errors reported against the given source matches the number of errors
+ * that are given and that they have the expected error codes. The order in which the errors were
+ * gathered is ignored.
*
- * @param expectedErrorCodes the error codes of the errors that should have been gathered
- * @throws AssertionFailedError if a different number of errors have been gathered than were
+ * @param source the source against which the errors should have been reported
+ * @param expectedErrorCodes the error codes of the errors that should have been reported
+ * @throws AnalysisException if the reported errors could not be computed
+ * @throws AssertionFailedError if a different number of errors have been reported than were
* expected
*/
- void assertErrors(List<ErrorCode> expectedErrorCodes) {
+ void assertErrors(Source source, List<ErrorCode> expectedErrorCodes) {
GatheringErrorListener errorListener = new GatheringErrorListener();
- for (ChangeNotice notice in analysisContext.performAnalysisTask()) {
- for (AnalysisError error in notice.errors) {
- errorListener.onError(error);
- }
+ for (AnalysisError error in analysisContext.computeErrors(source)) {
+ errorListener.onError(error);
}
errorListener.assertErrors2(expectedErrorCodes);
}
/**
- * Assert that no errors have been gathered.
+ * Assert that no errors have been reported against the given source.
*
- * @throws AssertionFailedError if any errors have been gathered
+ * @param source the source against which no errors should have been reported
+ * @throws AnalysisException if the reported errors could not be computed
+ * @throws AssertionFailedError if any errors have been reported
*/
- void assertNoErrors() {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- for (ChangeNotice notice in analysisContext.performAnalysisTask()) {
- for (AnalysisError error in notice.errors) {
- errorListener.onError(error);
- }
- }
- errorListener.assertNoErrors();
+ void assertNoErrors(Source source) {
+ EngineTestCase.assertLength(0, analysisContext.computeErrors(source));
}
/**
@@ -6247,15 +6598,15 @@
element.type = type;
int count = parameterNames.length;
if (count > 0) {
- List<TypeVariableElementImpl> typeVariables = new List<TypeVariableElementImpl>(count);
- List<TypeVariableTypeImpl> typeArguments = new List<TypeVariableTypeImpl>(count);
+ List<TypeParameterElementImpl> typeParameters = new List<TypeParameterElementImpl>(count);
+ List<TypeParameterTypeImpl> typeArguments = new List<TypeParameterTypeImpl>(count);
for (int i = 0; i < count; i++) {
- TypeVariableElementImpl variable = new TypeVariableElementImpl(ASTFactory.identifier3(parameterNames[i]));
- typeVariables[i] = variable;
- typeArguments[i] = new TypeVariableTypeImpl(variable);
- variable.type = typeArguments[i];
+ TypeParameterElementImpl typeParameter = new TypeParameterElementImpl(ASTFactory.identifier3(parameterNames[i]));
+ typeParameters[i] = typeParameter;
+ typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
+ typeParameter.type = typeArguments[i];
}
- element.typeVariables = typeVariables;
+ element.typeParameters = typeParameters;
type.typeArguments = typeArguments;
}
return element;
@@ -6955,7 +7306,7 @@
void fail_compileTimeConstantRaisesException() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION]);
+ assertErrors(source, [CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAISES_EXCEPTION]);
verify([source]);
}
void fail_constEvalThrowsException() {
@@ -6965,7 +7316,7 @@
"}",
"f() { return const C(); }"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]);
verify([source]);
}
void fail_mixinDeclaresConstructor() {
@@ -6975,19 +7326,19 @@
"}",
"class B extends Object mixin A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
verify([source]);
}
void fail_mixinOfNonClass() {
Source source = addSource(EngineTestCase.createSource(["var A;", "class B extends Object mixin A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
verify([source]);
}
void fail_objectCannotExtendAnotherClass() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS]);
verify([source]);
}
void fail_recursiveCompileTimeConstant() {
@@ -6997,19 +7348,19 @@
" final m = const A();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
+ assertErrors(source, [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
verify([source]);
}
void fail_recursiveCompileTimeConstant_cycle() {
Source source = addSource(EngineTestCase.createSource(["const x = y + 1;", "const y = x + 1;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
+ assertErrors(source, [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
verify([source]);
}
void fail_superInitializerInObject() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT]);
verify([source]);
}
void test_ambiguousExport() {
@@ -7020,7 +7371,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.AMBIGUOUS_EXPORT]);
+ assertErrors(source, [CompileTimeErrorCode.AMBIGUOUS_EXPORT]);
verify([source]);
}
void test_ambiguousImport_function() {
@@ -7031,14 +7382,14 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "f() {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "f() {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
StaticWarningCode.AMBIGUOUS_IMPORT,
CompileTimeErrorCode.UNDEFINED_FUNCTION]);
}
void test_argumentDefinitionTestNonParameter() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var v = 0;", " return ?v;", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST,
CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER]);
verify([source]);
@@ -7052,7 +7403,7 @@
" const A(42);",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_const_super() {
@@ -7064,13 +7415,13 @@
" const B() : super(42);",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_builtInIdentifierAsType() {
Source source = addSource(EngineTestCase.createSource(["f() {", " typedef x;", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE,
StaticWarningCode.UNDEFINED_CLASS]);
verify([source]);
@@ -7078,25 +7429,25 @@
void test_builtInIdentifierAsTypedefName_classTypeAlias() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "class B {}", "typedef as = A with B;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
verify([source]);
}
void test_builtInIdentifierAsTypedefName_functionTypeAlias() {
Source source = addSource(EngineTestCase.createSource(["typedef bool as();"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
verify([source]);
}
void test_builtInIdentifierAsTypeName() {
Source source = addSource(EngineTestCase.createSource(["class as {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
verify([source]);
}
- void test_builtInIdentifierAsTypeVariableName() {
+ void test_builtInIdentifierAsTypeParameterName() {
Source source = addSource(EngineTestCase.createSource(["class A<as> {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME]);
verify([source]);
}
void test_caseExpressionTypeImplementsEquals() {
@@ -7107,6 +7458,7 @@
" bool operator ==(IntWrapper x) {",
" return value == x.value;",
" }",
+ " get hashCode => value;",
"}",
"",
"f(var a) {",
@@ -7116,19 +7468,19 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+ assertErrors(source, [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
verify([source]);
}
void test_conflictingConstructorNameAndMember_field() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A.x() {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD]);
verify([source]);
}
void test_conflictingConstructorNameAndMember_method() {
Source source = addSource(EngineTestCase.createSource(["class A {", " const A.x();", " void x() {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]);
+ assertErrors(source, [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]);
verify([source]);
}
void test_conflictingGetterAndMethod_field_method() {
@@ -7140,7 +7492,7 @@
" m() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD]);
+ assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD]);
verify([source]);
}
void test_conflictingGetterAndMethod_getter_method() {
@@ -7152,7 +7504,7 @@
" m() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD]);
+ assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD]);
verify([source]);
}
void test_conflictingGetterAndMethod_method_field() {
@@ -7164,7 +7516,7 @@
" int m;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]);
+ assertErrors(source, [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]);
verify([source]);
}
void test_conflictingGetterAndMethod_method_getter() {
@@ -7176,7 +7528,7 @@
" get m => 0;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]);
+ assertErrors(source, [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]);
verify([source]);
}
void test_constConstructorWithNonConstSuper_explicit() {
@@ -7188,7 +7540,7 @@
" const B(): super();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
verify([source]);
}
void test_constConstructorWithNonConstSuper_implicit() {
@@ -7200,7 +7552,7 @@
" const B();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
verify([source]);
}
void test_constConstructorWithNonFinalField_mixin() {
@@ -7212,7 +7564,7 @@
" const B();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]);
verify([source]);
}
void test_constConstructorWithNonFinalField_super() {
@@ -7224,7 +7576,7 @@
" const B();",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
verify([source]);
@@ -7232,13 +7584,13 @@
void test_constConstructorWithNonFinalField_this() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " const A();", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]);
verify([source]);
}
void test_constEval_newInstance_constConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " const A();", "}", "const a = new A();"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
verify([source]);
}
void test_constEval_propertyExtraction_targetNotConst() {
@@ -7250,7 +7602,7 @@
"final a = const A();",
"const C = a.m;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
verify([source]);
}
void test_constEvalThrowsException_binaryMinus_null() {
@@ -7264,27 +7616,27 @@
void test_constEvalThrowsException_divisionByZero() {
Source source = addSource("const C = 1 ~/ 0;");
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE]);
verify([source]);
}
void test_constEvalThrowsException_unaryBitNot_null() {
Source source = addSource("const C = ~null;");
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_constEvalThrowsException_unaryNegated_null() {
Source source = addSource("const C = -null;");
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_constEvalThrowsException_unaryNot_null() {
Source source = addSource("const C = !null;");
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
verify([source]);
}
void test_constEvalTypeBool_binary() {
@@ -7294,7 +7646,7 @@
void test_constEvalTypeBool_binary_leftTrue() {
Source source = addSource("const C = (true || 0);");
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
HintCode.DEAD_CODE]);
verify([source]);
@@ -7309,7 +7661,7 @@
" const B(num p) : a = p == const A();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
verify([source]);
}
void test_constEvalTypeBoolNumString_notEqual() {
@@ -7322,7 +7674,7 @@
" const B(String p) : a = p != const A();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
verify([source]);
}
void test_constEvalTypeInt_binary() {
@@ -7347,43 +7699,43 @@
void test_constEvalTypeNum_plus_String() {
Source source = addSource("const C = 'a' + 'b';");
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_EVAL_TYPE_NUM]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_TYPE_NUM]);
verify([source]);
}
void test_constFormalParameter_fieldFormalParameter() {
Source source = addSource(EngineTestCase.createSource(["class A {", " var x;", " A(const this.x) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
verify([source]);
}
void test_constFormalParameter_simpleFormalParameter() {
Source source = addSource(EngineTestCase.createSource(["f(const x) {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
verify([source]);
}
void test_constInitializedWithNonConstValue() {
Source source = addSource(EngineTestCase.createSource(["f(p) {", " const C = p;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
verify([source]);
}
void test_constInitializedWithNonConstValue_missingConstInListLiteral() {
Source source = addSource("const List L = [0];");
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
verify([source]);
}
void test_constInitializedWithNonConstValue_missingConstInMapLiteral() {
Source source = addSource("const Map M = {'a' : 0};");
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
verify([source]);
}
void test_constInstanceField() {
Source source = addSource(EngineTestCase.createSource(["class C {", " const int f = 0;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_INSTANCE_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_INSTANCE_FIELD]);
verify([source]);
}
void test_constWithInvalidTypeParameters() {
@@ -7393,7 +7745,7 @@
"}",
"f() { return const A<A>(); }"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
verify([source]);
}
void test_constWithInvalidTypeParameters_tooFew() {
@@ -7406,7 +7758,7 @@
" return const C<A>();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
verify([source]);
}
void test_constWithInvalidTypeParameters_tooMany() {
@@ -7419,7 +7771,7 @@
" return const C<A, A>();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
verify([source]);
}
void test_constWithNonConst() {
@@ -7429,7 +7781,7 @@
"}",
"f() { return const T(0, 1, c: 2, d: 3); }"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_NON_CONST]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_CONST]);
verify([source]);
}
void test_constWithNonConstantArgument_annotation() {
@@ -7442,7 +7794,7 @@
"main() {",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT]);
verify([source]);
}
void test_constWithNonConstantArgument_instanceCreation() {
@@ -7452,13 +7804,13 @@
"}",
"f(p) { return const A(p); }"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT]);
verify([source]);
}
void test_constWithNonType() {
Source source = addSource(EngineTestCase.createSource(["int A;", "f() {", " return const A();", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
verify([source]);
}
void test_constWithNonType_fromLibrary() {
@@ -7470,7 +7822,7 @@
"}"]));
resolve(source1);
resolve(source2);
- assertErrors([CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
+ assertErrors(source2, [CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
verify([source1]);
}
void test_constWithTypeParameters_direct() {
@@ -7480,7 +7832,7 @@
" const A();",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
verify([source]);
@@ -7492,7 +7844,7 @@
" const A();",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
verify([source]);
@@ -7506,7 +7858,7 @@
" return const A.noSuchConstructor();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
}
void test_constWithUndefinedConstructorDefault() {
Source source = addSource(EngineTestCase.createSource([
@@ -7517,31 +7869,31 @@
" return const A();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]);
verify([source]);
}
void test_defaultValueInFunctionTypeAlias() {
Source source = addSource(EngineTestCase.createSource(["typedef F([x = 0]);"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
+ assertErrors(source, [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
verify([source]);
}
void test_defaultValueInFunctionTypedParameter_named() {
Source source = addSource(EngineTestCase.createSource(["f(g({p: null})) {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
+ assertErrors(source, [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
verify([source]);
}
void test_defaultValueInFunctionTypedParameter_optional() {
Source source = addSource(EngineTestCase.createSource(["f(g([p = null])) {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
+ assertErrors(source, [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
verify([source]);
}
void test_duplicateConstructorName_named() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A.a() {}", " A.a() {}", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME]);
verify([source]);
@@ -7549,7 +7901,7 @@
void test_duplicateConstructorName_unnamed() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() {}", " A() {}", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT]);
verify([source]);
@@ -7557,7 +7909,7 @@
void test_duplicateDefinition() {
Source source = addSource(EngineTestCase.createSource(["f() {", " int m = 0;", " m(a) {}", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION]);
verify([source]);
@@ -7567,23 +7919,23 @@
Source sourceA = addSource2("/a.dart", EngineTestCase.createSource(["part of lib;", "", "class A {}"]));
Source sourceB = addSource2("/b.dart", EngineTestCase.createSource(["part of lib;", "", "class A {}"]));
resolve(librarySource);
- assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertErrors(sourceB, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
verify([librarySource, sourceA, sourceB]);
}
void test_duplicateDefinition_classMembers_fields() {
- Source librarySource = addSource(EngineTestCase.createSource(["class A {", " int a;", " int a;", "}"]));
- resolve(librarySource);
- assertErrors([
+ Source source = addSource(EngineTestCase.createSource(["class A {", " int a;", " int a;", "}"]));
+ resolve(source);
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION]);
- verify([librarySource]);
+ verify([source]);
}
void test_duplicateDefinition_classMembers_fields_oneStatic() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " static int x;", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION,
@@ -7591,31 +7943,31 @@
verify([source]);
}
void test_duplicateDefinition_classMembers_methods() {
- Source librarySource = addSource(EngineTestCase.createSource(["class A {", " m() {}", " m() {}", "}"]));
- resolve(librarySource);
- assertErrors([
+ Source source = addSource(EngineTestCase.createSource(["class A {", " m() {}", " m() {}", "}"]));
+ resolve(source);
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION]);
- verify([librarySource]);
+ verify([source]);
}
void test_duplicateDefinition_localFields() {
- Source librarySource = addSource(EngineTestCase.createSource([
+ Source source = addSource(EngineTestCase.createSource([
"class A {",
" m() {",
" int a;",
" int a;",
" }",
"}"]));
- resolve(librarySource);
- assertErrors([
+ resolve(source);
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION]);
- verify([librarySource]);
+ verify([source]);
}
void test_duplicateDefinition_parameterWithFunctionName_local() {
Source source = addSource(EngineTestCase.createSource(["main() {", " f(f) {}", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION]);
verify([source]);
@@ -7623,7 +7975,7 @@
void test_duplicateDefinition_parameterWithFunctionName_topLevel() {
Source source = addSource(EngineTestCase.createSource(["main() {", " f(f) {}", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.DUPLICATE_DEFINITION,
CompileTimeErrorCode.DUPLICATE_DEFINITION]);
verify([source]);
@@ -7637,7 +7989,7 @@
" static int get x => 0;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
verify([source]);
}
void test_duplicateDefinitionInheritance_instanceGetterAbstract_staticGetter() {
@@ -7649,7 +8001,7 @@
" static int get x => 0;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
verify([source]);
}
void test_duplicateDefinitionInheritance_instanceMethod_staticMethod() {
@@ -7661,7 +8013,7 @@
" static x() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
verify([source]);
}
void test_duplicateDefinitionInheritance_instanceMethodAbstract_staticMethod() {
@@ -7673,7 +8025,7 @@
" static x() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
verify([source]);
}
void test_duplicateDefinitionInheritance_instanceSetter_staticSetter() {
@@ -7685,7 +8037,7 @@
" static set x(value) {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
verify([source]);
}
void test_duplicateDefinitionInheritance_instanceSetterAbstract_staticSetter() {
@@ -7697,32 +8049,32 @@
" static set x(value) {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
verify([source]);
}
void test_duplicateNamedArgument() {
Source source = addSource(EngineTestCase.createSource(["f({a, b}) {}", "main() {", " f(a: 1, a: 2);", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT]);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT]);
verify([source]);
}
void test_exportInternalLibrary() {
Source source = addSource(EngineTestCase.createSource(["export 'dart:_interceptors';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]);
+ assertErrors(source, [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]);
verify([source]);
}
void test_exportOfNonLibrary() {
Source source = addSource(EngineTestCase.createSource(["library L;", "export 'lib1.dart';"]));
addSource2("/lib1.dart", EngineTestCase.createSource(["part of lib;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
+ assertErrors(source, [CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
verify([source]);
}
void test_extendsDisallowedClass_bool() {
Source source = addSource(EngineTestCase.createSource(["class A extends bool {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
verify([source]);
@@ -7730,7 +8082,7 @@
void test_extendsDisallowedClass_double() {
Source source = addSource(EngineTestCase.createSource(["class A extends double {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
verify([source]);
@@ -7738,7 +8090,7 @@
void test_extendsDisallowedClass_int() {
Source source = addSource(EngineTestCase.createSource(["class A extends int {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
verify([source]);
@@ -7746,7 +8098,7 @@
void test_extendsDisallowedClass_Null() {
Source source = addSource(EngineTestCase.createSource(["class A extends Null {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
verify([source]);
@@ -7754,7 +8106,7 @@
void test_extendsDisallowedClass_num() {
Source source = addSource(EngineTestCase.createSource(["class A extends num {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
verify([source]);
@@ -7762,7 +8114,7 @@
void test_extendsDisallowedClass_String() {
Source source = addSource(EngineTestCase.createSource(["class A extends String {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
verify([source]);
@@ -7770,13 +8122,13 @@
void test_extendsNonClass_class() {
Source source = addSource(EngineTestCase.createSource(["int A;", "class B extends A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.EXTENDS_NON_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.EXTENDS_NON_CLASS]);
verify([source]);
}
void test_extendsNonClass_dynamic() {
Source source = addSource(EngineTestCase.createSource(["class B extends dynamic {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.EXTENDS_NON_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.EXTENDS_NON_CLASS]);
verify([source]);
}
void test_extraPositionalArguments_const() {
@@ -7788,7 +8140,7 @@
" const A(0);",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS]);
+ assertErrors(source, [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS]);
verify([source]);
}
void test_extraPositionalArguments_const_super() {
@@ -7800,13 +8152,13 @@
" const B() : super(0);",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS]);
+ assertErrors(source, [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS]);
verify([source]);
}
void test_fieldInitializedByMultipleInitializers() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A() : x = 0, x = 1 {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
verify([source]);
}
void test_fieldInitializedByMultipleInitializers_multipleInits() {
@@ -7816,7 +8168,7 @@
" A() : x = 0, x = 1, x = 2 {}",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
verify([source]);
@@ -7829,7 +8181,7 @@
" A() : x = 0, x = 1, y = 0, y = 1 {}",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
verify([source]);
@@ -7837,13 +8189,13 @@
void test_fieldInitializedInParameterAndInitializer() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A(this.x) : x = 1 {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
verify([source]);
}
void test_fieldInitializerFactoryConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " factory A(this.x) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR]);
verify([source]);
}
void test_fieldInitializerNotAssignable() {
@@ -7853,13 +8205,13 @@
" const A() : x = '';",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE]);
verify([source]);
}
void test_fieldInitializerOutsideConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " m(this.x) {}", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
verify([source]);
@@ -7867,7 +8219,7 @@
void test_fieldInitializerOutsideConstructor_defaultParameter() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " m([this.x]) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
verify([source]);
}
void test_fieldInitializerRedirectingConstructor_afterRedirection() {
@@ -7878,7 +8230,7 @@
" A() : this.named(), x = 42;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
verify([source]);
}
void test_fieldInitializerRedirectingConstructor_beforeRedirection() {
@@ -7889,7 +8241,7 @@
" A() : x = 42, this.named();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
verify([source]);
}
void test_fieldInitializingFormalRedirectingConstructor() {
@@ -7900,13 +8252,13 @@
" A(this.x) : this.named();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
verify([source]);
}
void test_finalInitializedMultipleTimes_initializers() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final x;", " A() : x = 0, x = 0 {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
verify([source]);
}
@@ -7921,19 +8273,37 @@
void test_finalInitializedMultipleTimes_initializingFormal_initializer() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final x;", " A(this.x) : x = 0 {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
verify([source]);
}
void test_finalInitializedMultipleTimes_initializingFormals() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final x;", " A(this.x, this.x) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES]);
+ assertErrors(source, [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES]);
+ verify([source]);
+ }
+ void test_finalNotInitialized_instanceField_const_static() {
+ Source source = addSource(EngineTestCase.createSource(["class A {", " static const F;", "}"]));
+ resolve(source);
+ assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
+ verify([source]);
+ }
+ void test_finalNotInitialized_library_const() {
+ Source source = addSource(EngineTestCase.createSource(["const F;"]));
+ resolve(source);
+ assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
+ verify([source]);
+ }
+ void test_finalNotInitialized_local_const() {
+ Source source = addSource(EngineTestCase.createSource(["f() {", " const int x;", "}"]));
+ resolve(source);
+ assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
verify([source]);
}
void test_getterAndMethodWithSameName() {
Source source = addSource(EngineTestCase.createSource(["class A {", " x(y) {}", " get x => 0;", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME]);
verify([source]);
@@ -7941,61 +8311,61 @@
void test_implementsDisallowedClass_bool() {
Source source = addSource(EngineTestCase.createSource(["class A implements bool {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
verify([source]);
}
void test_implementsDisallowedClass_double() {
Source source = addSource(EngineTestCase.createSource(["class A implements double {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
verify([source]);
}
void test_implementsDisallowedClass_int() {
Source source = addSource(EngineTestCase.createSource(["class A implements int {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
verify([source]);
}
void test_implementsDisallowedClass_Null() {
Source source = addSource(EngineTestCase.createSource(["class A implements Null {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
verify([source]);
}
void test_implementsDisallowedClass_num() {
Source source = addSource(EngineTestCase.createSource(["class A implements num {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
verify([source]);
}
void test_implementsDisallowedClass_String() {
Source source = addSource(EngineTestCase.createSource(["class A implements String {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
verify([source]);
}
void test_implementsDynamic() {
Source source = addSource(EngineTestCase.createSource(["class A implements dynamic {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_DYNAMIC]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DYNAMIC]);
verify([source]);
}
void test_implementsNonClass_class() {
Source source = addSource(EngineTestCase.createSource(["int A;", "class B implements A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
verify([source]);
}
void test_implementsNonClass_typedef() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "int B;", "typedef C = A implements B;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
verify([source]);
}
void test_implementsRepeated() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "class B implements A, A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
verify([source]);
}
void test_implementsRepeated_3times() {
@@ -8003,7 +8373,7 @@
"class A {} class C{}",
"class B implements A, A, A, A {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.IMPLEMENTS_REPEATED,
CompileTimeErrorCode.IMPLEMENTS_REPEATED,
CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
@@ -8012,13 +8382,13 @@
void test_implementsSuperClass() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "class B extends A implements A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
verify([source]);
}
void test_implementsSuperClass_Object() {
Source source = addSource(EngineTestCase.createSource(["class A implements Object {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
verify([source]);
}
void test_implicitThisReferenceInInitializer_field() {
@@ -8029,13 +8399,13 @@
" var f;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
verify([source]);
}
void test_implicitThisReferenceInInitializer_field2() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final x = 0;", " final y = x;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
verify([source]);
}
void test_implicitThisReferenceInInitializer_invocation() {
@@ -8046,13 +8416,13 @@
" f() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
verify([source]);
}
void test_implicitThisReferenceInInitializer_invocationInStatic() {
Source source = addSource(EngineTestCase.createSource(["class A {", " static var F = m();", " m() {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
verify([source]);
}
void test_implicitThisReferenceInInitializer_redirectingConstructorInvocation() {
@@ -8063,7 +8433,7 @@
" var f;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
verify([source]);
}
void test_implicitThisReferenceInInitializer_superConstructorInvocation() {
@@ -8076,13 +8446,13 @@
" var f;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
verify([source]);
}
void test_importInternalLibrary() {
Source source = addSource(EngineTestCase.createSource(["import 'dart:_interceptors';"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
HintCode.UNUSED_IMPORT]);
verify([source]);
@@ -8090,7 +8460,7 @@
void test_importInternalLibrary_collection() {
Source source = addSource(EngineTestCase.createSource(["import 'dart:_collection-dev';"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
HintCode.UNUSED_IMPORT]);
verify([source]);
@@ -8099,7 +8469,7 @@
Source source = addSource(EngineTestCase.createSource(["library lib;", "import 'part.dart';", "A a;"]));
addSource2("/part.dart", EngineTestCase.createSource(["part of lib;", "class A{}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
+ assertErrors(source, [CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
verify([source]);
}
void test_inconsistentCaseExpressionTypes() {
@@ -8113,7 +8483,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES]);
+ assertErrors(source, [CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES]);
verify([source]);
}
void test_inconsistentCaseExpressionTypes_repeated() {
@@ -8129,7 +8499,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES]);
verify([source]);
@@ -8137,18 +8507,18 @@
void test_initializerForNonExistant_initializer() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() : x = 0 {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD]);
}
void test_initializerForStaticField() {
Source source = addSource(EngineTestCase.createSource(["class A {", " static int x;", " A() : x = 0 {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD]);
verify([source]);
}
void test_initializingFormalForNonExistantField() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A(this.x) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD]);
verify([source]);
}
void test_initializingFormalForNonExistantField_notInEnclosingClass() {
@@ -8160,25 +8530,25 @@
" B(this.x) {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD]);
verify([source]);
}
void test_initializingFormalForNonExistantField_optional() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A([this.x]) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD]);
verify([source]);
}
void test_initializingFormalForNonExistantField_synthetic() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int get x => 1;", " A(this.x) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD]);
verify([source]);
}
void test_initializingFormalForStaticField() {
Source source = addSource(EngineTestCase.createSource(["class A {", " static int x;", " A([this.x]) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD]);
+ assertErrors(source, [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD]);
verify([source]);
}
void test_instanceMemberAccessFromStatic_field() {
@@ -8190,7 +8560,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
+ assertErrors(source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
verify([source]);
}
void test_instanceMemberAccessFromStatic_getter() {
@@ -8202,7 +8572,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
+ assertErrors(source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
verify([source]);
}
void test_instanceMemberAccessFromStatic_method() {
@@ -8214,46 +8584,46 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
+ assertErrors(source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
verify([source]);
}
void test_invalidAnnotation_getter() {
Source source = addSource(EngineTestCase.createSource(["get V => 0;", "@V", "main() {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_ANNOTATION]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
verify([source]);
}
void test_invalidAnnotation_importWithPrefix_getter() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "get V => 0;"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as p;", "@p.V", "main() {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_ANNOTATION]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
verify([source]);
}
void test_invalidAnnotation_importWithPrefix_notConstantVariable() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "final V = 0;"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as p;", "@p.V", "main() {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_ANNOTATION]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
verify([source]);
}
void test_invalidAnnotation_importWithPrefix_notVariableOrConstructorInvocation() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "typedef V();"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as p;", "@p.V", "main() {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_ANNOTATION]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
verify([source]);
}
void test_invalidAnnotation_notConstantVariable() {
Source source = addSource(EngineTestCase.createSource(["final V = 0;", "@V", "main() {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_ANNOTATION]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
verify([source]);
}
void test_invalidAnnotation_notVariableOrConstructorInvocation() {
Source source = addSource(EngineTestCase.createSource(["typedef V();", "@V", "main() {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_ANNOTATION]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
verify([source]);
}
void test_invalidAnnotation_staticMethodReference() {
@@ -8265,58 +8635,58 @@
"main() {",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_ANNOTATION]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
verify([source]);
}
void test_invalidConstructorName_notEnclosingClassName_defined() {
Source source = addSource(EngineTestCase.createSource(["class A {", " B() : super();", "}", "class B {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
}
void test_invalidConstructorName_notEnclosingClassName_undefined() {
Source source = addSource(EngineTestCase.createSource(["class A {", " B() : super();", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
}
void test_invalidFactoryNameNotAClass_notClassName() {
Source source = addSource(EngineTestCase.createSource(["int B;", "class A {", " factory B() {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
verify([source]);
}
void test_invalidFactoryNameNotAClass_notEnclosingClassName() {
Source source = addSource(EngineTestCase.createSource(["class A {", " factory B() {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
}
void test_invalidReferenceToThis_factoryConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " factory A() { return this; }", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
verify([source]);
}
void test_invalidReferenceToThis_instanceVariableInitializer_inConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " var f;", " A() : f = this;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
verify([source]);
}
void test_invalidReferenceToThis_instanceVariableInitializer_inDeclaration() {
Source source = addSource(EngineTestCase.createSource(["class A {", " var f = this;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
verify([source]);
}
void test_invalidReferenceToThis_staticMethod() {
Source source = addSource(EngineTestCase.createSource(["class A {", " static m() { return this; }", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
verify([source]);
}
void test_invalidReferenceToThis_staticVariableInitializer() {
Source source = addSource(EngineTestCase.createSource(["class A {", " static A f = this;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
verify([source]);
}
void test_invalidReferenceToThis_superInitializer() {
@@ -8328,19 +8698,19 @@
" B() : super(this);",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
verify([source]);
}
void test_invalidReferenceToThis_topLevelFunction() {
Source source = addSource("f() { return this; }");
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
verify([source]);
}
void test_invalidReferenceToThis_variableInitializer() {
Source source = addSource("int x = this;");
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
verify([source]);
}
void test_invalidTypeArgumentInConstList() {
@@ -8351,7 +8721,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST]);
verify([source]);
}
void test_invalidTypeArgumentInConstMap() {
@@ -8362,23 +8732,23 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]);
verify([source]);
}
void test_invalidUri_export() {
Source source = addSource(EngineTestCase.createSource(["export 'ht:';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_URI]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
}
void test_invalidUri_import() {
Source source = addSource(EngineTestCase.createSource(["import 'ht:';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_URI]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
}
void test_invalidUri_part() {
Source source = addSource(EngineTestCase.createSource(["part 'ht:';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.INVALID_URI]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
}
void test_labelInOuterScope() {
Source source = addSource(EngineTestCase.createSource([
@@ -8392,7 +8762,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE]);
+ assertErrors(source, [CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE]);
}
void test_labelUndefined_break() {
Source source = addSource(EngineTestCase.createSource([
@@ -8402,7 +8772,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.LABEL_UNDEFINED]);
+ assertErrors(source, [CompileTimeErrorCode.LABEL_UNDEFINED]);
}
void test_labelUndefined_continue() {
Source source = addSource(EngineTestCase.createSource([
@@ -8412,42 +8782,42 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.LABEL_UNDEFINED]);
+ assertErrors(source, [CompileTimeErrorCode.LABEL_UNDEFINED]);
}
void test_listElementTypeNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["var v = const <String> [42];"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_mapKeyTypeNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["var v = const <String, int > {1 : 2};"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_mapValueTypeNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["var v = const <String, String> {'a' : 2};"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_memberWithClassName_field() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int A = 0;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
verify([source]);
}
void test_memberWithClassName_field2() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int z, A, b = 0;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
verify([source]);
}
void test_memberWithClassName_getter() {
Source source = addSource(EngineTestCase.createSource(["class A {", " get A => 0;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
verify([source]);
}
void test_memberWithClassName_method() {
@@ -8455,7 +8825,7 @@
void test_methodAndGetterWithSameName() {
Source source = addSource(EngineTestCase.createSource(["class A {", " get x => 0;", " x(y) {}", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME]);
verify([source]);
@@ -8467,7 +8837,7 @@
"}",
"class B extends Object with A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
verify([source]);
}
void test_mixinDeclaresConstructor_typedef() {
@@ -8477,7 +8847,7 @@
"}",
"typedef B = Object with A;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
verify([source]);
}
void test_mixinInheritsFromNotObject_classDeclaration_extends() {
@@ -8486,7 +8856,7 @@
"class B extends A {}",
"class C extends Object with B {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
verify([source]);
}
void test_mixinInheritsFromNotObject_classDeclaration_with() {
@@ -8495,7 +8865,7 @@
"class B extends Object with A {}",
"class C extends Object with B {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
verify([source]);
}
void test_mixinInheritsFromNotObject_typedef_extends() {
@@ -8504,7 +8874,7 @@
"class B extends A {}",
"typedef C = Object with B;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
verify([source]);
}
void test_mixinInheritsFromNotObject_typedef_with() {
@@ -8513,55 +8883,55 @@
"class B extends Object with A {}",
"typedef C = Object with B;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
verify([source]);
}
void test_mixinOfDisallowedClass_bool() {
Source source = addSource(EngineTestCase.createSource(["class A extends Object with bool {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
verify([source]);
}
void test_mixinOfDisallowedClass_double() {
Source source = addSource(EngineTestCase.createSource(["class A extends Object with double {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
verify([source]);
}
void test_mixinOfDisallowedClass_int() {
Source source = addSource(EngineTestCase.createSource(["class A extends Object with int {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
verify([source]);
}
void test_mixinOfDisallowedClass_Null() {
Source source = addSource(EngineTestCase.createSource(["class A extends Object with Null {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
verify([source]);
}
void test_mixinOfDisallowedClass_num() {
Source source = addSource(EngineTestCase.createSource(["class A extends Object with num {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
verify([source]);
}
void test_mixinOfDisallowedClass_String() {
Source source = addSource(EngineTestCase.createSource(["class A extends Object with String {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
verify([source]);
}
void test_mixinOfNonClass_class() {
Source source = addSource(EngineTestCase.createSource(["int A;", "class B extends Object with A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
verify([source]);
}
void test_mixinOfNonClass_typedef() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "int B;", "typedef C = A with B;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
verify([source]);
}
void test_mixinReferencesSuper() {
@@ -8571,19 +8941,19 @@
"}",
"class B extends Object with A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
verify([source]);
}
void test_mixinWithNonClassSuperclass_class() {
Source source = addSource(EngineTestCase.createSource(["int A;", "class B {}", "class C extends A with B {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
verify([source]);
}
void test_mixinWithNonClassSuperclass_typedef() {
Source source = addSource(EngineTestCase.createSource(["int A;", "class B {}", "typedef C = A with B;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
verify([source]);
}
void test_multipleRedirectingConstructorInvocations() {
@@ -8594,7 +8964,7 @@
" A.b() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS]);
+ assertErrors(source, [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS]);
verify([source]);
}
void test_multipleSuperInitializers() {
@@ -8604,31 +8974,31 @@
" B() : super(), super() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]);
+ assertErrors(source, [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]);
verify([source]);
}
void test_nativeClauseInNonSDKCode() {
Source source = addSource(EngineTestCase.createSource(["class A native 'string' {}"]));
resolve(source);
- assertErrors([ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
+ assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
verify([source]);
}
void test_nativeFunctionBodyInNonSDKCode_function() {
Source source = addSource(EngineTestCase.createSource(["int m(a) native 'string';"]));
resolve(source);
- assertErrors([ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
+ assertErrors(source, [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
verify([source]);
}
void test_nativeFunctionBodyInNonSDKCode_method() {
Source source = addSource(EngineTestCase.createSource(["class A{", " static int m(a) native 'string';", "}"]));
resolve(source);
- assertErrors([ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
+ assertErrors(source, [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
verify([source]);
}
void test_noAnnotationConstructorArguments() {
Source source = addSource(EngineTestCase.createSource(["class A {", " const A();", "}", "@A", "main() {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS]);
+ assertErrors(source, [CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS]);
verify([source]);
}
void test_noDefaultSuperConstructorExplicit() {
@@ -8640,19 +9010,19 @@
" B() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]);
+ assertErrors(source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]);
verify([source]);
}
void test_noDefaultSuperConstructorImplicit_superHasParameters() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A(p);", "}", "class B extends A {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
+ assertErrors(source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
verify([source]);
}
void test_noDefaultSuperConstructorImplicit_superOnlyNamed() {
Source source = addSource(EngineTestCase.createSource(["class A { A.named() {} }", "class B extends A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
+ assertErrors(source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
verify([source]);
}
void test_nonConstantAnnotationConstructor_named() {
@@ -8664,49 +9034,49 @@
"main() {",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR]);
verify([source]);
}
void test_nonConstantAnnotationConstructor_unnamed() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() {}", "}", "@A()", "main() {", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR]);
verify([source]);
}
void test_nonConstantDefaultValue_function_named() {
Source source = addSource(EngineTestCase.createSource(["int y;", "f({x : y}) {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
verify([source]);
}
void test_nonConstantDefaultValue_function_positional() {
Source source = addSource(EngineTestCase.createSource(["int y;", "f([x = y]) {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
verify([source]);
}
void test_nonConstantDefaultValue_inConstructor_named() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int y;", " A({x : y}) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
verify([source]);
}
void test_nonConstantDefaultValue_inConstructor_positional() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int y;", " A([x = y]) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
verify([source]);
}
void test_nonConstantDefaultValue_method_named() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int y;", " m({x : y}) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
verify([source]);
}
void test_nonConstantDefaultValue_method_positional() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int y;", " m([x = y]) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
verify([source]);
}
void test_nonConstCaseExpression() {
@@ -8718,37 +9088,37 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION]);
verify([source]);
}
void test_nonConstListElement() {
Source source = addSource(EngineTestCase.createSource(["f(a) {", " return const [a];", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
verify([source]);
}
void test_nonConstMapAsExpressionStatement_begin() {
Source source = addSource(EngineTestCase.createSource(["f() {", " {'a' : 0, 'b' : 1}.length;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
verify([source]);
}
void test_nonConstMapAsExpressionStatement_only() {
Source source = addSource(EngineTestCase.createSource(["f() {", " {'a' : 0, 'b' : 1};", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
verify([source]);
}
void test_nonConstMapKey() {
Source source = addSource(EngineTestCase.createSource(["f(a) {", " return const {a : 0};", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
verify([source]);
}
void test_nonConstMapValue() {
Source source = addSource(EngineTestCase.createSource(["f(a) {", " return const {'a' : a};", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
verify([source]);
}
void test_nonConstValueInInitializer_binary_notBool_left() {
@@ -8758,7 +9128,7 @@
" const A(String p) : a = p && true;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
verify([source]);
}
void test_nonConstValueInInitializer_binary_notBool_right() {
@@ -8768,7 +9138,7 @@
" const A(String p) : a = true && p;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
verify([source]);
}
void test_nonConstValueInInitializer_binary_notInt() {
@@ -8778,7 +9148,7 @@
" const A(String p) : a = 5 & p;",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
@@ -8790,7 +9160,7 @@
" const A(String p) : a = 5 + p;",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
@@ -8803,7 +9173,7 @@
" const A() : a = C;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
verify([source]);
}
void test_nonConstValueInInitializer_redirecting() {
@@ -8814,7 +9184,7 @@
" const A() : this.named(C);",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
verify([source]);
}
void test_nonConstValueInInitializer_super() {
@@ -8827,7 +9197,7 @@
" const B() : super(C);",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
verify([source]);
}
void test_nonGenerativeConstructor_explicit() {
@@ -8839,7 +9209,7 @@
" B() : super.named();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
verify([source]);
}
void test_nonGenerativeConstructor_implicit() {
@@ -8851,7 +9221,7 @@
" B();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
verify([source]);
}
void test_nonGenerativeConstructor_implicit2() {
@@ -8862,7 +9232,7 @@
"class B extends A {",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
verify([source]);
}
void test_notEnoughRequiredArguments_const() {
@@ -8874,7 +9244,7 @@
" const A();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
+ assertErrors(source, [CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
verify([source]);
}
void test_notEnoughRequiredArguments_const_super() {
@@ -8886,72 +9256,72 @@
" const B() : super();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
+ assertErrors(source, [CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
verify([source]);
}
void test_optionalParameterInOperator_named() {
Source source = addSource(EngineTestCase.createSource(["class A {", " operator +({p}) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
+ assertErrors(source, [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
verify([source]);
}
void test_optionalParameterInOperator_positional() {
Source source = addSource(EngineTestCase.createSource(["class A {", " operator +([p]) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
+ assertErrors(source, [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
verify([source]);
}
void test_partOfNonPart() {
Source source = addSource(EngineTestCase.createSource(["library l1;", "part 'l2.dart';"]));
addSource2("/l2.dart", EngineTestCase.createSource(["library l2;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.PART_OF_NON_PART]);
+ assertErrors(source, [CompileTimeErrorCode.PART_OF_NON_PART]);
verify([source]);
}
void test_prefixCollidesWithTopLevelMembers_functionTypeAlias() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "class A{}"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as p;", "typedef p();", "p.A a;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+ assertErrors(source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
verify([source]);
}
void test_prefixCollidesWithTopLevelMembers_topLevelFunction() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "class A{}"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as p;", "p() {}", "p.A a;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+ assertErrors(source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
verify([source]);
}
void test_prefixCollidesWithTopLevelMembers_topLevelVariable() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "class A{}"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as p;", "var p = null;", "p.A a;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+ assertErrors(source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
verify([source]);
}
void test_prefixCollidesWithTopLevelMembers_type() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "class A{}"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as p;", "class p {}", "p.A a;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+ assertErrors(source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
verify([source]);
}
void test_privateOptionalParameter() {
Source source = addSource(EngineTestCase.createSource(["f({var _p}) {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
+ assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
verify([source]);
}
void test_privateOptionalParameter_fieldFormal() {
Source source = addSource(EngineTestCase.createSource(["class A {", " var _p;", " A({this._p: 0});", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
+ assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
verify([source]);
}
void test_privateOptionalParameter_withDefaultValue() {
Source source = addSource(EngineTestCase.createSource(["f({_p : 0}) {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
+ assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
verify([source]);
}
void test_recursiveConstructorRedirect() {
@@ -8961,7 +9331,7 @@
" A.b() : this.a();",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT,
CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]);
verify([source]);
@@ -8969,7 +9339,7 @@
void test_recursiveConstructorRedirect_directSelfReference() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() : this();", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]);
+ assertErrors(source, [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]);
verify([source]);
}
void test_recursiveFactoryRedirect() {
@@ -8984,7 +9354,7 @@
" factory C() = B;",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
@@ -8996,7 +9366,7 @@
void test_recursiveFactoryRedirect_directSelfReference() {
Source source = addSource(EngineTestCase.createSource(["class A {", " factory A() = A;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]);
+ assertErrors(source, [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]);
verify([source]);
}
void test_recursiveFactoryRedirect_generic() {
@@ -9011,7 +9381,7 @@
" factory C() = B;",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
@@ -9032,7 +9402,7 @@
" factory C.nameC() = B.nameB;",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
@@ -9058,7 +9428,7 @@
" factory C() = B;",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
@@ -9068,7 +9438,7 @@
void test_recursiveInterfaceInheritance_extends() {
Source source = addSource(EngineTestCase.createSource(["class A extends B {}", "class B extends A {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE]);
verify([source]);
@@ -9076,7 +9446,7 @@
void test_recursiveInterfaceInheritance_extends_implements() {
Source source = addSource(EngineTestCase.createSource(["class A extends B {}", "class B implements A {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE]);
verify([source]);
@@ -9084,7 +9454,7 @@
void test_recursiveInterfaceInheritance_implements() {
Source source = addSource(EngineTestCase.createSource(["class A implements B {}", "class B implements A {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE]);
verify([source]);
@@ -9094,7 +9464,7 @@
"abstract class A implements A {}",
"class B implements A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]);
+ assertErrors(source, [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]);
verify([source]);
}
void test_recursiveInterfaceInheritance_tail2() {
@@ -9103,7 +9473,7 @@
"abstract class B implements A {}",
"class C implements A {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE]);
verify([source]);
@@ -9115,7 +9485,7 @@
"abstract class C implements A {}",
"class D implements A {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE]);
@@ -9124,13 +9494,13 @@
void test_recursiveInterfaceInheritanceBaseCaseExtends() {
Source source = addSource(EngineTestCase.createSource(["class A extends A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS]);
+ assertErrors(source, [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS]);
verify([source]);
}
void test_recursiveInterfaceInheritanceBaseCaseImplements() {
Source source = addSource(EngineTestCase.createSource(["class A implements A {}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]);
+ assertErrors(source, [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]);
verify([source]);
}
void test_recursiveInterfaceInheritanceBaseCaseImplements_typedef() {
@@ -9139,7 +9509,7 @@
"class M {}",
"typedef B = A with M implements B;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]);
+ assertErrors(source, [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]);
verify([source]);
}
void test_redirectToNonConstConstructor() {
@@ -9149,55 +9519,55 @@
" const factory A.b() = A.a;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]);
verify([source]);
}
void test_referenceToDeclaredVariableInInitializer_closure() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var x = (x) {};", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
verify([source]);
}
void test_referenceToDeclaredVariableInInitializer_getter() {
Source source = addSource(EngineTestCase.createSource(["f() {", " int x = x + 1;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
verify([source]);
}
void test_referenceToDeclaredVariableInInitializer_setter() {
Source source = addSource(EngineTestCase.createSource(["f() {", " int x = x++;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
verify([source]);
}
void test_referenceToDeclaredVariableInInitializer_unqualifiedInvocation() {
Source source = addSource(EngineTestCase.createSource(["f() {", " var x = x();", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER]);
verify([source]);
}
void test_rethrowOutsideCatch() {
Source source = addSource(EngineTestCase.createSource(["f() {", " rethrow;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]);
+ assertErrors(source, [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]);
verify([source]);
}
void test_returnInGenerativeConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() { return 0; }", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
verify([source]);
}
void test_returnInGenerativeConstructor_expressionFunctionBody() {
Source source = addSource(EngineTestCase.createSource(["class A {", " A() => null;", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
verify([source]);
}
void test_superInInvalidContext_binaryExpression() {
Source source = addSource(EngineTestCase.createSource(["var v = super + 0;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
}
void test_superInInvalidContext_constructorFieldInitializer() {
Source source = addSource(EngineTestCase.createSource([
@@ -9209,7 +9579,7 @@
" B() : f = super.m();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
}
void test_superInInvalidContext_factoryConstructor() {
Source source = addSource(EngineTestCase.createSource([
@@ -9222,7 +9592,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
}
void test_superInInvalidContext_instanceVariableInitializer() {
Source source = addSource(EngineTestCase.createSource([
@@ -9233,7 +9603,7 @@
" var b = super.a;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
}
void test_superInInvalidContext_staticMethod() {
Source source = addSource(EngineTestCase.createSource([
@@ -9244,7 +9614,7 @@
" static n() { return super.m(); }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
}
void test_superInInvalidContext_staticVariableInitializer() {
Source source = addSource(EngineTestCase.createSource([
@@ -9255,17 +9625,17 @@
" static int b = super.a;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
}
void test_superInInvalidContext_topLevelFunction() {
Source source = addSource(EngineTestCase.createSource(["f() {", " super.f();", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
}
void test_superInInvalidContext_topLevelVariableInitializer() {
Source source = addSource(EngineTestCase.createSource(["var v = super.y;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
}
void test_superInRedirectingConstructor_redirectionSuper() {
Source source = addSource(EngineTestCase.createSource([
@@ -9275,7 +9645,7 @@
" B.name() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR]);
verify([source]);
}
void test_superInRedirectingConstructor_superRedirection() {
@@ -9286,31 +9656,31 @@
" B.name() {}",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR]);
+ assertErrors(source, [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR]);
verify([source]);
}
void test_typeAliasCannotReferenceItself_parameterType_named() {
Source source = addSource(EngineTestCase.createSource(["typedef A({A a});"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+ assertErrors(source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
}
void test_typeAliasCannotReferenceItself_parameterType_positional() {
Source source = addSource(EngineTestCase.createSource(["typedef A([A a]);"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+ assertErrors(source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
}
void test_typeAliasCannotReferenceItself_parameterType_required() {
Source source = addSource(EngineTestCase.createSource(["typedef A(A a);"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+ assertErrors(source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
}
void test_typeAliasCannotReferenceItself_parameterType_typeArgument() {
Source source = addSource(EngineTestCase.createSource(["typedef A(List<A> a);"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+ assertErrors(source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
}
void test_typeAliasCannotReferenceItself_returnClass_withTypeAlias() {
@@ -9321,19 +9691,19 @@
" B a;",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+ assertErrors(source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
}
void test_typeAliasCannotReferenceItself_returnType() {
Source source = addSource(EngineTestCase.createSource(["typedef A A();"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+ assertErrors(source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
}
void test_typeAliasCannotReferenceItself_returnType_indirect() {
Source source = addSource(EngineTestCase.createSource(["typedef B A();", "typedef A B();"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
@@ -9341,7 +9711,7 @@
void test_typeAliasCannotRereferenceItself_mixin_direct() {
Source source = addSource(EngineTestCase.createSource(["typedef M = Object with M;"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+ assertErrors(source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
}
void test_typeAliasCannotRereferenceItself_mixin_indirect() {
@@ -9349,7 +9719,7 @@
"typedef M1 = Object with M2;",
"typedef M2 = Object with M1;"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
verify([source]);
@@ -9363,13 +9733,13 @@
"}",
"f() { return const G<B>(); }"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ assertErrors(source, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
verify([source]);
}
void test_undefinedClass_const() {
Source source = addSource(EngineTestCase.createSource(["f() {", " return const A();", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.UNDEFINED_CLASS]);
+ assertErrors(source, [CompileTimeErrorCode.UNDEFINED_CLASS]);
verify([source]);
}
void test_undefinedConstructorInInitializer_explicit_named() {
@@ -9379,7 +9749,7 @@
" B() : super.named();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER]);
}
void test_undefinedConstructorInInitializer_explicit_unnamed() {
Source source = addSource(EngineTestCase.createSource([
@@ -9390,7 +9760,7 @@
" B() : super();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
+ assertErrors(source, [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
verify([source]);
}
void test_undefinedConstructorInInitializer_implicit() {
@@ -9402,19 +9772,19 @@
" B();",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
+ assertErrors(source, [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
verify([source]);
}
void test_undefinedFunction() {
Source source = addSource(EngineTestCase.createSource(["void f() {", " g();", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.UNDEFINED_FUNCTION]);
+ assertErrors(source, [CompileTimeErrorCode.UNDEFINED_FUNCTION]);
}
void test_undefinedFunction_hasImportPrefix() {
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as f;", "main() { return f(); }"]));
addSource2("/lib.dart", "library lib;");
resolve(source);
- assertErrors([CompileTimeErrorCode.UNDEFINED_FUNCTION]);
+ assertErrors(source, [CompileTimeErrorCode.UNDEFINED_FUNCTION]);
}
void test_undefinedFunction_inCatch() {
Source source = addSource(EngineTestCase.createSource([
@@ -9425,7 +9795,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.UNDEFINED_FUNCTION]);
+ assertErrors(source, [CompileTimeErrorCode.UNDEFINED_FUNCTION]);
}
void test_undefinedNamedParameter() {
Source source = addSource(EngineTestCase.createSource([
@@ -9436,39 +9806,39 @@
" const A(p: 0);",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER]);
+ assertErrors(source, [CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER]);
}
void test_uriDoesNotExist_export() {
Source source = addSource(EngineTestCase.createSource(["export 'unknown.dart';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+ assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
}
void test_uriDoesNotExist_import() {
Source source = addSource(EngineTestCase.createSource(["import 'unknown.dart';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+ assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
}
void test_uriDoesNotExist_part() {
Source source = addSource(EngineTestCase.createSource(["part 'unknown.dart';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+ assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
}
void test_uriWithInterpolation_constant() {
Source source = addSource(EngineTestCase.createSource(["import 'stuff_\$platform.dart';"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.URI_WITH_INTERPOLATION,
StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_uriWithInterpolation_nonConstant() {
Source source = addSource(EngineTestCase.createSource(["library lib;", "part '\${'a'}.dart';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.URI_WITH_INTERPOLATION]);
+ assertErrors(source, [CompileTimeErrorCode.URI_WITH_INTERPOLATION]);
}
void test_wrongNumberOfParametersForOperator_minus() {
Source source = addSource(EngineTestCase.createSource(["class A {", " operator -(a, b) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS]);
verify([source]);
reset();
}
@@ -9496,59 +9866,59 @@
void test_wrongNumberOfParametersForSetter_function_named() {
Source source = addSource("set x({p}) {}");
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
verify([source]);
}
void test_wrongNumberOfParametersForSetter_function_optional() {
Source source = addSource("set x([p]) {}");
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
verify([source]);
}
void test_wrongNumberOfParametersForSetter_function_tooFew() {
Source source = addSource("set x() {}");
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
verify([source]);
}
void test_wrongNumberOfParametersForSetter_function_tooMany() {
Source source = addSource("set x(a, b) {}");
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
verify([source]);
}
void test_wrongNumberOfParametersForSetter_method_named() {
Source source = addSource(EngineTestCase.createSource(["class A {", " set x({p}) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
verify([source]);
}
void test_wrongNumberOfParametersForSetter_method_optional() {
Source source = addSource(EngineTestCase.createSource(["class A {", " set x([p]) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
verify([source]);
}
void test_wrongNumberOfParametersForSetter_method_tooFew() {
Source source = addSource(EngineTestCase.createSource(["class A {", " set x() {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
verify([source]);
}
void test_wrongNumberOfParametersForSetter_method_tooMany() {
Source source = addSource(EngineTestCase.createSource(["class A {", " set x(a, b) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
verify([source]);
}
void check_constEvalThrowsException_binary_null(String expr, bool resolved) {
Source source = addSource("const C = ${expr};");
resolve(source);
if (resolved) {
- assertErrors([CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
verify([source]);
} else {
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
@@ -9561,7 +9931,7 @@
" const A(bool p) : a = ${expr};",
"}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
verify([source]);
reset();
}
@@ -9572,7 +9942,7 @@
" const A(int p) : a = ${expr};",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
@@ -9585,7 +9955,7 @@
" const A(num p) : a = ${expr};",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
@@ -9594,7 +9964,7 @@
void check_wrongNumberOfParametersForOperator(String name, String parameters) {
Source source = addSource(EngineTestCase.createSource(["class A {", " operator ${name}(${parameters}) {}", "}"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]);
+ assertErrors(source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]);
verify([source]);
reset();
}
@@ -9632,9 +10002,9 @@
final __test = new CompileTimeErrorCodeTest();
runJUnitTest(__test, __test.test_builtInIdentifierAsTypeName);
});
- _ut.test('test_builtInIdentifierAsTypeVariableName', () {
+ _ut.test('test_builtInIdentifierAsTypeParameterName', () {
final __test = new CompileTimeErrorCodeTest();
- runJUnitTest(__test, __test.test_builtInIdentifierAsTypeVariableName);
+ runJUnitTest(__test, __test.test_builtInIdentifierAsTypeParameterName);
});
_ut.test('test_builtInIdentifierAsTypedefName_classTypeAlias', () {
final __test = new CompileTimeErrorCodeTest();
@@ -10008,6 +10378,18 @@
final __test = new CompileTimeErrorCodeTest();
runJUnitTest(__test, __test.test_finalInitializedMultipleTimes_initializingFormals);
});
+ _ut.test('test_finalNotInitialized_instanceField_const_static', () {
+ final __test = new CompileTimeErrorCodeTest();
+ runJUnitTest(__test, __test.test_finalNotInitialized_instanceField_const_static);
+ });
+ _ut.test('test_finalNotInitialized_library_const', () {
+ final __test = new CompileTimeErrorCodeTest();
+ runJUnitTest(__test, __test.test_finalNotInitialized_library_const);
+ });
+ _ut.test('test_finalNotInitialized_local_const', () {
+ final __test = new CompileTimeErrorCodeTest();
+ runJUnitTest(__test, __test.test_finalNotInitialized_local_const);
+ });
_ut.test('test_getterAndMethodWithSameName', () {
final __test = new CompileTimeErrorCodeTest();
runJUnitTest(__test, __test.test_getterAndMethodWithSameName);
@@ -10999,12 +11381,13 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void setUp() {
super.setUp();
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
options.strictMode = true;
+ options.hint = false;
analysisContext.analysisOptions = options;
}
void test_assert_is() {
@@ -11014,7 +11397,7 @@
" return n & 0x0F;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_conditional_and_is() {
Source source = addSource(EngineTestCase.createSource([
@@ -11022,7 +11405,7 @@
" return (n is int && n > 0) ? n & 0x0F : 0;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_conditional_is() {
Source source = addSource(EngineTestCase.createSource([
@@ -11030,7 +11413,7 @@
" return (n is int) ? n & 0x0F : 0;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_conditional_isNot() {
Source source = addSource(EngineTestCase.createSource([
@@ -11038,7 +11421,7 @@
" return (n is! int) ? 0 : n & 0x0F;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_conditional_or_is() {
Source source = addSource(EngineTestCase.createSource([
@@ -11046,7 +11429,7 @@
" return (n is! int || n < 0) ? 0 : n & 0x0F;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_forEach() {
Source source = addSource(EngineTestCase.createSource([
@@ -11057,7 +11440,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_if_and_is() {
Source source = addSource(EngineTestCase.createSource([
@@ -11068,7 +11451,7 @@
" return 0;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_if_is() {
Source source = addSource(EngineTestCase.createSource([
@@ -11079,7 +11462,7 @@
" return 0;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_if_isNot() {
Source source = addSource(EngineTestCase.createSource([
@@ -11091,7 +11474,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_if_isNot_abrupt() {
Source source = addSource(EngineTestCase.createSource([
@@ -11102,7 +11485,7 @@
" return n & 0x0F;",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_if_or_is() {
Source source = addSource(EngineTestCase.createSource([
@@ -11114,12 +11497,12 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
void test_localVar() {
Source source = addSource(EngineTestCase.createSource(["int f() {", " num n = 1234;", " return n & 0x0F;", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
static dartSuite() {
_ut.group('StrictModeTest', () {
@@ -11569,7 +11952,7 @@
subclass.constructors = <ConstructorElement> [subConstructor];
SuperConstructorInvocation invocation = ASTFactory.superConstructorInvocation([]);
resolveInClass(invocation, subclass);
- JUnitTestCase.assertEquals(superConstructor, invocation.element);
+ JUnitTestCase.assertEquals(superConstructor, invocation.staticElement);
_listener.assertNoErrors();
}
void test_visitSuperConstructorInvocation_namedParameter() {
@@ -11584,7 +11967,7 @@
subclass.constructors = <ConstructorElement> [subConstructor];
SuperConstructorInvocation invocation = ASTFactory.superConstructorInvocation([ASTFactory.namedExpression2(parameterName, ASTFactory.integer(0))]);
resolveInClass(invocation, subclass);
- JUnitTestCase.assertEquals(superConstructor, invocation.element);
+ JUnitTestCase.assertEquals(superConstructor, invocation.staticElement);
JUnitTestCase.assertSame(parameter, ((invocation.argumentList.arguments[0] as NamedExpression)).name.label.staticElement);
_listener.assertNoErrors();
}
@@ -11982,19 +12365,19 @@
void test_import_package() {
Source source = addSource(EngineTestCase.createSource(["import 'package:somepackage/other.dart';"]));
resolve(source);
- assertErrors([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+ assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
}
void test_import_packageWithDotDot() {
Source source = addSource(EngineTestCase.createSource(["import 'package:somepackage/../other.dart';"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.URI_DOES_NOT_EXIST,
PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT]);
}
void test_import_packageWithLeadingDotDot() {
Source source = addSource(EngineTestCase.createSource(["import 'package:../other.dart';"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
CompileTimeErrorCode.URI_DOES_NOT_EXIST,
PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT]);
}
@@ -12003,47 +12386,47 @@
cacheSource("/myproj/lib/other.dart", "");
Source source = addSource2("/myproj/web/test.dart", EngineTestCase.createSource(["import '../lib/other.dart';"]));
resolve(source);
- assertErrors([PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
+ assertErrors(source, [PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
}
void test_import_referenceIntoLibDirectory_no_pubspec() {
cacheSource("/myproj/lib/other.dart", "");
Source source = addSource2("/myproj/web/test.dart", EngineTestCase.createSource(["import '../lib/other.dart';"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_import_referenceOutOfLibDirectory() {
cacheSource("/myproj/pubspec.yaml", "");
cacheSource("/myproj/web/other.dart", "");
Source source = addSource2("/myproj/lib/test.dart", EngineTestCase.createSource(["import '../web/other.dart';"]));
resolve(source);
- assertErrors([PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
+ assertErrors(source, [PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
}
void test_import_referenceOutOfLibDirectory_no_pubspec() {
cacheSource("/myproj/web/other.dart", "");
Source source = addSource2("/myproj/lib/test.dart", EngineTestCase.createSource(["import '../web/other.dart';"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_import_valid_inside_lib1() {
cacheSource("/myproj/pubspec.yaml", "");
cacheSource("/myproj/lib/other.dart", "");
Source source = addSource2("/myproj/lib/test.dart", EngineTestCase.createSource(["import 'other.dart';"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_import_valid_inside_lib2() {
cacheSource("/myproj/pubspec.yaml", "");
cacheSource("/myproj/lib/bar/other.dart", "");
Source source = addSource2("/myproj/lib/foo/test.dart", EngineTestCase.createSource(["import '../bar/other.dart';"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
void test_import_valid_outside_lib() {
cacheSource("/myproj/pubspec.yaml", "");
cacheSource("/myproj/web/other.dart", "");
Source source = addSource2("/myproj/lib2/test.dart", EngineTestCase.createSource(["import '../web/other.dart';"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
}
static dartSuite() {
_ut.group('PubSuggestionCodeTest', () {
@@ -12099,37 +12482,37 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void fail_commentReferenceConstructorNotVisible() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([StaticWarningCode.COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE]);
+ assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE]);
verify([source]);
}
void fail_commentReferenceIdentifierNotVisible() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([StaticWarningCode.COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE]);
+ assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE]);
verify([source]);
}
void fail_commentReferenceUndeclaredConstructor() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([StaticWarningCode.COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR]);
+ assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR]);
verify([source]);
}
void fail_commentReferenceUndeclaredIdentifier() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([StaticWarningCode.COMMENT_REFERENCE_UNDECLARED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_UNDECLARED_IDENTIFIER]);
verify([source]);
}
void fail_commentReferenceUriNotLibrary() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([StaticWarningCode.COMMENT_REFERENCE_URI_NOT_LIBRARY]);
+ assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_URI_NOT_LIBRARY]);
verify([source]);
}
void fail_mismatchedAccessorTypes_getterAndSuperSetter() {
@@ -12142,7 +12525,7 @@
" set g(String v) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+ assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
verify([source]);
}
void fail_mismatchedAccessorTypes_superGetterAndSetter() {
@@ -12155,38 +12538,38 @@
" String get g { return ''; }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+ assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
verify([source]);
}
void fail_undefinedGetter() {
Source source = addSource(EngineTestCase.createSource([]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_GETTER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_GETTER]);
verify([source]);
}
void fail_undefinedIdentifier_commentReference() {
Source source = addSource(EngineTestCase.createSource(["/** [m] xxx [new B.c] */", "class A {", "}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
StaticWarningCode.UNDEFINED_IDENTIFIER,
StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void fail_undefinedSetter() {
Source source = addSource(EngineTestCase.createSource(["class C {}", "f(var p) {", " C.m = 0;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_SETTER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_SETTER]);
verify([source]);
}
void fail_undefinedStaticMethodOrGetter_getter() {
Source source = addSource(EngineTestCase.createSource(["class C {}", "f(var p) {", " f(C.m);", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER]);
verify([source]);
}
void fail_undefinedStaticMethodOrGetter_method() {
Source source = addSource(EngineTestCase.createSource(["class C {}", "f(var p) {", " f(C.m());", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER]);
verify([source]);
}
void test_ambiguousImport_as() {
@@ -12197,7 +12580,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
void test_ambiguousImport_extends() {
Source source = addSource(EngineTestCase.createSource([
@@ -12207,7 +12590,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
StaticWarningCode.AMBIGUOUS_IMPORT,
CompileTimeErrorCode.EXTENDS_NON_CLASS]);
}
@@ -12219,7 +12602,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
StaticWarningCode.AMBIGUOUS_IMPORT,
CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
}
@@ -12232,7 +12615,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
void test_ambiguousImport_is() {
Source source = addSource(EngineTestCase.createSource([
@@ -12242,7 +12625,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
void test_ambiguousImport_qualifier() {
Source source = addSource(EngineTestCase.createSource([
@@ -12252,7 +12635,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
void test_ambiguousImport_typeAnnotation() {
Source source = addSource(EngineTestCase.createSource([
@@ -12269,7 +12652,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
StaticWarningCode.AMBIGUOUS_IMPORT,
StaticWarningCode.AMBIGUOUS_IMPORT,
StaticWarningCode.AMBIGUOUS_IMPORT,
@@ -12287,7 +12670,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
void test_ambiguousImport_typeArgument_instanceCreation() {
Source source = addSource(EngineTestCase.createSource([
@@ -12298,7 +12681,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
resolve(source);
- assertErrors([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
void test_ambiguousImport_varRead() {
Source source = addSource(EngineTestCase.createSource([
@@ -12309,7 +12692,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "var v;"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "var v;"]));
resolve(source);
- assertErrors([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
void test_ambiguousImport_varWrite() {
Source source = addSource(EngineTestCase.createSource([
@@ -12319,7 +12702,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "var v;"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "var v;"]));
resolve(source);
- assertErrors([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
void test_argumentTypeNotAssignable_annotation_namedConstructor() {
Source source = addSource(EngineTestCase.createSource([
@@ -12330,7 +12713,7 @@
"main() {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_annotation_unnamedConstructor() {
@@ -12342,7 +12725,7 @@
"main() {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_binary() {
@@ -12354,7 +12737,7 @@
" a + '0';",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_index() {
@@ -12366,7 +12749,7 @@
" a['0'];",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_callParameter() {
@@ -12378,7 +12761,7 @@
" a('0');",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_callVariable() {
@@ -12391,13 +12774,13 @@
" a('0');",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_functionParameter() {
Source source = addSource(EngineTestCase.createSource(["a(b(int p)) {", " b('0');", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_functionTypes_optional() {
@@ -12408,7 +12791,7 @@
" acceptFunNumOptBool(funNumBool);",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_generic() {
@@ -12420,31 +12803,31 @@
" a.m(1);",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_named() {
Source source = addSource(EngineTestCase.createSource(["f({String p}) {}", "main() {", " f(p: 42);", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_optional() {
Source source = addSource(EngineTestCase.createSource(["f([String p]) {}", "main() {", " f(42);", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_required() {
Source source = addSource(EngineTestCase.createSource(["f(String p) {}", "main() {", " f(42);", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_typedef_generic() {
Source source = addSource(EngineTestCase.createSource(["typedef A<T>(T p);", "f(A<int> a) {", " a('1');", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_typedef_local() {
@@ -12456,13 +12839,13 @@
" a('1');",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_invocation_typedef_parameter() {
Source source = addSource(EngineTestCase.createSource(["typedef A(int p);", "f(A a) {", " a('1');", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_new_generic() {
@@ -12474,7 +12857,7 @@
" new A<String>(42);",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_new_optional() {
@@ -12486,7 +12869,7 @@
" new A(42);",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_argumentTypeNotAssignable_new_required() {
@@ -12498,7 +12881,7 @@
" new A(42);",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_assignmentToConst_instanceVariable() {
@@ -12510,13 +12893,13 @@
" A.v = 1;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_CONST]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_CONST]);
verify([source]);
}
void test_assignmentToConst_localVariable() {
Source source = addSource(EngineTestCase.createSource(["f() {", " const x = 0;", " x = 1;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_CONST]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_CONST]);
verify([source]);
}
void test_assignmentToFinal_instanceVariable() {
@@ -12529,25 +12912,25 @@
" a.v = 1;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
verify([source]);
}
void test_assignmentToFinal_localVariable() {
Source source = addSource(EngineTestCase.createSource(["f() {", " final x = 0;", " x = 1;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
verify([source]);
}
void test_assignmentToFinal_prefixMinusMinus() {
Source source = addSource(EngineTestCase.createSource(["f() {", " final x = 0;", " --x;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
verify([source]);
}
void test_assignmentToFinal_prefixPlusPlus() {
Source source = addSource(EngineTestCase.createSource(["f() {", " final x = 0;", " ++x;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
verify([source]);
}
void test_assignmentToFinal_propertyAccess() {
@@ -12562,25 +12945,25 @@
" B.a.x = 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
verify([source]);
}
void test_assignmentToFinal_suffixMinusMinus() {
Source source = addSource(EngineTestCase.createSource(["f() {", " final x = 0;", " x--;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
verify([source]);
}
void test_assignmentToFinal_suffixPlusPlus() {
Source source = addSource(EngineTestCase.createSource(["f() {", " final x = 0;", " x++;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
verify([source]);
}
void test_assignmentToFinal_topLevelVariable() {
Source source = addSource(EngineTestCase.createSource(["final x = 0;", "f() { x = 1; }"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_FINAL]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
verify([source]);
}
void test_assignmentToMethod() {
@@ -12592,7 +12975,7 @@
" a.m = () {};",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.ASSIGNMENT_TO_METHOD]);
+ assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_METHOD]);
verify([source]);
}
void test_caseBlockNotTerminated() {
@@ -12606,19 +12989,19 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]);
+ assertErrors(source, [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]);
verify([source]);
}
void test_castToNonType() {
Source source = addSource(EngineTestCase.createSource(["var A = 0;", "f(String s) { var x = s as A; }"]));
resolve(source);
- assertErrors([StaticWarningCode.CAST_TO_NON_TYPE]);
+ assertErrors(source, [StaticWarningCode.CAST_TO_NON_TYPE]);
verify([source]);
}
void test_concreteClassWithAbstractMember() {
Source source = addSource(EngineTestCase.createSource(["class A {", " m();", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]);
verify([source]);
}
void test_conflictingInstanceGetterAndSuperclassMember_direct_field() {
@@ -12630,7 +13013,7 @@
" get v => 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
verify([source]);
}
void test_conflictingInstanceGetterAndSuperclassMember_direct_getter() {
@@ -12642,7 +13025,7 @@
" get v => 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
verify([source]);
}
void test_conflictingInstanceGetterAndSuperclassMember_direct_method() {
@@ -12654,7 +13037,7 @@
" get v => 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
verify([source]);
}
void test_conflictingInstanceGetterAndSuperclassMember_direct_setter() {
@@ -12666,7 +13049,7 @@
" get v => 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
verify([source]);
}
void test_conflictingInstanceGetterAndSuperclassMember_indirect() {
@@ -12679,7 +13062,7 @@
" get v => 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
verify([source]);
}
void test_conflictingInstanceGetterAndSuperclassMember_mixin() {
@@ -12691,7 +13074,7 @@
" get v => 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
verify([source]);
}
void test_conflictingInstanceSetterAndSuperclassMember() {
@@ -12703,7 +13086,7 @@
" set v(x) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]);
verify([source]);
}
void test_conflictingStaticGetterAndInstanceSetter_mixin() {
@@ -12715,7 +13098,7 @@
" static get x => 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
verify([source]);
}
void test_conflictingStaticGetterAndInstanceSetter_superClass() {
@@ -12727,7 +13110,7 @@
" static get x => 0;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
verify([source]);
}
void test_conflictingStaticGetterAndInstanceSetter_thisClass() {
@@ -12737,7 +13120,7 @@
" set x(int p) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
verify([source]);
}
void test_conflictingStaticSetterAndInstanceMember_thisClass_getter() {
@@ -12747,13 +13130,13 @@
" static set x(int p) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]);
verify([source]);
}
void test_conflictingStaticSetterAndInstanceMember_thisClass_method() {
Source source = addSource(EngineTestCase.createSource(["class A {", " x() {}", " static set x(int p) {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]);
+ assertErrors(source, [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]);
verify([source]);
}
void test_constWithAbstractClass() {
@@ -12765,13 +13148,13 @@
" A a = const A();",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.CONST_WITH_ABSTRACT_CLASS]);
+ assertErrors(source, [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS]);
verify([source]);
}
void test_equalKeysInMap() {
Source source = addSource(EngineTestCase.createSource(["var m = {'a' : 0, 'b' : 1, 'a' : 2};"]));
resolve(source);
- assertErrors([StaticWarningCode.EQUAL_KEYS_IN_MAP]);
+ assertErrors(source, [StaticWarningCode.EQUAL_KEYS_IN_MAP]);
verify([source]);
}
void test_exportDuplicatedLibraryName() {
@@ -12782,13 +13165,13 @@
addSource2("/lib1.dart", "library lib;");
addSource2("/lib2.dart", "library lib;");
resolve(source);
- assertErrors([StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAME]);
+ assertErrors(source, [StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAME]);
verify([source]);
}
void test_extraPositionalArguments() {
Source source = addSource(EngineTestCase.createSource(["f() {}", "main() {", " f(0, 1, '2');", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS]);
+ assertErrors(source, [StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS]);
verify([source]);
}
void test_fieldInitializedInInitializerAndDeclaration_final() {
@@ -12798,19 +13181,19 @@
" A() : x = 1 {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION]);
+ assertErrors(source, [StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION]);
verify([source]);
}
void test_fieldInitializerNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A() : x = '';", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]);
verify([source]);
}
void test_fieldInitializingFormalNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A(String this.x) {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE]);
verify([source]);
}
@@ -12826,61 +13209,43 @@
void test_finalInitializedInDeclarationAndConstructor_initializers() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final x = 0;", " A() : x = 0 {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION]);
+ assertErrors(source, [StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION]);
verify([source]);
}
void test_finalInitializedInDeclarationAndConstructor_initializingFormal() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final x = 0;", " A(this.x) {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR]);
+ assertErrors(source, [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR]);
verify([source]);
}
void test_finalNotInitialized_inConstructor() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final int x;", " A() {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
- verify([source]);
- }
- void test_finalNotInitialized_instanceField_const_static() {
- Source source = addSource(EngineTestCase.createSource(["class A {", " static const F;", "}"]));
- resolve(source);
- assertErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
+ assertErrors(source, [StaticWarningCode.FINAL_NOT_INITIALIZED]);
verify([source]);
}
void test_finalNotInitialized_instanceField_final() {
Source source = addSource(EngineTestCase.createSource(["class A {", " final F;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
+ assertErrors(source, [StaticWarningCode.FINAL_NOT_INITIALIZED]);
verify([source]);
}
void test_finalNotInitialized_instanceField_final_static() {
Source source = addSource(EngineTestCase.createSource(["class A {", " static final F;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
- verify([source]);
- }
- void test_finalNotInitialized_library_const() {
- Source source = addSource(EngineTestCase.createSource(["const F;"]));
- resolve(source);
- assertErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
+ assertErrors(source, [StaticWarningCode.FINAL_NOT_INITIALIZED]);
verify([source]);
}
void test_finalNotInitialized_library_final() {
Source source = addSource(EngineTestCase.createSource(["final F;"]));
resolve(source);
- assertErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
- verify([source]);
- }
- void test_finalNotInitialized_local_const() {
- Source source = addSource(EngineTestCase.createSource(["f() {", " const int x;", "}"]));
- resolve(source);
- assertErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
+ assertErrors(source, [StaticWarningCode.FINAL_NOT_INITIALIZED]);
verify([source]);
}
void test_finalNotInitialized_local_final() {
Source source = addSource(EngineTestCase.createSource(["f() {", " final int x;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
+ assertErrors(source, [StaticWarningCode.FINAL_NOT_INITIALIZED]);
verify([source]);
}
void test_importDuplicatedLibraryName() {
@@ -12891,7 +13256,7 @@
addSource2("/lib1.dart", "library lib;");
addSource2("/lib2.dart", "library lib;");
resolve(source);
- assertErrors([
+ assertErrors(source, [
StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAME,
HintCode.UNUSED_IMPORT,
HintCode.UNUSED_IMPORT]);
@@ -12908,7 +13273,7 @@
"class C implements A, B {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
+ assertErrors(source, [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
verify([source]);
}
void test_instanceMethodNameCollidesWithSuperclassStatic_field() {
@@ -12920,7 +13285,7 @@
" void n() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+ assertErrors(source, [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
verify([source]);
}
void test_instanceMethodNameCollidesWithSuperclassStatic_field2() {
@@ -12934,7 +13299,7 @@
" void n() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+ assertErrors(source, [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
verify([source]);
}
void test_instanceMethodNameCollidesWithSuperclassStatic_getter() {
@@ -12946,7 +13311,7 @@
" void n() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+ assertErrors(source, [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
verify([source]);
}
void test_instanceMethodNameCollidesWithSuperclassStatic_getter2() {
@@ -12960,7 +13325,7 @@
" void n() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+ assertErrors(source, [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
verify([source]);
}
void test_instanceMethodNameCollidesWithSuperclassStatic_method() {
@@ -12972,7 +13337,7 @@
" void n() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+ assertErrors(source, [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
verify([source]);
}
void test_instanceMethodNameCollidesWithSuperclassStatic_method2() {
@@ -12986,7 +13351,7 @@
" void n() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+ assertErrors(source, [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
verify([source]);
}
void test_instanceMethodNameCollidesWithSuperclassStatic_setter() {
@@ -12998,7 +13363,7 @@
" void n() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+ assertErrors(source, [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
verify([source]);
}
void test_instanceMethodNameCollidesWithSuperclassStatic_setter2() {
@@ -13012,7 +13377,7 @@
" void n() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
+ assertErrors(source, [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC]);
verify([source]);
}
void test_invalidGetterOverrideReturnType() {
@@ -13024,7 +13389,7 @@
" String get g { return 'a'; }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]);
verify([source]);
}
void test_invalidGetterOverrideReturnType_implicit() {
@@ -13036,7 +13401,7 @@
" int f;",
"}"]));
resolve(source);
- assertErrors([
+ assertErrors(source, [
StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE,
StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
verify([source]);
@@ -13050,7 +13415,7 @@
" m({String a}) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE]);
verify([source]);
}
void test_invalidMethodOverrideNormalParamType() {
@@ -13062,7 +13427,7 @@
" m(String a) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]);
verify([source]);
}
void test_invalidMethodOverrideOptionalParamType() {
@@ -13074,7 +13439,7 @@
" m([String a]) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]);
verify([source]);
}
void test_invalidMethodOverrideReturnType_interface() {
@@ -13086,7 +13451,7 @@
" String m() { return 'a'; }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
verify([source]);
}
void test_invalidMethodOverrideReturnType_interface2() {
@@ -13100,7 +13465,7 @@
" String m() { return 'a'; }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
verify([source]);
}
void test_invalidMethodOverrideReturnType_mixin() {
@@ -13112,7 +13477,7 @@
" String m() { return 'a'; }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
verify([source]);
}
void test_invalidMethodOverrideReturnType_superclass() {
@@ -13124,7 +13489,7 @@
" String m() { return 'a'; }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
verify([source]);
}
void test_invalidMethodOverrideReturnType_superclass2() {
@@ -13138,7 +13503,7 @@
" String m() { return 'a'; }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
verify([source]);
}
void test_invalidMethodOverrideReturnType_void() {
@@ -13150,7 +13515,7 @@
" void m() {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]);
verify([source]);
}
void test_invalidOverrideDifferentDefaultValues_named() {
@@ -13162,7 +13527,7 @@
" m({int p : 1}) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED]);
+ assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED]);
verify([source]);
}
void test_invalidOverrideDifferentDefaultValues_positional() {
@@ -13174,7 +13539,7 @@
" m([int p = 1]) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL]);
+ assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL]);
verify([source]);
}
void test_invalidOverrideNamed_fewerNamedParameters() {
@@ -13186,7 +13551,7 @@
" m({a}) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_OVERRIDE_NAMED]);
+ assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_NAMED]);
verify([source]);
}
void test_invalidOverrideNamed_missingNamedParameter() {
@@ -13198,7 +13563,7 @@
" m({a, c}) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_OVERRIDE_NAMED]);
+ assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_NAMED]);
verify([source]);
}
void test_invalidOverridePositional() {
@@ -13210,7 +13575,7 @@
" m([a]) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]);
+ assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]);
verify([source]);
}
void test_invalidOverrideRequired() {
@@ -13222,7 +13587,7 @@
" m(a, b) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_OVERRIDE_REQUIRED]);
+ assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_REQUIRED]);
verify([source]);
}
void test_invalidSetterOverrideNormalParamType() {
@@ -13234,25 +13599,25 @@
" void set s(String v) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
+ assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
verify([source]);
}
void test_listElementTypeNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["var v = <String> [42];"]));
resolve(source);
- assertErrors([StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_mapKeyTypeNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["var v = <String, int > {1 : 2};"]));
resolve(source);
- assertErrors([StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_mapValueTypeNotAssignable() {
Source source = addSource(EngineTestCase.createSource(["var v = <String, String> {'a' : 2};"]));
resolve(source);
- assertErrors([StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
void test_mismatchedAccessorTypes_class() {
@@ -13262,13 +13627,13 @@
" set g(String v) {}",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+ assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
verify([source]);
}
void test_mismatchedAccessorTypes_topLevel() {
Source source = addSource(EngineTestCase.createSource(["int get g { return 0; }", "set g(String v) {}"]));
resolve(source);
- assertErrors([StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+ assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
verify([source]);
}
void test_newWithAbstractClass() {
@@ -13278,13 +13643,13 @@
" A a = new A();",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]);
+ assertErrors(source, [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]);
verify([source]);
}
void test_newWithInvalidTypeParameters() {
Source source = addSource(EngineTestCase.createSource(["class A {}", "f() { return new A<A>(); }"]));
resolve(source);
- assertErrors([StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS]);
+ assertErrors(source, [StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS]);
verify([source]);
}
void test_newWithInvalidTypeParameters_tooFew() {
@@ -13295,7 +13660,7 @@
" return new C<A>();",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS]);
+ assertErrors(source, [StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS]);
verify([source]);
}
void test_newWithInvalidTypeParameters_tooMany() {
@@ -13306,13 +13671,13 @@
" return new C<A, A>();",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS]);
+ assertErrors(source, [StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS]);
verify([source]);
}
void test_newWithNonType() {
Source source = addSource(EngineTestCase.createSource(["var A = 0;", "void f() {", " var a = new A();", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.NEW_WITH_NON_TYPE]);
+ assertErrors(source, [StaticWarningCode.NEW_WITH_NON_TYPE]);
verify([source]);
}
void test_newWithNonType_fromLibrary() {
@@ -13325,7 +13690,7 @@
"lib.B b;"]));
resolve(source1);
resolve(source2);
- assertErrors([StaticWarningCode.NEW_WITH_NON_TYPE]);
+ assertErrors(source2, [StaticWarningCode.NEW_WITH_NON_TYPE]);
verify([source1]);
}
void test_newWithUndefinedConstructor() {
@@ -13337,7 +13702,7 @@
" new A.name();",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]);
+ assertErrors(source, [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]);
}
void test_newWithUndefinedConstructorDefault() {
Source source = addSource(EngineTestCase.createSource([
@@ -13348,7 +13713,7 @@
" new A();",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]);
+ assertErrors(source, [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberFivePlus() {
@@ -13363,7 +13728,7 @@
"class C extends A {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberFour() {
@@ -13377,7 +13742,7 @@
"class C extends A {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_getter_fromInterface() {
@@ -13388,7 +13753,7 @@
"class C implements I {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_getter_fromSuperclass() {
@@ -13399,7 +13764,7 @@
"class C extends A {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_method_fromInterface() {
@@ -13410,7 +13775,7 @@
"class C implements I {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_method_fromSuperclass() {
@@ -13421,7 +13786,7 @@
"class C extends A {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_method_optionalParamCount() {
@@ -13435,7 +13800,7 @@
"class C implements A, B {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_setter_fromInterface() {
@@ -13446,7 +13811,7 @@
"class C implements I {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_setter_fromSuperclass() {
@@ -13457,7 +13822,7 @@
"class C extends A {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberOne_superclasses_interface() {
@@ -13471,7 +13836,7 @@
"class C extends B {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberThree() {
@@ -13484,7 +13849,7 @@
"class C extends A {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE]);
verify([source]);
}
void test_nonAbstractClassInheritsAbstractMemberTwo() {
@@ -13496,13 +13861,13 @@
"class C extends A {",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO]);
+ assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO]);
verify([source]);
}
void test_nonTypeInCatchClause_noElement() {
Source source = addSource(EngineTestCase.createSource(["f() {", " try {", " } on T catch (e) {", " }", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE]);
+ assertErrors(source, [StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE]);
verify([source]);
}
void test_nonTypeInCatchClause_notType() {
@@ -13514,19 +13879,19 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE]);
+ assertErrors(source, [StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE]);
verify([source]);
}
void test_nonVoidReturnForOperator() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int operator []=(a, b) {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]);
+ assertErrors(source, [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]);
verify([source]);
}
void test_nonVoidReturnForSetter_function() {
Source source = addSource(EngineTestCase.createSource(["int set x(int v) {", " return 42;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]);
+ assertErrors(source, [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]);
verify([source]);
}
void test_nonVoidReturnForSetter_method() {
@@ -13537,26 +13902,26 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]);
+ assertErrors(source, [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]);
verify([source]);
}
void test_notAType() {
Source source = addSource(EngineTestCase.createSource(["f() {}", "main() {", " f v = null;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.NOT_A_TYPE]);
+ assertErrors(source, [StaticWarningCode.NOT_A_TYPE]);
verify([source]);
}
void test_notEnoughRequiredArguments() {
Source source = addSource(EngineTestCase.createSource(["f(int a, String b) {}", "main() {", " f();", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
+ assertErrors(source, [StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
verify([source]);
}
void test_partOfDifferentLibrary() {
Source source = addSource(EngineTestCase.createSource(["library lib;", "part 'part.dart';"]));
addSource2("/part.dart", EngineTestCase.createSource(["part of lub;"]));
resolve(source);
- assertErrors([StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]);
+ assertErrors(source, [StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]);
verify([source]);
}
void test_redirectToInvalidFunctionType() {
@@ -13568,7 +13933,7 @@
" factory B() = A;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE]);
+ assertErrors(source, [StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE]);
verify([source]);
}
void test_redirectToInvalidReturnType() {
@@ -13580,7 +13945,7 @@
" factory B() = A;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE]);
+ assertErrors(source, [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE]);
verify([source]);
}
void test_redirectToMissingConstructor_named() {
@@ -13592,7 +13957,7 @@
" factory B() = A.name;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
+ assertErrors(source, [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
}
void test_redirectToMissingConstructor_unnamed() {
Source source = addSource(EngineTestCase.createSource([
@@ -13603,42 +13968,42 @@
" factory B() = A;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
+ assertErrors(source, [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
}
void test_redirectToNonClass_notAType() {
Source source = addSource(EngineTestCase.createSource(["class B {", " int A;", " factory B() = A;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.REDIRECT_TO_NON_CLASS]);
+ assertErrors(source, [StaticWarningCode.REDIRECT_TO_NON_CLASS]);
verify([source]);
}
void test_redirectToNonClass_undefinedIdentifier() {
Source source = addSource(EngineTestCase.createSource(["class B {", " factory B() = A;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.REDIRECT_TO_NON_CLASS]);
+ assertErrors(source, [StaticWarningCode.REDIRECT_TO_NON_CLASS]);
verify([source]);
}
void test_returnWithoutValue() {
Source source = addSource(EngineTestCase.createSource(["int f() { return; }"]));
resolve(source);
- assertErrors([StaticWarningCode.RETURN_WITHOUT_VALUE]);
+ assertErrors(source, [StaticWarningCode.RETURN_WITHOUT_VALUE]);
verify([source]);
}
void test_staticAccessToInstanceMember_method_invocation() {
Source source = addSource(EngineTestCase.createSource(["class A {", " m() {}", "}", "main() {", " A.m();", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
+ assertErrors(source, [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
verify([source]);
}
void test_staticAccessToInstanceMember_method_reference() {
Source source = addSource(EngineTestCase.createSource(["class A {", " m() {}", "}", "main() {", " A.m;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
+ assertErrors(source, [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
verify([source]);
}
void test_staticAccessToInstanceMember_propertyAccess_field() {
Source source = addSource(EngineTestCase.createSource(["class A {", " var f;", "}", "main() {", " A.f;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
+ assertErrors(source, [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
verify([source]);
}
void test_staticAccessToInstanceMember_propertyAccess_getter() {
@@ -13650,7 +14015,7 @@
" A.f;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
+ assertErrors(source, [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
verify([source]);
}
void test_staticAccessToInstanceMember_propertyAccess_setter() {
@@ -13662,7 +14027,7 @@
" A.f = 42;",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
+ assertErrors(source, [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]);
verify([source]);
}
void test_switchExpressionNotAssignable() {
@@ -13673,65 +14038,65 @@
" }",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]);
+ assertErrors(source, [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]);
verify([source]);
}
void test_typeParameterReferencedByStatic_field() {
Source source = addSource(EngineTestCase.createSource(["class A<K> {", " static K k;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
+ assertErrors(source, [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
verify([source]);
}
void test_typeParameterReferencedByStatic_getter() {
Source source = addSource(EngineTestCase.createSource(["class A<K> {", " static K get k => 0;", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
+ assertErrors(source, [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
verify([source]);
}
void test_typeParameterReferencedByStatic_methodBodyReference() {
Source source = addSource(EngineTestCase.createSource(["class A<K> {", " static m() {", " K k;", " }", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
+ assertErrors(source, [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
verify([source]);
}
void test_typeParameterReferencedByStatic_methodParameter() {
Source source = addSource(EngineTestCase.createSource(["class A<K> {", " static m(K k) {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
+ assertErrors(source, [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
verify([source]);
}
void test_typeParameterReferencedByStatic_methodReturn() {
Source source = addSource(EngineTestCase.createSource(["class A<K> {", " static K m() {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
+ assertErrors(source, [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
verify([source]);
}
void test_typeParameterReferencedByStatic_setter() {
Source source = addSource(EngineTestCase.createSource(["class A<K> {", " static set s(K k) {}", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
+ assertErrors(source, [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
verify([source]);
}
void test_typeTestNonType() {
Source source = addSource(EngineTestCase.createSource(["var A = 0;", "f(var p) {", " if (p is A) {", " }", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.TYPE_TEST_NON_TYPE]);
+ assertErrors(source, [StaticWarningCode.TYPE_TEST_NON_TYPE]);
verify([source]);
}
void test_undefinedClass_instanceCreation() {
Source source = addSource(EngineTestCase.createSource(["f() { new C(); }"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_CLASS]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
}
void test_undefinedClass_variableDeclaration() {
Source source = addSource(EngineTestCase.createSource(["f() { C c; }"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_CLASS]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
}
void test_undefinedClassBoolean_variableDeclaration() {
Source source = addSource(EngineTestCase.createSource(["f() { boolean v; }"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_CLASS_BOOLEAN]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS_BOOLEAN]);
}
void test_undefinedGetter_fromLibrary() {
Source source1 = addSource2("lib.dart", "");
@@ -13742,19 +14107,24 @@
"}"]));
resolve(source1);
resolve(source2);
- assertErrors([StaticWarningCode.UNDEFINED_GETTER]);
+ assertErrors(source2, [StaticWarningCode.UNDEFINED_GETTER]);
verify([source1]);
}
+ void test_undefinedIdentifier_for() {
+ Source source = addSource(EngineTestCase.createSource(["f(var l) {", " for (e in l) {", " }", "}"]));
+ resolve(source);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ }
void test_undefinedIdentifier_function() {
Source source = addSource(EngineTestCase.createSource(["int a() => b;"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_undefinedIdentifier_function_prefix() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "class C {}"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as b;", "", "int a() => b;", "b.C c;"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
verify([source]);
}
void test_undefinedIdentifier_hideInBlock_function() {
@@ -13766,7 +14136,7 @@
"}",
"print(x) {}"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_undefinedIdentifier_hideInBlock_local() {
Source source = addSource(EngineTestCase.createSource([
@@ -13777,7 +14147,7 @@
"}",
"print(x) {}"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_undefinedIdentifier_hideInBlock_subBlock() {
Source source = addSource(EngineTestCase.createSource([
@@ -13790,33 +14160,33 @@
"}",
"print(x) {}"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_undefinedIdentifier_initializer() {
Source source = addSource(EngineTestCase.createSource(["var a = b;"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_undefinedIdentifier_initializer_prefix() {
addSource2("/lib.dart", EngineTestCase.createSource(["library lib;", "class C {}"]));
Source source = addSource(EngineTestCase.createSource(["import 'lib.dart' as b;", "", "var a = b;", "b.C c;"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_undefinedIdentifier_metadata() {
Source source = addSource(EngineTestCase.createSource(["@undefined class A {}"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_undefinedIdentifier_methodInvocation() {
Source source = addSource(EngineTestCase.createSource(["f() { C.m(); }"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_IDENTIFIER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
}
void test_undefinedNamedParameter() {
Source source = addSource(EngineTestCase.createSource(["f({a, b}) {}", "main() {", " f(c: 1);", "}"]));
resolve(source);
- assertErrors([StaticWarningCode.UNDEFINED_NAMED_PARAMETER]);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_NAMED_PARAMETER]);
}
void test_undefinedSetter() {
Source source1 = addSource2("lib.dart", "");
@@ -13827,7 +14197,7 @@
"}"]));
resolve(source1);
resolve(source2);
- assertErrors([StaticWarningCode.UNDEFINED_SETTER]);
+ assertErrors(source2, [StaticWarningCode.UNDEFINED_SETTER]);
}
static dartSuite() {
_ut.group('StaticWarningCodeTest', () {
@@ -14091,10 +14461,6 @@
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_finalNotInitialized_inConstructor);
});
- _ut.test('test_finalNotInitialized_instanceField_const_static', () {
- final __test = new StaticWarningCodeTest();
- runJUnitTest(__test, __test.test_finalNotInitialized_instanceField_const_static);
- });
_ut.test('test_finalNotInitialized_instanceField_final', () {
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_finalNotInitialized_instanceField_final);
@@ -14103,18 +14469,10 @@
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_finalNotInitialized_instanceField_final_static);
});
- _ut.test('test_finalNotInitialized_library_const', () {
- final __test = new StaticWarningCodeTest();
- runJUnitTest(__test, __test.test_finalNotInitialized_library_const);
- });
_ut.test('test_finalNotInitialized_library_final', () {
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_finalNotInitialized_library_final);
});
- _ut.test('test_finalNotInitialized_local_const', () {
- final __test = new StaticWarningCodeTest();
- runJUnitTest(__test, __test.test_finalNotInitialized_local_const);
- });
_ut.test('test_finalNotInitialized_local_final', () {
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_finalNotInitialized_local_final);
@@ -14459,6 +14817,10 @@
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_undefinedGetter_fromLibrary);
});
+ _ut.test('test_undefinedIdentifier_for', () {
+ final __test = new StaticWarningCodeTest();
+ runJUnitTest(__test, __test.test_undefinedIdentifier_for);
+ });
_ut.test('test_undefinedIdentifier_function', () {
final __test = new StaticWarningCodeTest();
runJUnitTest(__test, __test.test_undefinedIdentifier_function);
@@ -14520,7 +14882,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
+ assertErrors(source, [ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
verify([source]);
}
void test_continueLabelOnSwitch() {
@@ -14534,7 +14896,7 @@
" }",
"}"]));
resolve(source);
- assertErrors([ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
+ assertErrors(source, [ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
verify([source]);
}
static dartSuite() {
@@ -14680,7 +15042,7 @@
if (_iterableType == null) {
ClassElementImpl iterableElement = ElementFactory.classElement2("Iterable", ["E"]);
_iterableType = iterableElement.type;
- Type2 eType = iterableElement.typeVariables[0].type;
+ Type2 eType = iterableElement.typeParameters[0].type;
iterableElement.accessors = <PropertyAccessorElement> [
ElementFactory.getterElement("iterator", false, iteratorType.substitute4(<Type2> [eType])),
ElementFactory.getterElement("last", false, eType)];
@@ -14692,7 +15054,7 @@
if (_iteratorType == null) {
ClassElementImpl iteratorElement = ElementFactory.classElement2("Iterator", ["E"]);
_iteratorType = iteratorElement.type;
- Type2 eType = iteratorElement.typeVariables[0].type;
+ Type2 eType = iteratorElement.typeParameters[0].type;
iteratorElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("current", false, eType)];
propagateTypeArguments(iteratorElement);
}
@@ -14703,7 +15065,7 @@
ClassElementImpl listElement = ElementFactory.classElement2("List", ["E"]);
listElement.constructors = <ConstructorElement> [ElementFactory.constructorElement(listElement, null)];
_listType = listElement.type;
- Type2 eType = listElement.typeVariables[0].type;
+ Type2 eType = listElement.typeParameters[0].type;
InterfaceType iterableType = this.iterableType.substitute4(<Type2> [eType]);
listElement.interfaces = <InterfaceType> [iterableType];
listElement.accessors = <PropertyAccessorElement> [ElementFactory.getterElement("length", false, intType)];
@@ -14876,7 +15238,7 @@
* @param classElement the element representing the class with type parameters
*/
void propagateTypeArguments(ClassElementImpl classElement) {
- List<Type2> typeArguments = TypeVariableTypeImpl.getTypes(classElement.typeVariables);
+ List<Type2> typeArguments = TypeParameterTypeImpl.getTypes(classElement.typeParameters);
for (PropertyAccessorElement accessor in classElement.accessors) {
FunctionTypeImpl functionType = accessor.type as FunctionTypeImpl;
functionType.typeArguments = typeArguments;
@@ -14900,77 +15262,10 @@
/**
* Create an analysis context that has a fake core library already resolved.
*
- * Added in order to test AnalysisContextImpl2.
- *
- * @return the analysis context that was created
- */
- static AnalysisContextImpl2 context2WithCore() {
- AnalysisContextImpl2 sdkContext = DirectoryBasedDartSdk.defaultSdk2.context as AnalysisContextImpl2;
- SourceFactory sourceFactory = sdkContext.sourceFactory;
- TestTypeProvider provider = new TestTypeProvider();
- CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl("core.dart");
- Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
- sdkContext.setContents(coreSource, "");
- coreUnit.source = coreSource;
- coreUnit.types = <ClassElement> [
- provider.boolType.element,
- provider.doubleType.element,
- provider.functionType.element,
- provider.intType.element,
- provider.listType.element,
- provider.mapType.element,
- provider.nullType.element,
- provider.numType.element,
- provider.objectType.element,
- provider.stackTraceType.element,
- provider.stringType.element,
- provider.typeType.element];
- LibraryElementImpl coreLibrary = new LibraryElementImpl(sdkContext, ASTFactory.libraryIdentifier2(["dart", "core"]));
- coreLibrary.definingCompilationUnit = coreUnit;
- CompilationUnitElementImpl htmlUnit = new CompilationUnitElementImpl("html_dartium.dart");
- Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
- sdkContext.setContents(htmlSource, "");
- htmlUnit.source = htmlSource;
- ClassElementImpl elementElement = ElementFactory.classElement2("Element", []);
- InterfaceType elementType = elementElement.type;
- ClassElementImpl documentElement = ElementFactory.classElement("Document", elementType, []);
- ClassElementImpl htmlDocumentElement = ElementFactory.classElement("HtmlDocument", documentElement.type, []);
- htmlDocumentElement.methods = <MethodElement> [ElementFactory.methodElement("query", elementType, <Type2> [provider.stringType])];
- htmlUnit.types = <ClassElement> [
- ElementFactory.classElement("AnchorElement", elementType, []),
- ElementFactory.classElement("BodyElement", elementType, []),
- ElementFactory.classElement("ButtonElement", elementType, []),
- ElementFactory.classElement("DivElement", elementType, []),
- documentElement,
- elementElement,
- htmlDocumentElement,
- ElementFactory.classElement("InputElement", elementType, []),
- ElementFactory.classElement("SelectElement", elementType, [])];
- htmlUnit.functions = <FunctionElement> [ElementFactory.functionElement3("query", elementElement, <ClassElement> [provider.stringType.element], ClassElementImpl.EMPTY_ARRAY)];
- TopLevelVariableElementImpl document = ElementFactory.topLevelVariableElement3("document", true, htmlDocumentElement.type);
- htmlUnit.topLevelVariables = <TopLevelVariableElement> [document];
- htmlUnit.accessors = <PropertyAccessorElement> [document.getter];
- LibraryElementImpl htmlLibrary = new LibraryElementImpl(sdkContext, ASTFactory.libraryIdentifier2(["dart", "dom", "html"]));
- htmlLibrary.definingCompilationUnit = htmlUnit;
- Map<Source, LibraryElement> elementMap = new Map<Source, LibraryElement>();
- elementMap[coreSource] = coreLibrary;
- elementMap[htmlSource] = htmlLibrary;
- sdkContext.recordLibraryElements(elementMap);
- AnalysisContextImpl2 context = new DelegatingAnalysisContextImpl2();
- sourceFactory = new SourceFactory.con2([
- new DartUriResolver(sdkContext.sourceFactory.dartSdk),
- new FileUriResolver()]);
- context.sourceFactory = sourceFactory;
- return context;
- }
-
- /**
- * Create an analysis context that has a fake core library already resolved.
- *
* @return the analysis context that was created
*/
static AnalysisContextImpl contextWithCore() {
- AnalysisContextImpl sdkContext = DirectoryBasedDartSdk.defaultSdk.context as AnalysisContextImpl;
+ AnalysisContext sdkContext = DirectoryBasedDartSdk.defaultSdk.context;
SourceFactory sourceFactory = sdkContext.sourceFactory;
TestTypeProvider provider = new TestTypeProvider();
CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl("core.dart");
@@ -15020,7 +15315,7 @@
Map<Source, LibraryElement> elementMap = new Map<Source, LibraryElement>();
elementMap[coreSource] = coreLibrary;
elementMap[htmlSource] = htmlLibrary;
- sdkContext.recordLibraryElements(elementMap);
+ ((sdkContext as AnalysisContextImpl)).recordLibraryElements(elementMap);
AnalysisContextImpl context = new DelegatingAnalysisContextImpl();
sourceFactory = new SourceFactory.con2([
new DartUriResolver(sdkContext.sourceFactory.dartSdk),
@@ -15058,9 +15353,14 @@
errorListener.assertErrors2([StaticWarningCode.AMBIGUOUS_IMPORT]);
EngineTestCase.assertInstanceOf(MultiplyDefinedElement, element);
List<Element> conflictingElements = ((element as MultiplyDefinedElement)).conflictingElements;
- JUnitTestCase.assertEquals(typeB1, conflictingElements[0]);
- JUnitTestCase.assertEquals(typeB2, conflictingElements[1]);
- JUnitTestCase.assertEquals(2, conflictingElements.length);
+ EngineTestCase.assertLength(2, conflictingElements);
+ if (identical(conflictingElements[0], typeB1)) {
+ JUnitTestCase.assertSame(typeB2, conflictingElements[1]);
+ } else if (identical(conflictingElements[0], typeB2)) {
+ JUnitTestCase.assertSame(typeB1, conflictingElements[1]);
+ } else {
+ JUnitTestCase.assertSame(typeB1, conflictingElements[0]);
+ }
}
{
GatheringErrorListener errorListener = new GatheringErrorListener();
@@ -15103,6 +15403,40 @@
LibraryImportScope scope = new LibraryImportScope(definingLibrary, errorListener);
JUnitTestCase.assertEquals(errorListener, scope.errorListener);
}
+ void test_nonConflictingImports_fromSdk() {
+ AnalysisContext context = AnalysisContextFactory.contextWithCore();
+ String typeName = "List";
+ ClassElement type = ElementFactory.classElement2(typeName, []);
+ LibraryElement importedLibrary = createTestLibrary2(context, "lib", []);
+ ((importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [type];
+ ImportElementImpl importCore = ElementFactory.importFor(context.getLibraryElement(context.sourceFactory.forUri("dart:core")), null, []);
+ ImportElementImpl importLib = ElementFactory.importFor(importedLibrary, null, []);
+ LibraryElementImpl importingLibrary = createTestLibrary2(context, "importing", []);
+ importingLibrary.imports = <ImportElement> [importCore, importLib];
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryImportScope(importingLibrary, errorListener);
+ JUnitTestCase.assertEquals(type, scope.lookup(ASTFactory.identifier3(typeName), importingLibrary));
+ errorListener.assertNoErrors();
+ }
+ void test_nonConflictingImports_sameElement() {
+ AnalysisContext context = new AnalysisContextImpl();
+ String typeNameA = "A";
+ String typeNameB = "B";
+ ClassElement typeA = ElementFactory.classElement2(typeNameA, []);
+ ClassElement typeB = ElementFactory.classElement2(typeNameB, []);
+ LibraryElement importedLibrary = createTestLibrary2(context, "imported", []);
+ ((importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [typeA, typeB];
+ ImportElementImpl import1 = ElementFactory.importFor(importedLibrary, null, []);
+ ImportElementImpl import2 = ElementFactory.importFor(importedLibrary, null, []);
+ LibraryElementImpl importingLibrary = createTestLibrary2(context, "importing", []);
+ importingLibrary.imports = <ImportElement> [import1, import2];
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryImportScope(importingLibrary, errorListener);
+ JUnitTestCase.assertEquals(typeA, scope.lookup(ASTFactory.identifier3(typeNameA), importingLibrary));
+ errorListener.assertNoErrors();
+ JUnitTestCase.assertEquals(typeB, scope.lookup(ASTFactory.identifier3(typeNameB), importingLibrary));
+ errorListener.assertNoErrors();
+ }
void test_prefixedAndNonPrefixed() {
AnalysisContext context = new AnalysisContextImpl();
String typeName = "C";
@@ -15148,6 +15482,14 @@
final __test = new LibraryImportScopeTest();
runJUnitTest(__test, __test.test_getErrorListener);
});
+ _ut.test('test_nonConflictingImports_fromSdk', () {
+ final __test = new LibraryImportScopeTest();
+ runJUnitTest(__test, __test.test_nonConflictingImports_fromSdk);
+ });
+ _ut.test('test_nonConflictingImports_sameElement', () {
+ final __test = new LibraryImportScopeTest();
+ runJUnitTest(__test, __test.test_nonConflictingImports_sameElement);
+ });
_ut.test('test_prefixedAndNonPrefixed', () {
final __test = new LibraryImportScopeTest();
runJUnitTest(__test, __test.test_prefixedAndNonPrefixed);
@@ -15577,7 +15919,7 @@
setType(p1, dynamicType);
FormalParameter p2 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
setType(p2, dynamicType);
- FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+ FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([]));
analyze3(p1);
analyze3(p2);
Type2 resultType = analyze(node);
@@ -15605,7 +15947,7 @@
setType(p1, dynamicType);
FormalParameter p2 = ASTFactory.simpleFormalParameter3("p2");
setType(p2, dynamicType);
- FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+ FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([]));
analyze3(p1);
analyze3(p2);
Type2 resultType = analyze(node);
@@ -15628,7 +15970,7 @@
setType(p1, dynamicType);
FormalParameter p2 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
setType(p2, dynamicType);
- FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+ FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([]));
analyze3(p2);
Type2 resultType = analyze(node);
Map<String, Type2> expectedNamedTypes = new Map<String, Type2>();
@@ -15656,7 +15998,7 @@
setType(p1, dynamicType);
FormalParameter p2 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
setType(p2, dynamicType);
- FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+ FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([]));
analyze3(p1);
analyze3(p2);
Type2 resultType = analyze(node);
@@ -15682,7 +16024,7 @@
setType(p1, dynamicType);
FormalParameter p2 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p2"), resolvedInteger(0));
setType(p2, dynamicType);
- FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody([]));
+ FunctionExpression node = resolvedFunctionExpression(ASTFactory.formalParameterList([p1, p2]), ASTFactory.blockFunctionBody2([]));
analyze3(p1);
analyze3(p2);
Type2 resultType = analyze(node);
@@ -15754,7 +16096,7 @@
constructor.type = constructorType;
classElement.constructors = <ConstructorElement> [constructor];
InstanceCreationExpression node = ASTFactory.instanceCreationExpression2(null, ASTFactory.typeName(classElement, []), [ASTFactory.identifier3(constructorName)]);
- node.element = constructor;
+ node.staticElement = constructor;
JUnitTestCase.assertSame(classElement.type, analyze(node));
_listener.assertNoErrors();
}
@@ -15769,7 +16111,7 @@
TypeName typeName = ASTFactory.typeName(elementC, [ASTFactory.typeName(elementI, [])]);
typeName.type = elementC.type.substitute4(<Type2> [elementI.type]);
InstanceCreationExpression node = ASTFactory.instanceCreationExpression2(null, typeName, []);
- node.element = constructor;
+ node.staticElement = constructor;
InterfaceType interfaceType = analyze(node) as InterfaceType;
List<Type2> typeArgs = interfaceType.typeArguments;
JUnitTestCase.assertEquals(1, typeArgs.length);
@@ -15784,7 +16126,7 @@
constructor.type = constructorType;
classElement.constructors = <ConstructorElement> [constructor];
InstanceCreationExpression node = ASTFactory.instanceCreationExpression2(null, ASTFactory.typeName(classElement, []), []);
- node.element = constructor;
+ node.staticElement = constructor;
JUnitTestCase.assertSame(classElement.type, analyze(node));
_listener.assertNoErrors();
}
@@ -16474,6 +16816,100 @@
}
}
class NonHintCodeTest extends ResolverTestCase {
+ void test_deadCode_deadBlock_conditionalElse_debugConst() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const bool DEBUG = true;",
+ "f() {",
+ " DEBUG ? 1 : 2;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadBlock_conditionalIf_debugConst() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const bool DEBUG = false;",
+ "f() {",
+ " DEBUG ? 1 : 2;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadBlock_else() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const bool DEBUG = true;",
+ "f() {",
+ " if(DEBUG) {} else {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {",
+ " static const bool DEBUG = false;",
+ "}",
+ "f() {",
+ " if(A.DEBUG) {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib2.dart';",
+ "f() {",
+ " if(A.DEBUG) {}",
+ "}"]));
+ addSource2("/lib2.dart", EngineTestCase.createSource([
+ "library lib2;",
+ "class A {",
+ " static const bool DEBUG = false;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadBlock_if_debugConst_propertyAccessor() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib2.dart' as LIB;",
+ "f() {",
+ " if(LIB.A.DEBUG) {}",
+ "}"]));
+ addSource2("/lib2.dart", EngineTestCase.createSource([
+ "library lib2;",
+ "class A {",
+ " static const bool DEBUG = false;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadBlock_if_debugConst_simpleIdentifier() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const bool DEBUG = false;",
+ "f() {",
+ " if(DEBUG) {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadBlock_while_debugConst() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const bool DEBUG = false;",
+ "f() {",
+ " while(DEBUG) {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
void test_deadCode_deadCatch_onCatchSubtype() {
Source source = addSource(EngineTestCase.createSource([
"class A {}",
@@ -16482,7 +16918,127 @@
" try {} on B catch (e) {} on A catch (e) {} catch (e) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadOperandLHS_and_debugConst() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const bool DEBUG = false;",
+ "f() {",
+ " bool b = DEBUG && false;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_deadCode_deadOperandLHS_or_debugConst() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const bool DEBUG = true;",
+ "f() {",
+ " bool b = DEBUG || true;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_divisionOptimization() {
+ Source source = addSource(EngineTestCase.createSource(["f(int x, int y) {", " var v = x / y.toInt();", "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_divisionOptimization_supressIfDivisionNotDefinedInCore() {
+ Source source = addSource(EngineTestCase.createSource(["f(x, y) {", " var v = (x / y).toInt();", "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_divisionOptimization_supressIfDivisionOverridden() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {",
+ " num operator /(x) {}",
+ "}",
+ "f(A x, A y) {",
+ " var v = (x / y).toInt();",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_duplicateImport_as() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib1.dart';",
+ "import 'lib1.dart' as one;",
+ "A a;",
+ "one.A a2;"]));
+ addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_duplicateImport_hide() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib1.dart';",
+ "import 'lib1.dart' hide A;",
+ "A a;",
+ "B b;"]));
+ addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}", "class B {}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_duplicateImport_show() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib1.dart';",
+ "import 'lib1.dart' show A;",
+ "A a;",
+ "B b;"]));
+ addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {}", "class B {}"]));
+ resolve(source);
+ assertNoErrors(source);
+ 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 {",
+ " bool operator ==(x) {}",
+ " get hashCode => 0;",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_unnecessaryCast_dynamic_type() {
+ Source source = addSource(EngineTestCase.createSource(["m(v) {", " var b = v as Object;", "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_unnecessaryCast_type_dynamic() {
+ Source source = addSource(EngineTestCase.createSource(["m(v) {", " var b = Object as dynamic;", "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_unusedImport_core_library() {
+ Source source = addSource(EngineTestCase.createSource(["library L;", "import 'dart:core';"]));
+ resolve(source);
+ assertNoErrors(source);
verify([source]);
}
void test_unusedImport_export() {
@@ -16490,7 +17046,7 @@
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "export 'lib2.dart';", "class One {}"]));
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class Two {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_unusedImport_export_infiniteLoop() {
@@ -16499,7 +17055,7 @@
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "export 'lib3.dart';", "class Two {}"]));
addSource2("/lib3.dart", EngineTestCase.createSource(["library lib3;", "export 'lib2.dart';", "class Three {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_unusedImport_export2() {
@@ -16508,7 +17064,7 @@
addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "export 'lib3.dart';", "class Two {}"]));
addSource2("/lib3.dart", EngineTestCase.createSource(["library lib3;", "class Three {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_unusedImport_prefix_topLevelFunction() {
@@ -16524,15 +17080,99 @@
"}"]));
addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class One {}", "topLevelFunction() {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
static dartSuite() {
_ut.group('NonHintCodeTest', () {
+ _ut.test('test_deadCode_deadBlock_conditionalElse_debugConst', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadBlock_conditionalElse_debugConst);
+ });
+ _ut.test('test_deadCode_deadBlock_conditionalIf_debugConst', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadBlock_conditionalIf_debugConst);
+ });
+ _ut.test('test_deadCode_deadBlock_else', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadBlock_else);
+ });
+ _ut.test('test_deadCode_deadBlock_if_debugConst_prefixedIdentifier', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadBlock_if_debugConst_prefixedIdentifier);
+ });
+ _ut.test('test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2);
+ });
+ _ut.test('test_deadCode_deadBlock_if_debugConst_propertyAccessor', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadBlock_if_debugConst_propertyAccessor);
+ });
+ _ut.test('test_deadCode_deadBlock_if_debugConst_simpleIdentifier', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadBlock_if_debugConst_simpleIdentifier);
+ });
+ _ut.test('test_deadCode_deadBlock_while_debugConst', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadBlock_while_debugConst);
+ });
_ut.test('test_deadCode_deadCatch_onCatchSubtype', () {
final __test = new NonHintCodeTest();
runJUnitTest(__test, __test.test_deadCode_deadCatch_onCatchSubtype);
});
+ _ut.test('test_deadCode_deadOperandLHS_and_debugConst', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadOperandLHS_and_debugConst);
+ });
+ _ut.test('test_deadCode_deadOperandLHS_or_debugConst', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_deadCode_deadOperandLHS_or_debugConst);
+ });
+ _ut.test('test_divisionOptimization', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_divisionOptimization);
+ });
+ _ut.test('test_divisionOptimization_supressIfDivisionNotDefinedInCore', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_divisionOptimization_supressIfDivisionNotDefinedInCore);
+ });
+ _ut.test('test_divisionOptimization_supressIfDivisionOverridden', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_divisionOptimization_supressIfDivisionOverridden);
+ });
+ _ut.test('test_duplicateImport_as', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_duplicateImport_as);
+ });
+ _ut.test('test_duplicateImport_hide', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_duplicateImport_hide);
+ });
+ _ut.test('test_duplicateImport_show', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_duplicateImport_show);
+ });
+ _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);
+ });
+ _ut.test('test_unnecessaryCast_dynamic_type', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryCast_dynamic_type);
+ });
+ _ut.test('test_unnecessaryCast_type_dynamic', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_unnecessaryCast_type_dynamic);
+ });
+ _ut.test('test_unusedImport_core_library', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_unusedImport_core_library);
+ });
_ut.test('test_unusedImport_export', () {
final __test = new NonHintCodeTest();
runJUnitTest(__test, __test.test_unusedImport_export);
@@ -16556,7 +17196,7 @@
void test_define_duplicate() {
LibraryElement definingLibrary2 = createTestLibrary();
GatheringErrorListener errorListener2 = new GatheringErrorListener();
- Scope rootScope = new Scope_23(definingLibrary2, errorListener2);
+ Scope rootScope = new Scope_20(definingLibrary2, errorListener2);
EnclosedScope scope = new EnclosedScope(rootScope);
VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
VariableElement element2 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
@@ -16567,7 +17207,7 @@
void test_define_normal() {
LibraryElement definingLibrary3 = createTestLibrary();
GatheringErrorListener errorListener3 = new GatheringErrorListener();
- Scope rootScope = new Scope_24(definingLibrary3, errorListener3);
+ Scope rootScope = new Scope_21(definingLibrary3, errorListener3);
EnclosedScope outerScope = new EnclosedScope(rootScope);
EnclosedScope innerScope = new EnclosedScope(outerScope);
VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
@@ -16589,18 +17229,18 @@
});
}
}
-class Scope_23 extends Scope {
+class Scope_20 extends Scope {
LibraryElement definingLibrary2;
GatheringErrorListener errorListener2;
- Scope_23(this.definingLibrary2, this.errorListener2) : super();
+ Scope_20(this.definingLibrary2, this.errorListener2) : super();
LibraryElement get definingLibrary => definingLibrary2;
AnalysisErrorListener get errorListener => errorListener2;
Element lookup3(Identifier identifier, String name, LibraryElement referencingLibrary) => null;
}
-class Scope_24 extends Scope {
+class Scope_21 extends Scope {
LibraryElement definingLibrary3;
GatheringErrorListener errorListener3;
- Scope_24(this.definingLibrary3, this.errorListener3) : super();
+ Scope_21(this.definingLibrary3, this.errorListener3) : super();
LibraryElement get definingLibrary => definingLibrary3;
AnalysisErrorListener get errorListener => errorListener3;
Element lookup3(Identifier identifier, String name, LibraryElement referencingLibrary) => null;
@@ -16893,7 +17533,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_argumentResolution_required_matching() {
@@ -16995,7 +17635,7 @@
" return a(0);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_class_extends_implements() {
@@ -17004,7 +17644,7 @@
"class B {}",
"class C {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_commentReference_class() {
@@ -17017,7 +17657,7 @@
" m() {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_commentReference_parameter() {
@@ -17029,19 +17669,19 @@
" m(e, f()) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_commentReference_singleLine() {
Source source = addSource(EngineTestCase.createSource(["/// [A]", "class A {}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_empty() {
Source source = addSource("");
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_extractedMethodAsConstant() {
@@ -17054,13 +17694,13 @@
" void sort([compare = Comparable.compare]) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_fieldFormalParameter() {
Source source = addSource(EngineTestCase.createSource(["class A {", " int x;", " A(this.x) {}", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_forEachLoops_nonConflicting() {
@@ -17071,7 +17711,7 @@
" for (int x in list) {}",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_forLoops_nonConflicting() {
@@ -17083,7 +17723,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_functionTypeAlias() {
@@ -17096,7 +17736,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_getterAndSetterWithDifferentTypes() {
@@ -17109,7 +17749,7 @@
" a.f = a.f.toString();",
"}"]));
resolve(source);
- assertErrors([StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+ assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
verify([source]);
}
void test_hasReferenceToSuper() {
@@ -17122,7 +17762,7 @@
EngineTestCase.assertLength(2, classes);
JUnitTestCase.assertFalse(classes[0].hasReferenceToSuper());
JUnitTestCase.assertTrue(classes[1].hasReferenceToSuper());
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_import_hide() {
@@ -17137,7 +17777,7 @@
"}",
"A a;"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_import_prefix() {
@@ -17149,7 +17789,7 @@
" _two.f(0);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_import_spaceInUri() {
@@ -17161,7 +17801,7 @@
" foo();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_indexExpression_typeParameters() {
@@ -17175,13 +17815,13 @@
" c[0][0][0];",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_indexExpression_typeParameters_invalidAssignmentWarning() {
Source source = addSource(EngineTestCase.createSource(["f() {", " List<List<int>> b;", " b[0][0] = 'hi';", "}"]));
resolve(source);
- assertErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
void test_indirectOperatorThroughCall() {
@@ -17202,7 +17842,7 @@
" g(f()[0]);",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_invoke_dynamicThroughGetter() {
@@ -17214,7 +17854,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_isValidMixin_badSuperclass() {
@@ -17226,7 +17866,7 @@
List<ClassElement> classes = unit.types;
EngineTestCase.assertLength(2, classes);
JUnitTestCase.assertFalse(classes[0].isValidMixin);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_isValidMixin_constructor() {
@@ -17238,7 +17878,7 @@
List<ClassElement> classes = unit.types;
EngineTestCase.assertLength(1, classes);
JUnitTestCase.assertFalse(classes[0].isValidMixin);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_isValidMixin_super() {
@@ -17255,7 +17895,7 @@
List<ClassElement> classes = unit.types;
EngineTestCase.assertLength(1, classes);
JUnitTestCase.assertFalse(classes[0].isValidMixin);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_isValidMixin_valid() {
@@ -17267,7 +17907,7 @@
List<ClassElement> classes = unit.types;
EngineTestCase.assertLength(1, classes);
JUnitTestCase.assertTrue(classes[0].isValidMixin);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_labels_switch() {
@@ -17284,7 +17924,7 @@
"}"]));
LibraryElement library = resolve(source);
JUnitTestCase.assertNotNull(library);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_metadata_class() {
@@ -17297,7 +17937,7 @@
EngineTestCase.assertLength(1, classes);
List<ElementAnnotation> annotations = classes[0].metadata;
EngineTestCase.assertLength(1, annotations);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_metadata_field() {
@@ -17311,7 +17951,7 @@
FieldElement field = classes[0].fields[0];
List<ElementAnnotation> annotations = field.metadata;
EngineTestCase.assertLength(1, annotations);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_metadata_libraryDirective() {
@@ -17320,7 +17960,7 @@
JUnitTestCase.assertNotNull(library);
List<ElementAnnotation> annotations = library.metadata;
EngineTestCase.assertLength(1, annotations);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_metadata_method() {
@@ -17334,7 +17974,7 @@
MethodElement method = classes[0].methods[0];
List<ElementAnnotation> annotations = method.metadata;
EngineTestCase.assertLength(1, annotations);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_method_fromMixin() {
@@ -17351,7 +17991,7 @@
" foo() => super.foo();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_method_fromSuperclassMixin() {
@@ -17367,7 +18007,7 @@
" c.m1();",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_methodCascades() {
@@ -17382,7 +18022,7 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_methodCascades_withSetter() {
@@ -17399,13 +18039,13 @@
" }",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_resolveAgainstNull() {
Source source = addSource(EngineTestCase.createSource(["f(var p) {", " return null == p;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_setter_inherited() {
@@ -17419,13 +18059,13 @@
" int f() => x = 1;",
"}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
void test_setter_static() {
Source source = addSource(EngineTestCase.createSource(["set s(x) {", "}", "", "main() {", " s = 123;", "}"]));
resolve(source);
- assertNoErrors();
+ assertNoErrors(source);
verify([source]);
}
diff --git a/pkg/analyzer_experimental/test/generated/scanner_test.dart b/pkg/analyzer_experimental/test/generated/scanner_test.dart
index 6317f92..aa74c46 100644
--- a/pkg/analyzer_experimental/test/generated/scanner_test.dart
+++ b/pkg/analyzer_experimental/test/generated/scanner_test.dart
@@ -245,58 +245,26 @@
final __test = new CharBufferScannerTest();
runJUnitTest(__test, __test.test_double_fraction);
});
- _ut.test('test_double_fraction_D', () {
- final __test = new CharBufferScannerTest();
- runJUnitTest(__test, __test.test_double_fraction_D);
- });
_ut.test('test_double_fraction_E', () {
final __test = new CharBufferScannerTest();
runJUnitTest(__test, __test.test_double_fraction_E);
});
- _ut.test('test_double_fraction_Ed', () {
- final __test = new CharBufferScannerTest();
- runJUnitTest(__test, __test.test_double_fraction_Ed);
- });
- _ut.test('test_double_fraction_d', () {
- final __test = new CharBufferScannerTest();
- runJUnitTest(__test, __test.test_double_fraction_d);
- });
_ut.test('test_double_fraction_e', () {
final __test = new CharBufferScannerTest();
runJUnitTest(__test, __test.test_double_fraction_e);
});
- _ut.test('test_double_fraction_ed', () {
- final __test = new CharBufferScannerTest();
- runJUnitTest(__test, __test.test_double_fraction_ed);
- });
_ut.test('test_double_missingDigitInExponent', () {
final __test = new CharBufferScannerTest();
runJUnitTest(__test, __test.test_double_missingDigitInExponent);
});
- _ut.test('test_double_whole_D', () {
- final __test = new CharBufferScannerTest();
- runJUnitTest(__test, __test.test_double_whole_D);
- });
_ut.test('test_double_whole_E', () {
final __test = new CharBufferScannerTest();
runJUnitTest(__test, __test.test_double_whole_E);
});
- _ut.test('test_double_whole_Ed', () {
- final __test = new CharBufferScannerTest();
- runJUnitTest(__test, __test.test_double_whole_Ed);
- });
- _ut.test('test_double_whole_d', () {
- final __test = new CharBufferScannerTest();
- runJUnitTest(__test, __test.test_double_whole_d);
- });
_ut.test('test_double_whole_e', () {
final __test = new CharBufferScannerTest();
runJUnitTest(__test, __test.test_double_whole_e);
});
- _ut.test('test_double_whole_ed', () {
- final __test = new CharBufferScannerTest();
- runJUnitTest(__test, __test.test_double_whole_ed);
- });
_ut.test('test_eq', () {
final __test = new CharBufferScannerTest();
runJUnitTest(__test, __test.test_eq);
@@ -932,58 +900,26 @@
final __test = new StringScannerTest();
runJUnitTest(__test, __test.test_double_fraction);
});
- _ut.test('test_double_fraction_D', () {
- final __test = new StringScannerTest();
- runJUnitTest(__test, __test.test_double_fraction_D);
- });
_ut.test('test_double_fraction_E', () {
final __test = new StringScannerTest();
runJUnitTest(__test, __test.test_double_fraction_E);
});
- _ut.test('test_double_fraction_Ed', () {
- final __test = new StringScannerTest();
- runJUnitTest(__test, __test.test_double_fraction_Ed);
- });
- _ut.test('test_double_fraction_d', () {
- final __test = new StringScannerTest();
- runJUnitTest(__test, __test.test_double_fraction_d);
- });
_ut.test('test_double_fraction_e', () {
final __test = new StringScannerTest();
runJUnitTest(__test, __test.test_double_fraction_e);
});
- _ut.test('test_double_fraction_ed', () {
- final __test = new StringScannerTest();
- runJUnitTest(__test, __test.test_double_fraction_ed);
- });
_ut.test('test_double_missingDigitInExponent', () {
final __test = new StringScannerTest();
runJUnitTest(__test, __test.test_double_missingDigitInExponent);
});
- _ut.test('test_double_whole_D', () {
- final __test = new StringScannerTest();
- runJUnitTest(__test, __test.test_double_whole_D);
- });
_ut.test('test_double_whole_E', () {
final __test = new StringScannerTest();
runJUnitTest(__test, __test.test_double_whole_E);
});
- _ut.test('test_double_whole_Ed', () {
- final __test = new StringScannerTest();
- runJUnitTest(__test, __test.test_double_whole_Ed);
- });
- _ut.test('test_double_whole_d', () {
- final __test = new StringScannerTest();
- runJUnitTest(__test, __test.test_double_whole_d);
- });
_ut.test('test_double_whole_e', () {
final __test = new StringScannerTest();
runJUnitTest(__test, __test.test_double_whole_e);
});
- _ut.test('test_double_whole_ed', () {
- final __test = new StringScannerTest();
- runJUnitTest(__test, __test.test_double_whole_ed);
- });
_ut.test('test_eq', () {
final __test = new StringScannerTest();
runJUnitTest(__test, __test.test_eq);
@@ -1641,45 +1577,21 @@
void test_double_fraction() {
assertToken(TokenType.DOUBLE, ".123");
}
- void test_double_fraction_d() {
- assertToken(TokenType.DOUBLE, ".123d");
- }
- void test_double_fraction_D() {
- assertToken(TokenType.DOUBLE, ".123D");
- }
void test_double_fraction_e() {
assertToken(TokenType.DOUBLE, ".123e4");
}
void test_double_fraction_E() {
assertToken(TokenType.DOUBLE, ".123E4");
}
- void test_double_fraction_ed() {
- assertToken(TokenType.DOUBLE, ".123e4d");
- }
- void test_double_fraction_Ed() {
- assertToken(TokenType.DOUBLE, ".123E4d");
- }
void test_double_missingDigitInExponent() {
assertError(ScannerErrorCode.MISSING_DIGIT, 1, "1e");
}
- void test_double_whole_d() {
- assertToken(TokenType.DOUBLE, "12d");
- }
- void test_double_whole_D() {
- assertToken(TokenType.DOUBLE, "12D");
- }
void test_double_whole_e() {
assertToken(TokenType.DOUBLE, "12e4");
}
void test_double_whole_E() {
assertToken(TokenType.DOUBLE, "12E4");
}
- void test_double_whole_ed() {
- assertToken(TokenType.DOUBLE, "12e4d");
- }
- void test_double_whole_Ed() {
- assertToken(TokenType.DOUBLE, "12E4d");
- }
void test_eq() {
assertToken(TokenType.EQ, "=");
}
@@ -2243,6 +2155,19 @@
JUnitTestCase.assertEquals(source.length, tokenWithSpaces.length);
JUnitTestCase.assertEquals(source, tokenWithSpaces.lexeme);
return originalToken;
+ } else if (identical(expectedType, TokenType.INT) || identical(expectedType, TokenType.DOUBLE)) {
+ Token tokenWithLowerD = scan2("${source}d");
+ JUnitTestCase.assertNotNull(tokenWithLowerD);
+ JUnitTestCase.assertEquals(expectedType, tokenWithLowerD.type);
+ JUnitTestCase.assertEquals(0, tokenWithLowerD.offset);
+ JUnitTestCase.assertEquals(source.length, tokenWithLowerD.length);
+ JUnitTestCase.assertEquals(source, tokenWithLowerD.lexeme);
+ Token tokenWithUpperD = scan2("${source}D");
+ JUnitTestCase.assertNotNull(tokenWithUpperD);
+ JUnitTestCase.assertEquals(expectedType, tokenWithUpperD.type);
+ JUnitTestCase.assertEquals(0, tokenWithUpperD.offset);
+ JUnitTestCase.assertEquals(source.length, tokenWithUpperD.length);
+ JUnitTestCase.assertEquals(source, tokenWithUpperD.lexeme);
}
Token tokenWithSpaces = scan2(" ${source} ");
JUnitTestCase.assertNotNull(tokenWithSpaces);
diff --git a/pkg/analyzer_experimental/test/generated/test_support.dart b/pkg/analyzer_experimental/test/generated/test_support.dart
index 0152e1a..d0977be 100644
--- a/pkg/analyzer_experimental/test/generated/test_support.dart
+++ b/pkg/analyzer_experimental/test/generated/test_support.dart
@@ -613,6 +613,22 @@
}
/**
+ * Assert that the given collection is non-`null` and has the expected number of elements.
+ *
+ * @param expectedSize the expected number of elements
+ * @param c the collection being tested
+ * @throws AssertionFailedError if the list is `null` or does not have the expected number
+ * of elements
+ */
+ static void assertCollectionSize(int expectedSize, Iterable c) {
+ if (c == null) {
+ JUnitTestCase.fail("Expected collection of size ${expectedSize}; found null");
+ } else if (c.length != expectedSize) {
+ JUnitTestCase.fail("Expected collection of size ${expectedSize}; contained ${c.length} elements");
+ }
+ }
+
+ /**
* Assert that the given list is non-`null` and has the expected number of elements.
*
* @param expectedSize the expected number of elements
diff --git a/pkg/analyzer_experimental/test/services/formatter_test.dart b/pkg/analyzer_experimental/test/services/formatter_test.dart
index 5503234..51187f3 100644
--- a/pkg/analyzer_experimental/test/services/formatter_test.dart
+++ b/pkg/analyzer_experimental/test/services/formatter_test.dart
@@ -772,6 +772,14 @@
expect(formattedSource, startsWith(' '));
});
+ test('selections', () {
+ expectSelectedPostFormat('class X {}', '}');
+ expectSelectedPostFormat('class X{}', '{');
+ expectSelectedPostFormat('class X{int y;}', ';');
+ expectSelectedPostFormat('class X{int y;}', '}');
+ expectSelectedPostFormat('class X {}', ' {');
+ });
+
});
@@ -955,14 +963,23 @@
return tokens[0];
}
-String formatCU(src, {options: const FormatterOptions()}) =>
- new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src).source;
+FormattedSource formatCU(src, {options: const FormatterOptions(), selection}) =>
+ new CodeFormatter(options).format(
+ CodeKind.COMPILATION_UNIT, src, selection: selection);
String formatStatement(src, {options: const FormatterOptions()}) =>
new CodeFormatter(options).format(CodeKind.STATEMENT, src).source;
Token tokenize(String str) => new StringScanner(null, str, null).tokenize();
+expectSelectedPostFormat(src, token) {
+ var preOffset = src.indexOf(token);
+ var length = token.length;
+ var formatted = formatCU(src, selection: new Selection(preOffset, length));
+ var postOffset = formatted.selection.offset;
+ expect(formatted.source.substring(postOffset, postOffset + length),
+ equals(src.substring(preOffset, preOffset + length)));
+}
expectTokenizedEqual(String s1, String s2) =>
expectStreamsEqual(tokenize(s1), tokenize(s2));
@@ -978,7 +995,8 @@
expect(() => new TokenStreamComparator(null, t1, t2).verifyEquals(),
throwsA(new isInstanceOf<FormatterException>()));
-expectCUFormatsTo(src, expected) => expect(formatCU(src), equals(expected));
+expectCUFormatsTo(src, expected) =>
+ expect(formatCU(src).source, equals(expected));
-expectStmtFormatsTo(src, expected) => expect(formatStatement(src),
- equals(expected));
+expectStmtFormatsTo(src, expected) =>
+ expect(formatStatement(src), equals(expected));
diff --git a/pkg/analyzer_experimental/test/services/test_utils.dart b/pkg/analyzer_experimental/test/services/test_utils.dart
index 62b77159..3c7765e 100644
--- a/pkg/analyzer_experimental/test/services/test_utils.dart
+++ b/pkg/analyzer_experimental/test/services/test_utils.dart
@@ -55,7 +55,7 @@
var builder = new StringBuffer();
var expectedCounts = new Map<ErrorCode, int>();
- for (code in expectedErrorCodes) {
+ for (var code in expectedErrorCodes) {
var count = expectedCounts[code];
if (count == null) {
count = 1;
@@ -66,7 +66,7 @@
}
var errorsByCode = new Map<ErrorCode, List<AnalysisError>>();
- for (error in _errors) {
+ for (var error in _errors) {
var code = error.errorCode;
var list = errorsByCode[code];
if (list == null) {
@@ -76,7 +76,7 @@
list.add(error);
}
- for (entry in _getMapEntrySet(expectedCounts)) {
+ for (var entry in _getMapEntrySet(expectedCounts)) {
var code = entry.getKey();
var expectedCount = entry.getValue();
var actualCount;
@@ -102,7 +102,7 @@
}
}
- for (entry in _getMapEntrySet(errorsByCode)) {
+ for (var entry in _getMapEntrySet(errorsByCode)) {
var code = entry.getKey();
var actualErrors = entry.getValue();
var actualCount = actualErrors.length;
diff --git a/pkg/args/lib/args.dart b/pkg/args/lib/args.dart
index 0b877cd..a4db204 100644
--- a/pkg/args/lib/args.dart
+++ b/pkg/args/lib/args.dart
@@ -334,15 +334,16 @@
*/
void addOption(String name, {String abbr, String help, List<String> allowed,
Map<String, String> allowedHelp, String defaultsTo,
- void callback(value), bool allowMultiple: false}) {
+ void callback(value), bool allowMultiple: false, bool hide: false}) {
_addOption(name, abbr, help, allowed, allowedHelp, defaultsTo,
- callback, isFlag: false, allowMultiple: allowMultiple);
+ callback, isFlag: false, allowMultiple: allowMultiple,
+ hide: hide);
}
void _addOption(String name, String abbr, String help, List<String> allowed,
Map<String, String> allowedHelp, defaultsTo,
void callback(value), {bool isFlag, bool negatable: false,
- bool allowMultiple: false}) {
+ bool allowMultiple: false, bool hide: false}) {
// Make sure the name isn't in use.
if (_options.containsKey(name)) {
throw new ArgumentError('Duplicate option "$name".');
@@ -359,7 +360,7 @@
_options[name] = new Option(name, abbr, help, allowed, allowedHelp,
defaultsTo, callback, isFlag: isFlag, negatable: negatable,
- allowMultiple: allowMultiple);
+ allowMultiple: allowMultiple, hide: hide);
}
/**
diff --git a/pkg/args/lib/src/options.dart b/pkg/args/lib/src/options.dart
index 5f1f484..f47bd61 100644
--- a/pkg/args/lib/src/options.dart
+++ b/pkg/args/lib/src/options.dart
@@ -16,10 +16,12 @@
final bool isFlag;
final bool negatable;
final bool allowMultiple;
+ final bool hide;
Option(this.name, this.abbreviation, this.help, List<String> allowed,
Map<String, String> allowedHelp, this.defaultValue, this.callback,
- {this.isFlag, this.negatable, this.allowMultiple: false}) :
+ {this.isFlag, this.negatable, this.allowMultiple: false,
+ this.hide: false}) :
this.allowed = allowed == null ?
null : new UnmodifiableListView(allowed),
this.allowedHelp = allowedHelp == null ?
diff --git a/pkg/args/lib/src/usage.dart b/pkg/args/lib/src/usage.dart
index c3dd68e..3244c4e 100644
--- a/pkg/args/lib/src/usage.dart
+++ b/pkg/args/lib/src/usage.dart
@@ -67,6 +67,8 @@
calculateColumnWidths();
args.options.forEach((name, option) {
+ if (option.hide) return;
+
write(0, getAbbreviation(option));
write(1, getLongOption(option));
diff --git a/pkg/args/test/usage_test.dart b/pkg/args/test/usage_test.dart
index 6068f32..27b0389 100644
--- a/pkg/args/test/usage_test.dart
+++ b/pkg/args/test/usage_test.dart
@@ -167,6 +167,20 @@
[spades] Swords of a soldier
''');
});
+
+ test("hidden flags don't appear in the help", () {
+ var parser = new ArgParser();
+ parser.addOption('first', help: 'The first option');
+ parser.addOption('second', hide: true);
+ parser.addOption('third', help: 'The third option');
+
+
+ validateUsage(parser,
+ '''
+ --first The first option
+ --third The third option
+ ''');
+ });
});
}
diff --git a/pkg/barback/lib/src/asset_cascade.dart b/pkg/barback/lib/src/asset_cascade.dart
index 078c510..eb65679 100644
--- a/pkg/barback/lib/src/asset_cascade.dart
+++ b/pkg/barback/lib/src/asset_cascade.dart
@@ -16,6 +16,7 @@
import 'errors.dart';
import 'package_graph.dart';
import 'phase.dart';
+import 'stream_pool.dart';
import 'transformer.dart';
import 'utils.dart';
@@ -69,6 +70,20 @@
Stream<BarbackException> get errors => _errorsController.stream;
final _errorsController = new StreamController<BarbackException>.broadcast();
+ /// A stream that emits an event whenever this cascade becomes dirty.
+ ///
+ /// After this stream emits an event, [results] will emit an event once the
+ /// cascade is no longer dirty.
+ ///
+ /// This may emit events when the cascade was already dirty. Events are
+ /// emitted synchronously to ensure that the dirty state is thoroughly
+ /// propagated as soon as any assets are changed.
+ Stream get onDirty => _onDirtyPool.stream;
+ final _onDirtyPool = new StreamPool.broadcast();
+
+ /// A controller whose stream feeds into [_onDirtyPool].
+ final _onDirtyController = new StreamController.broadcast(sync: true);
+
/// The errors that have occurred since the current build started.
///
/// This will be empty if no build is occurring.
@@ -90,6 +105,7 @@
///
/// It loads source assets within [package] using [provider].
AssetCascade(this.graph, this.package) {
+ _onDirtyPool.add(_onDirtyController.stream);
_addPhase(new Phase(this, []));
}
@@ -201,6 +217,7 @@
/// Add [phase] to the end of [_phases] and watch its [onDirty] stream.
void _addPhase(Phase phase) {
+ _onDirtyPool.add(phase.onDirty);
phase.onDirty.listen((_) {
_newChanges = true;
_waitForProcess();
diff --git a/pkg/barback/lib/src/package_graph.dart b/pkg/barback/lib/src/package_graph.dart
index 5afe5f4..2cd5b46 100644
--- a/pkg/barback/lib/src/package_graph.dart
+++ b/pkg/barback/lib/src/package_graph.dart
@@ -69,6 +69,9 @@
// doesn't start building until some source in that graph is updated.
_cascadeResults[package] = new BuildResult.success();
_cascades[package] = cascade;
+ cascade.onDirty.listen((_) {
+ _cascadeResults[package] = null;
+ });
cascade.results.listen((result) {
_cascadeResults[cascade.package] = result;
@@ -144,7 +147,6 @@
groupBy(sources, (id) => id.package).forEach((package, ids) {
var cascade = _cascades[package];
if (cascade == null) throw new ArgumentError("Unknown package $package.");
- _cascadeResults[package] = null;
cascade.updateSources(ids);
});
}
@@ -154,14 +156,12 @@
groupBy(sources, (id) => id.package).forEach((package, ids) {
var cascade = _cascades[package];
if (cascade == null) throw new ArgumentError("Unknown package $package.");
- _cascadeResults[package] = null;
cascade.removeSources(ids);
});
}
void updateTransformers(String package,
Iterable<Iterable<Transformer>> transformers) {
- _cascadeResults[package] = null;
_cascades[package].updateTransformers(transformers);
}
}
diff --git a/pkg/barback/test/package_graph/transform_test.dart b/pkg/barback/test/package_graph/transform_test.dart
index af8df48..14aff9f 100644
--- a/pkg/barback/test/package_graph/transform_test.dart
+++ b/pkg/barback/test/package_graph/transform_test.dart
@@ -1002,6 +1002,29 @@
buildShouldSucceed();
});
+ test("doesn't complete the build until all packages' transforms are "
+ "finished running", () {
+ var transformer = new ManyToOneTransformer("txt");
+ initGraph({
+ "pkg1|a.txt": "pkg2|a.inc",
+ "pkg2|a.inc": "a"
+ }, {
+ "pkg1": [[transformer]]
+ });
+
+ updateSources(["pkg1|a.txt", "pkg2|a.inc"]);
+ expectAsset("pkg1|a.out", "a");
+ buildShouldSucceed();
+
+ transformer.pauseApply();
+ modifyAsset("pkg2|a.inc", "new a");
+ updateSources(["pkg2|a.inc"]);
+ buildShouldNotBeDone();
+
+ transformer.resumeApply();
+ buildShouldSucceed();
+ });
+
test("runs a transform that's added because of a change in another package",
() {
initGraph({
diff --git a/pkg/custom_element/lib/custom-elements.debug.js b/pkg/custom_element/lib/custom-elements.debug.js
index befb1a9..843e8a7 100644
--- a/pkg/custom_element/lib/custom-elements.debug.js
+++ b/pkg/custom_element/lib/custom-elements.debug.js
@@ -25,102 +25,6 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-(function() {
-
-var scope = window.PolymerLoader = {};
-var flags = {};
-
-// convert url arguments to flags
-
-if (!flags.noOpts) {
- location.search.slice(1).split('&').forEach(function(o) {
- o = o.split('=');
- o[0] && (flags[o[0]] = o[1] || true);
- });
-}
-
-// process global logFlags
-
-parseLogFlags(flags);
-
-function load(scopeName) {
- // imports
-
- var scope = window[scopeName];
- var entryPointName = scope.entryPointName;
- var processFlags = scope.processFlags;
-
- // acquire attributes and base path from entry point
-
- var entryPoint = findScript(entryPointName);
- var base = entryPoint.basePath;
-
- // acquire common flags
- var flags = scope.flags;
-
- // convert attributes to flags
- var flags = PolymerLoader.flags;
- for (var i=0, a; (a=entryPoint.attributes[i]); i++) {
- if (a.name !== 'src') {
- flags[a.name] = a.value || true;
- }
- }
-
- // parse log flags into global
- parseLogFlags(flags);
-
- // exports
-
- scope.basePath = base;
- scope.flags = flags;
-
- // process flags for dynamic dependencies
-
- if (processFlags) {
- processFlags.call(scope, flags);
- }
-
- // post-process imports
-
- var modules = scope.modules || [];
- var sheets = scope.sheets || [];
-
- // write script tags for dependencies
-
- modules.forEach(function(src) {
- document.write('<script src="' + base + src + '"></script>');
- });
-
- // write link tags for styles
-
- sheets.forEach(function(src) {
- document.write('<link rel="stylesheet" href="' + base + src + '">');
- });
-}
-
-// utility method
-
-function findScript(fileName) {
- var script = document.querySelector('script[src*="' + fileName + '"]');
- var src = script.attributes.src.value;
- script.basePath = src.slice(0, src.indexOf(fileName));
- return script;
-}
-
-function parseLogFlags(flags) {
- var logFlags = window.logFlags = window.logFlags || {};
- if (flags.log) {
- flags.log.split(',').forEach(function(f) {
- logFlags[f] = true;
- });
- }
-}
-
-scope.flags = flags;
-scope.load = load;
-
-})();
-
window.CustomElements = {flags:{}};
// SideTable is a weak map where possible. If WeakMap is not available the
// association is stored as an expando property.
@@ -729,7 +633,7 @@
// walk all shadowRoots on a given node.
function forRoots(node, cb) {
- var root = node.webkitShadowRoot;
+ var root = node.shadowRoot;
while(root) {
forSubtree(root, cb);
root = root.olderShadowRoot;
@@ -796,9 +700,50 @@
}
}
-// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this
+
+// TODO(sorvell): on platforms without MutationObserver, mutations may not be
+// reliable and therefore entered/leftView are not reliable.
+// To make these callbacks less likely to fail, we defer all inserts and removes
+// to give a chance for elements to be inserted into dom.
+// This ensures enteredViewCallback fires for elements that are created and
+// immediately added to dom.
+var hasPolyfillMutations = (!window.MutationObserver ||
+ (window.MutationObserver === window.JsMutationObserver));
+scope.hasPolyfillMutations = hasPolyfillMutations;
+
+var isPendingMutations = false;
+var pendingMutations = [];
+function deferMutation(fn) {
+ pendingMutations.push(fn);
+ if (!isPendingMutations) {
+ isPendingMutations = true;
+ var async = (window.Platform && window.Platform.endOfMicrotask) ||
+ setTimeout;
+ async(takeMutations);
+ }
+}
+
+function takeMutations() {
+ isPendingMutations = false;
+ var $p = pendingMutations;
+ for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
+ p();
+ }
+ pendingMutations = [];
+}
function inserted(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _inserted(element);
+ });
+ } else {
+ _inserted(element);
+ }
+}
+
+// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this
+function _inserted(element) {
// TODO(sjmiles): it's possible we were inserted and removed in the space
// of one microtask, in which case we won't be 'inDocument' here
// But there are other cases where we are testing for inserted without
@@ -837,6 +782,17 @@
});
}
+
+function removed(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _removed(element);
+ });
+ } else {
+ _removed(element);
+ }
+}
+
function removed(element) {
// TODO(sjmiles): temporary: do work on all custom elements so we can track
// behavior even when callbacks not defined
@@ -872,10 +828,10 @@
}
function watchShadow(node) {
- if (node.webkitShadowRoot && !node.webkitShadowRoot.__watched) {
+ if (node.shadowRoot && !node.shadowRoot.__watched) {
logFlags.dom && console.log('watching shadow-root for: ', node.localName);
// watch all unwatched roots...
- var root = node.webkitShadowRoot;
+ var root = node.shadowRoot;
while (root) {
watchRoot(root);
root = root.olderShadowRoot;
@@ -947,6 +903,7 @@
function takeRecords() {
// TODO(sjmiles): ask Raf why we have to call handler ourselves
handler(observer.takeRecords());
+ takeMutations();
}
var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
@@ -1460,8 +1417,23 @@
if (document.readyState === 'complete') {
bootstrap();
} else {
- var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : 'DOMContentLoaded';
+ var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' :
+ document.readyState == 'loading' ? 'DOMContentLoaded' : 'load';
window.addEventListener(loadEvent, bootstrap);
}
})();
+
+(function() {
+// Patch to allow custom element and shadow dom to work together, from:
+// https://github.com/Polymer/platform/blob/master/src/patches-shadowdom-polyfill.js
+// include .host reference
+if (HTMLElement.prototype.createShadowRoot) {
+ var originalCreateShadowRoot = HTMLElement.prototype.createShadowRoot;
+ HTMLElement.prototype.createShadowRoot = function() {
+ var root = originalCreateShadowRoot.call(this);
+ root.host = this;
+ return root;
+ }
+}
+})();
diff --git a/pkg/custom_element/lib/custom-elements.min.js b/pkg/custom_element/lib/custom-elements.min.js
index 3207b81..fdec66a 100644
--- a/pkg/custom_element/lib/custom-elements.min.js
+++ b/pkg/custom_element/lib/custom-elements.min.js
@@ -25,4 +25,4 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-window.CustomElements={flags:{}};var SideTable;if("undefined"!=typeof WeakMap&&navigator.userAgent.indexOf("Firefox/")<0?SideTable=WeakMap:function(){var a=Object.defineProperty,b=Date.now()%1e9;SideTable=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")},SideTable.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]:void 0},"delete":function(a){this.set(a,void 0)}}}(),function(a){function b(a){u.push(a),t||(t=!0,q(d))}function c(a){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(a)||a}function d(){t=!1;var a=u;u=[],a.sort(function(a,b){return a.uid_-b.uid_});var b=!1;a.forEach(function(a){var c=a.takeRecords();e(a),c.length&&(a.callback_(c,a),b=!0)}),b&&d()}function e(a){a.nodes_.forEach(function(b){var c=p.get(b);c&&c.forEach(function(b){b.observer===a&&b.removeTransientObservers()})})}function f(a,b){for(var c=a;c;c=c.parentNode){var d=p.get(c);if(d)for(var e=0;e<d.length;e++){var f=d[e],g=f.options;if(c===a||g.subtree){var h=b(g);h&&f.enqueue(h)}}}}function g(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++v}function h(a,b){this.type=a,this.target=b,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function i(a){var b=new h(a.type,a.target);return b.addedNodes=a.addedNodes.slice(),b.removedNodes=a.removedNodes.slice(),b.previousSibling=a.previousSibling,b.nextSibling=a.nextSibling,b.attributeName=a.attributeName,b.attributeNamespace=a.attributeNamespace,b.oldValue=a.oldValue,b}function j(a,b){return w=new h(a,b)}function k(a){return x?x:(x=i(w),x.oldValue=a,x)}function l(){w=x=void 0}function m(a){return a===x||a===w}function n(a,b){return a===b?a:x&&m(a)?x:null}function o(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var p=new SideTable,q=window.msSetImmediate;if(!q){var r=[],s=String(Math.random());window.addEventListener("message",function(a){if(a.data===s){var b=r;r=[],b.forEach(function(a){a()})}}),q=function(a){r.push(a),window.postMessage(s,"*")}}var t=!1,u=[],v=0;g.prototype={observe:function(a,b){if(a=c(a),!b.childList&&!b.attributes&&!b.characterData||b.attributeOldValue&&!b.attributes||b.attributeFilter&&b.attributeFilter.length&&!b.attributes||b.characterDataOldValue&&!b.characterData)throw new SyntaxError;var d=p.get(a);d||p.set(a,d=[]);for(var e,f=0;f<d.length;f++)if(d[f].observer===this){e=d[f],e.removeListeners(),e.options=b;break}e||(e=new o(this,a,b),d.push(e),this.nodes_.push(a)),e.addListeners()},disconnect:function(){this.nodes_.forEach(function(a){for(var b=p.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){d.removeListeners(),b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}};var w,x;o.prototype={enqueue:function(a){var c=this.observer.records_,d=c.length;if(c.length>0){var e=c[d-1],f=n(e,a);if(f)return c[d-1]=f,void 0}else b(this.observer);c[d]=a},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(a){var b=this.options;b.attributes&&a.addEventListener("DOMAttrModified",this,!0),b.characterData&&a.addEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.addEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(a){var b=this.options;b.attributes&&a.removeEventListener("DOMAttrModified",this,!0),b.characterData&&a.removeEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.removeEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(a){if(a!==this.target){this.addListeners_(a),this.transientObservedNodes.push(a);var b=p.get(a);b||p.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[],a.forEach(function(a){this.removeListeners_(a);for(var b=p.get(a),c=0;c<b.length;c++)if(b[c]===this){b.splice(c,1);break}},this)},handleEvent:function(a){switch(a.stopImmediatePropagation(),a.type){case"DOMAttrModified":var b=a.attrName,c=a.relatedNode.namespaceURI,d=a.target,e=new j("attributes",d);e.attributeName=b,e.attributeNamespace=c;var g=a.attrChange===MutationEvent.ADDITION?null:a.prevValue;f(d,function(a){return!a.attributes||a.attributeFilter&&a.attributeFilter.length&&-1===a.attributeFilter.indexOf(b)&&-1===a.attributeFilter.indexOf(c)?void 0:a.attributeOldValue?k(g):e});break;case"DOMCharacterDataModified":var d=a.target,e=j("characterData",d),g=a.prevValue;f(d,function(a){return a.characterData?a.characterDataOldValue?k(g):e:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(a.target);case"DOMNodeInserted":var h,i,d=a.relatedNode,m=a.target;"DOMNodeInserted"===a.type?(h=[m],i=[]):(h=[],i=[m]);var n=m.previousSibling,o=m.nextSibling,e=j("childList",d);e.addedNodes=h,e.removedNodes=i,e.previousSibling=n,e.nextSibling=o,f(d,function(a){return a.childList?e:void 0})}l()}},a.JsMutationObserver=g}(this),!window.MutationObserver&&(window.MutationObserver=window.WebKitMutationObserver||window.JsMutationObserver,!MutationObserver))throw new Error("no mutation observer support");!function(a){function b(a,c,d){var e=a.firstElementChild;if(!e)for(e=a.firstChild;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;for(;e;)c(e,d)!==!0&&b(e,c,d),e=e.nextElementSibling;return null}function c(a,b){for(var c=a.webkitShadowRoot;c;)d(c,b),c=c.olderShadowRoot}function d(a,d){b(a,function(a){return d(a)?!0:(c(a,d),void 0)}),c(a,d)}function e(a){return h(a)?(i(a),!0):(j(a),void 0)}function f(a){d(a,function(a){return e(a)?!0:void 0})}function g(a){return e(a)||f(a)}function h(b){if(!b.__upgraded__&&b.nodeType===Node.ELEMENT_NODE){var c=b.getAttribute("is")||b.localName,d=a.registry[c];if(d)return v.dom&&console.group("upgrade:",b.localName),a.upgrade(b),v.dom&&console.groupEnd(),!0}}function i(a){j(a),m(a)&&d(a,function(a){j(a)})}function j(a){(a.enteredViewCallback||a.__upgraded__&&v.dom)&&(v.dom&&console.group("inserted:",a.localName),m(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?v.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.enteredViewCallback&&(v.dom&&console.log("inserted:",a.localName),a.enteredViewCallback())),v.dom&&console.groupEnd())}function k(a){l(a),d(a,function(a){l(a)})}function l(a){(a.leftViewCallback||a.__upgraded__&&v.dom)&&(v.dom&&console.log("removed:",a.localName),m(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?v.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.leftViewCallback&&a.leftViewCallback()))}function m(a){for(var b=a,c=window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(document)||document;b;){if(b==c)return!0;b=b.parentNode||b.host}}function n(a){if(a.webkitShadowRoot&&!a.webkitShadowRoot.__watched){v.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.webkitShadowRoot;b;)o(b),b=b.olderShadowRoot}}function o(a){a.__watched||(s(a),a.__watched=!0)}function p(a){switch(a.localName){case"style":case"script":case"template":case void 0:return!0}}function q(a){if(v.dom){var b=a[0];if(b&&"childList"===b.type&&b.addedNodes&&b.addedNodes){for(var c=b.addedNodes[0];c&&c!==document&&!c.host;)c=c.parentNode;var d=c&&(c.URL||c._URL||c.host&&c.host.localName)||"";d=d.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",a.length,d||"")}a.forEach(function(a){"childList"===a.type&&(x(a.addedNodes,function(a){p(a)||g(a)}),x(a.removedNodes,function(a){p(a)||k(a)}))}),v.dom&&console.groupEnd()}function r(){q(w.takeRecords())}function s(a){w.observe(a,{childList:!0,subtree:!0})}function t(a){s(a)}function u(a){v.dom&&console.group("upgradeDocument: ",(a.URL||a._URL||"").split("/").pop()),g(a),v.dom&&console.groupEnd()}var v=window.logFlags||{},w=new MutationObserver(q),x=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.watchShadow=n,a.upgradeAll=g,a.upgradeSubtree=f,a.observeDocument=t,a.upgradeDocument=u,a.takeRecords=r}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("document.register: first argument `name` must not be empty");if(b.indexOf("-")<0)throw new Error("document.register: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(b)+"'.");if(g.name=b,!g.prototype)throw new Error("Options missing required prototype property");return g.lifecycle=g.lifecycle||{},g.ancestry=c(g.extends),d(g),e(g),k(g.prototype),m(b,g),g.ctor=n(g),g.ctor.prototype=g.prototype,g.prototype.constructor=g.ctor,a.ready&&a.upgradeAll(document),g.ctor}function c(a){var b=v[a];return b?c(b.extends).concat([b]):[]}function d(a){for(var b,c=a.extends,d=0;b=a.ancestry[d];d++)c=b.is&&b.tag;a.tag=c||a.name,c&&(a.is=a.name)}function e(a){if(!Object.__proto__){var b=HTMLElement.prototype;if(a.is){var c=document.createElement(a.tag);b=Object.getPrototypeOf(c)}for(var d,e=a.prototype;e&&e!==b;){var d=Object.getPrototypeOf(e);e.__proto__=d,e=d}}a.native=b}function f(a){return g(w(a.tag),a)}function g(b,c){return c.is&&b.setAttribute("is",c.is),h(b,c),b.__upgraded__=!0,a.upgradeSubtree(b),j(b),b}function h(a,b){Object.__proto__?a.__proto__=b.prototype:(i(a,b.prototype,b.native),a.__proto__=b.prototype)}function i(a,b,c){for(var d={},e=b;e!==c&&e!==HTMLUnknownElement.prototype;){for(var f,g=Object.getOwnPropertyNames(e),h=0;f=g[h];h++)d[f]||(Object.defineProperty(a,f,Object.getOwnPropertyDescriptor(e,f)),d[f]=1);e=Object.getPrototypeOf(e)}}function j(a){a.createdCallback&&a.createdCallback()}function k(a){var b=a.setAttribute;a.setAttribute=function(a,c){l.call(this,a,c,b)};var c=a.removeAttribute;a.removeAttribute=function(a,b){l.call(this,a,b,c)}}function l(a,b,c){var d=this.getAttribute(a);c.apply(this,arguments),this.attributeChangedCallback&&this.getAttribute(a)!==d&&this.attributeChangedCallback(a,d)}function m(a,b){if(v[a])throw new Error("Cannot register a tag more than once");v[a]=b}function n(a){return function(){return f(a)}}function o(a,b){var c=v[b||a];if(c){if(a==c.tag&&b==c.is)return new c.ctor;if(!b&&!c.is)return new c.ctor}if(b){var d=o(a);return d.setAttribute("is",b),d}var d=w(a);return a.indexOf("-")>=0&&h(d,HTMLElement),d}function p(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is"),c=v[b||a.localName];if(c){if(b&&c.tag==a.localName)return g(a,c);if(!b&&!c.extends)return g(a,c)}}}function q(b){var c=x.call(this,b);return a.upgradeAll(c),c}a||(a=window.CustomElements={flags:{}});var r=a.flags,s=Boolean(document.register),t=!r.register&&s;if(t){var u=function(){};a.registry={},a.upgradeElement=u,a.watchShadow=u,a.upgrade=u,a.upgradeAll=u,a.upgradeSubtree=u,a.observeDocument=u,a.upgradeDocument=u,a.takeRecords=u}else{var v={},w=document.createElement.bind(document),x=Node.prototype.cloneNode;document.register=b,document.createElement=o,Node.prototype.cloneNode=q,a.registry=v,a.upgrade=p}a.hasNative=s,a.useNative=t}(window.CustomElements),function(){function a(a){return"link"===a.localName&&a.getAttribute("rel")===b}var b=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none",c={selectors:["link[rel="+b+"]"],map:{link:"parseLink"},parse:function(a){if(!a.__parsed){a.__parsed=!0;var b=a.querySelectorAll(c.selectors);d(b,function(a){c[c.map[a.localName]](a)}),CustomElements.upgradeDocument(a),CustomElements.observeDocument(a)}},parseLink:function(b){a(b)&&this.parseImport(b)},parseImport:function(a){a.content&&c.parse(a.content)}},d=Array.prototype.forEach.call.bind(Array.prototype.forEach);CustomElements.parser=c}(),function(){function a(){CustomElements.parser.parse(document),CustomElements.upgradeDocument(document);var a=window.Platform&&Platform.endOfMicrotask?Platform.endOfMicrotask:setTimeout;a(function(){CustomElements.ready=!0,CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.body.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}if("function"!=typeof window.CustomEvent&&(window.CustomEvent=function(a){var b=document.createEvent("HTMLEvents");return b.initEvent(a,!0,!0),b}),"complete"===document.readyState)a();else{var b=window.HTMLImports?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(b,a)}}();
+window.CustomElements={flags:{}};var SideTable;if("undefined"!=typeof WeakMap&&navigator.userAgent.indexOf("Firefox/")<0?SideTable=WeakMap:function(){var a=Object.defineProperty,b=Date.now()%1e9;SideTable=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")},SideTable.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]:void 0},"delete":function(a){this.set(a,void 0)}}}(),function(a){function b(a){u.push(a),t||(t=!0,q(d))}function c(a){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(a)||a}function d(){t=!1;var a=u;u=[],a.sort(function(a,b){return a.uid_-b.uid_});var b=!1;a.forEach(function(a){var c=a.takeRecords();e(a),c.length&&(a.callback_(c,a),b=!0)}),b&&d()}function e(a){a.nodes_.forEach(function(b){var c=p.get(b);c&&c.forEach(function(b){b.observer===a&&b.removeTransientObservers()})})}function f(a,b){for(var c=a;c;c=c.parentNode){var d=p.get(c);if(d)for(var e=0;e<d.length;e++){var f=d[e],g=f.options;if(c===a||g.subtree){var h=b(g);h&&f.enqueue(h)}}}}function g(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++v}function h(a,b){this.type=a,this.target=b,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function i(a){var b=new h(a.type,a.target);return b.addedNodes=a.addedNodes.slice(),b.removedNodes=a.removedNodes.slice(),b.previousSibling=a.previousSibling,b.nextSibling=a.nextSibling,b.attributeName=a.attributeName,b.attributeNamespace=a.attributeNamespace,b.oldValue=a.oldValue,b}function j(a,b){return w=new h(a,b)}function k(a){return x?x:(x=i(w),x.oldValue=a,x)}function l(){w=x=void 0}function m(a){return a===x||a===w}function n(a,b){return a===b?a:x&&m(a)?x:null}function o(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var p=new SideTable,q=window.msSetImmediate;if(!q){var r=[],s=String(Math.random());window.addEventListener("message",function(a){if(a.data===s){var b=r;r=[],b.forEach(function(a){a()})}}),q=function(a){r.push(a),window.postMessage(s,"*")}}var t=!1,u=[],v=0;g.prototype={observe:function(a,b){if(a=c(a),!b.childList&&!b.attributes&&!b.characterData||b.attributeOldValue&&!b.attributes||b.attributeFilter&&b.attributeFilter.length&&!b.attributes||b.characterDataOldValue&&!b.characterData)throw new SyntaxError;var d=p.get(a);d||p.set(a,d=[]);for(var e,f=0;f<d.length;f++)if(d[f].observer===this){e=d[f],e.removeListeners(),e.options=b;break}e||(e=new o(this,a,b),d.push(e),this.nodes_.push(a)),e.addListeners()},disconnect:function(){this.nodes_.forEach(function(a){for(var b=p.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){d.removeListeners(),b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}};var w,x;o.prototype={enqueue:function(a){var c=this.observer.records_,d=c.length;if(c.length>0){var e=c[d-1],f=n(e,a);if(f)return c[d-1]=f,void 0}else b(this.observer);c[d]=a},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(a){var b=this.options;b.attributes&&a.addEventListener("DOMAttrModified",this,!0),b.characterData&&a.addEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.addEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(a){var b=this.options;b.attributes&&a.removeEventListener("DOMAttrModified",this,!0),b.characterData&&a.removeEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.removeEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(a){if(a!==this.target){this.addListeners_(a),this.transientObservedNodes.push(a);var b=p.get(a);b||p.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[],a.forEach(function(a){this.removeListeners_(a);for(var b=p.get(a),c=0;c<b.length;c++)if(b[c]===this){b.splice(c,1);break}},this)},handleEvent:function(a){switch(a.stopImmediatePropagation(),a.type){case"DOMAttrModified":var b=a.attrName,c=a.relatedNode.namespaceURI,d=a.target,e=new j("attributes",d);e.attributeName=b,e.attributeNamespace=c;var g=a.attrChange===MutationEvent.ADDITION?null:a.prevValue;f(d,function(a){return!a.attributes||a.attributeFilter&&a.attributeFilter.length&&-1===a.attributeFilter.indexOf(b)&&-1===a.attributeFilter.indexOf(c)?void 0:a.attributeOldValue?k(g):e});break;case"DOMCharacterDataModified":var d=a.target,e=j("characterData",d),g=a.prevValue;f(d,function(a){return a.characterData?a.characterDataOldValue?k(g):e:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(a.target);case"DOMNodeInserted":var h,i,d=a.relatedNode,m=a.target;"DOMNodeInserted"===a.type?(h=[m],i=[]):(h=[],i=[m]);var n=m.previousSibling,o=m.nextSibling,e=j("childList",d);e.addedNodes=h,e.removedNodes=i,e.previousSibling=n,e.nextSibling=o,f(d,function(a){return a.childList?e:void 0})}l()}},a.JsMutationObserver=g}(this),!window.MutationObserver&&(window.MutationObserver=window.WebKitMutationObserver||window.JsMutationObserver,!MutationObserver))throw new Error("no mutation observer support");!function(a){function b(a,c,d){var e=a.firstElementChild;if(!e)for(e=a.firstChild;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;for(;e;)c(e,d)!==!0&&b(e,c,d),e=e.nextElementSibling;return null}function c(a,b){for(var c=a.shadowRoot;c;)d(c,b),c=c.olderShadowRoot}function d(a,d){b(a,function(a){return d(a)?!0:(c(a,d),void 0)}),c(a,d)}function e(a){return h(a)?(i(a),!0):(l(a),void 0)}function f(a){d(a,function(a){return e(a)?!0:void 0})}function g(a){return e(a)||f(a)}function h(b){if(!b.__upgraded__&&b.nodeType===Node.ELEMENT_NODE){var c=b.getAttribute("is")||b.localName,d=a.registry[c];if(d)return y.dom&&console.group("upgrade:",b.localName),a.upgrade(b),y.dom&&console.groupEnd(),!0}}function i(a){l(a),p(a)&&d(a,function(a){l(a)})}function j(a){if(B.push(a),!A){A=!0;var b=window.Platform&&window.Platform.endOfMicrotask||setTimeout;b(k)}}function k(){A=!1;for(var a,b=B,c=0,d=b.length;d>c&&(a=b[c]);c++)a();B=[]}function l(a){z?j(function(){m(a)}):m(a)}function m(a){(a.enteredViewCallback||a.__upgraded__&&y.dom)&&(y.dom&&console.group("inserted:",a.localName),p(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?y.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.enteredViewCallback&&(y.dom&&console.log("inserted:",a.localName),a.enteredViewCallback())),y.dom&&console.groupEnd())}function n(a){o(a),d(a,function(a){o(a)})}function o(a){z?j(function(){_removed(a)}):_removed(a)}function o(a){(a.leftViewCallback||a.__upgraded__&&y.dom)&&(y.dom&&console.log("removed:",a.localName),p(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?y.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.leftViewCallback&&a.leftViewCallback()))}function p(a){for(var b=a,c=window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(document)||document;b;){if(b==c)return!0;b=b.parentNode||b.host}}function q(a){if(a.shadowRoot&&!a.shadowRoot.__watched){y.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.shadowRoot;b;)r(b),b=b.olderShadowRoot}}function r(a){a.__watched||(v(a),a.__watched=!0)}function s(a){switch(a.localName){case"style":case"script":case"template":case void 0:return!0}}function t(a){if(y.dom){var b=a[0];if(b&&"childList"===b.type&&b.addedNodes&&b.addedNodes){for(var c=b.addedNodes[0];c&&c!==document&&!c.host;)c=c.parentNode;var d=c&&(c.URL||c._URL||c.host&&c.host.localName)||"";d=d.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",a.length,d||"")}a.forEach(function(a){"childList"===a.type&&(D(a.addedNodes,function(a){s(a)||g(a)}),D(a.removedNodes,function(a){s(a)||n(a)}))}),y.dom&&console.groupEnd()}function u(){t(C.takeRecords()),k()}function v(a){C.observe(a,{childList:!0,subtree:!0})}function w(a){v(a)}function x(a){y.dom&&console.group("upgradeDocument: ",(a.URL||a._URL||"").split("/").pop()),g(a),y.dom&&console.groupEnd()}var y=window.logFlags||{},z=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;a.hasPolyfillMutations=z;var A=!1,B=[],C=new MutationObserver(t),D=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.watchShadow=q,a.upgradeAll=g,a.upgradeSubtree=f,a.observeDocument=w,a.upgradeDocument=x,a.takeRecords=u}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("document.register: first argument `name` must not be empty");if(b.indexOf("-")<0)throw new Error("document.register: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(b)+"'.");if(g.name=b,!g.prototype)throw new Error("Options missing required prototype property");return g.lifecycle=g.lifecycle||{},g.ancestry=c(g.extends),d(g),e(g),k(g.prototype),m(b,g),g.ctor=n(g),g.ctor.prototype=g.prototype,g.prototype.constructor=g.ctor,a.ready&&a.upgradeAll(document),g.ctor}function c(a){var b=v[a];return b?c(b.extends).concat([b]):[]}function d(a){for(var b,c=a.extends,d=0;b=a.ancestry[d];d++)c=b.is&&b.tag;a.tag=c||a.name,c&&(a.is=a.name)}function e(a){if(!Object.__proto__){var b=HTMLElement.prototype;if(a.is){var c=document.createElement(a.tag);b=Object.getPrototypeOf(c)}for(var d,e=a.prototype;e&&e!==b;){var d=Object.getPrototypeOf(e);e.__proto__=d,e=d}}a.native=b}function f(a){return g(w(a.tag),a)}function g(b,c){return c.is&&b.setAttribute("is",c.is),h(b,c),b.__upgraded__=!0,a.upgradeSubtree(b),j(b),b}function h(a,b){Object.__proto__?a.__proto__=b.prototype:(i(a,b.prototype,b.native),a.__proto__=b.prototype)}function i(a,b,c){for(var d={},e=b;e!==c&&e!==HTMLUnknownElement.prototype;){for(var f,g=Object.getOwnPropertyNames(e),h=0;f=g[h];h++)d[f]||(Object.defineProperty(a,f,Object.getOwnPropertyDescriptor(e,f)),d[f]=1);e=Object.getPrototypeOf(e)}}function j(a){a.createdCallback&&a.createdCallback()}function k(a){var b=a.setAttribute;a.setAttribute=function(a,c){l.call(this,a,c,b)};var c=a.removeAttribute;a.removeAttribute=function(a,b){l.call(this,a,b,c)}}function l(a,b,c){var d=this.getAttribute(a);c.apply(this,arguments),this.attributeChangedCallback&&this.getAttribute(a)!==d&&this.attributeChangedCallback(a,d)}function m(a,b){if(v[a])throw new Error("Cannot register a tag more than once");v[a]=b}function n(a){return function(){return f(a)}}function o(a,b){var c=v[b||a];if(c){if(a==c.tag&&b==c.is)return new c.ctor;if(!b&&!c.is)return new c.ctor}if(b){var d=o(a);return d.setAttribute("is",b),d}var d=w(a);return a.indexOf("-")>=0&&h(d,HTMLElement),d}function p(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is"),c=v[b||a.localName];if(c){if(b&&c.tag==a.localName)return g(a,c);if(!b&&!c.extends)return g(a,c)}}}function q(b){var c=x.call(this,b);return a.upgradeAll(c),c}a||(a=window.CustomElements={flags:{}});var r=a.flags,s=Boolean(document.register),t=!r.register&&s;if(t){var u=function(){};a.registry={},a.upgradeElement=u,a.watchShadow=u,a.upgrade=u,a.upgradeAll=u,a.upgradeSubtree=u,a.observeDocument=u,a.upgradeDocument=u,a.takeRecords=u}else{var v={},w=document.createElement.bind(document),x=Node.prototype.cloneNode;document.register=b,document.createElement=o,Node.prototype.cloneNode=q,a.registry=v,a.upgrade=p}a.hasNative=s,a.useNative=t}(window.CustomElements),function(){function a(a){return"link"===a.localName&&a.getAttribute("rel")===b}var b=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none",c={selectors:["link[rel="+b+"]"],map:{link:"parseLink"},parse:function(a){if(!a.__parsed){a.__parsed=!0;var b=a.querySelectorAll(c.selectors);d(b,function(a){c[c.map[a.localName]](a)}),CustomElements.upgradeDocument(a),CustomElements.observeDocument(a)}},parseLink:function(b){a(b)&&this.parseImport(b)},parseImport:function(a){a.content&&c.parse(a.content)}},d=Array.prototype.forEach.call.bind(Array.prototype.forEach);CustomElements.parser=c}(),function(){function a(){CustomElements.parser.parse(document),CustomElements.upgradeDocument(document);var a=window.Platform&&Platform.endOfMicrotask?Platform.endOfMicrotask:setTimeout;a(function(){CustomElements.ready=!0,CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.body.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}if("function"!=typeof window.CustomEvent&&(window.CustomEvent=function(a){var b=document.createEvent("HTMLEvents");return b.initEvent(a,!0,!0),b}),"complete"===document.readyState)a();else{var b=window.HTMLImports?"HTMLImportsLoaded":"loading"==document.readyState?"DOMContentLoaded":"load";window.addEventListener(b,a)}}(),function(){if(HTMLElement.prototype.createShadowRoot){var a=HTMLElement.prototype.createShadowRoot;HTMLElement.prototype.createShadowRoot=function(){var b=a.call(this);return b.host=this,b}}}();
diff --git a/pkg/custom_element/lib/custom_element.dart b/pkg/custom_element/lib/custom_element.dart
index d3bf02f..98bef74 100644
--- a/pkg/custom_element/lib/custom_element.dart
+++ b/pkg/custom_element/lib/custom_element.dart
@@ -174,9 +174,13 @@
/** Invoked when this component gets inserted in the DOM tree. */
void inserted() {}
+ @deprecated
+ void enteredView() {}
/** Invoked when this component is removed from the DOM tree. */
void removed() {}
+ @deprecated
+ void leftView() {}
// TODO(jmesserly): how do we implement this efficiently?
// See https://github.com/dart-lang/web-ui/issues/37
diff --git a/pkg/fixnum/lib/fixnum.dart b/pkg/fixnum/lib/fixnum.dart
index fe21c47..72a0c50 100644
--- a/pkg/fixnum/lib/fixnum.dart
+++ b/pkg/fixnum/lib/fixnum.dart
@@ -14,6 +14,8 @@
*/
library fixnum;
+import 'package:meta/meta.dart';
+
part 'src/intx.dart';
part 'src/int32.dart';
part 'src/int64.dart';
diff --git a/pkg/fixnum/lib/src/int32.dart b/pkg/fixnum/lib/src/int32.dart
index 85fbdc4..c013f91 100644
--- a/pkg/fixnum/lib/src/int32.dart
+++ b/pkg/fixnum/lib/src/int32.dart
@@ -81,7 +81,7 @@
/**
* Parses a decimal [String] and returns an [Int32].
*/
- static Int32 parseInt(String s) => new Int32.fromInt(int.parse(s));
+ static Int32 parseInt(String s) => new Int32(int.parse(s));
/**
* Parses a hexadecimal [String] and returns an [Int32].
@@ -136,7 +136,14 @@
* Constructs an [Int32] from an [int]. Only the low 32 bits of the input
* are used.
*/
- Int32.fromInt(int i) : _i = (i & 0x7fffffff) - (i & 0x80000000);
+ Int32([int i=0]) : _i = (i & 0x7fffffff) - (i & 0x80000000);
+
+ /**
+ * Constructs an [Int32] from an [int]. Only the low 32 bits of the input
+ * are used.
+ */
+ @deprecated
+ Int32.fromInt(int i) : this(i);
// Returns the [int] representation of the specified value. Throws
// [ArgumentError] for non-integer arguments.
@@ -167,17 +174,17 @@
if (other is Int64) {
return this.toInt64() + other;
}
- return new Int32.fromInt(_i + _toInt(other));
+ return new Int32(_i + _toInt(other));
}
IntX operator -(other) {
if (other is Int64) {
return this.toInt64() - other;
}
- return new Int32.fromInt(_i - _toInt(other));
+ return new Int32(_i - _toInt(other));
}
- Int32 operator -() => new Int32.fromInt(-_i);
+ Int32 operator -() => new Int32(-_i);
IntX operator *(other) {
if (other is Int64) {
@@ -192,14 +199,14 @@
// Result will be Int32
return (this.toInt64() % other).toInt32();
}
- return new Int32.fromInt(_i % _toInt(other));
+ return new Int32(_i % _toInt(other));
}
Int32 operator ~/(other) {
if (other is Int64) {
return (this.toInt64() ~/ other).toInt32();
}
- return new Int32.fromInt(_i ~/ _toInt(other));
+ return new Int32(_i ~/ _toInt(other));
}
Int32 remainder(other) {
@@ -214,31 +221,31 @@
if (other is Int64) {
return (this.toInt64() & other).toInt32();
}
- return new Int32.fromInt(_i & _toInt(other));
+ return new Int32(_i & _toInt(other));
}
Int32 operator |(other) {
if (other is Int64) {
return (this.toInt64() | other).toInt32();
}
- return new Int32.fromInt(_i | _toInt(other));
+ return new Int32(_i | _toInt(other));
}
Int32 operator ^(other) {
if (other is Int64) {
return (this.toInt64() ^ other).toInt32();
}
- return new Int32.fromInt(_i ^ _toInt(other));
+ return new Int32(_i ^ _toInt(other));
}
- Int32 operator ~() => new Int32.fromInt(~_i);
+ Int32 operator ~() => new Int32(~_i);
Int32 operator <<(int n) {
if (n < 0) {
throw new ArgumentError(n);
}
n &= 31;
- return new Int32.fromInt(_i << n);
+ return new Int32(_i << n);
}
Int32 operator >>(int n) {
@@ -252,7 +259,7 @@
} else {
value = (_i >> n) | (0xffffffff << (32 - n));
}
- return new Int32.fromInt(value);
+ return new Int32(value);
}
Int32 shiftRightUnsigned(int n) {
@@ -266,7 +273,7 @@
} else {
value = (_i >> n) & ((1 << (32 - n)) - 1);
}
- return new Int32.fromInt(value);
+ return new Int32(value);
}
/**
@@ -325,14 +332,38 @@
bool get isNegative => _i < 0;
bool get isOdd => (_i & 0x1) == 1;
bool get isZero => _i == 0;
+ int get bitLength => _i.bitLength;
int get hashCode => _i;
- Int32 abs() => _i < 0 ? new Int32.fromInt(-_i) : this;
+ Int32 abs() => _i < 0 ? new Int32(-_i) : this;
+
+ Int32 clamp(lowerLimit, upperLimit) {
+ if (this < lowerLimit) {
+ if (lowerLimit is IntX) return lowerLimit.toInt32();
+ if (lowerLimit is int) return new Int32(lowerLimit);
+ throw new ArgumentError(lowerLimit);
+ } else if (this > upperLimit) {
+ if (upperLimit is IntX) return upperLimit.toInt32();
+ if (upperLimit is int) return new Int32(upperLimit);
+ throw new ArgumentError(upperLimit);
+ }
+ return this;
+ }
int numberOfLeadingZeros() => _numberOfLeadingZeros(_i);
int numberOfTrailingZeros() => _numberOfTrailingZeros(_i);
+ Int32 toSigned(int width) {
+ if (width < 1 || width > 32) throw new ArgumentError(width);
+ return new Int32(_i.toSigned(width));
+ }
+
+ Int32 toUnsigned(int width) {
+ if (width < 0 || width > 32) throw new ArgumentError(width);
+ return new Int32(_i.toUnsigned(width));
+ }
+
List<int> toBytes() {
List<int> result = new List<int>(4);
result[0] = _i & 0xff;
@@ -342,9 +373,10 @@
return result;
}
+ double toDouble() => _i.toDouble();
int toInt() => _i;
Int32 toInt32() => this;
- Int64 toInt64() => new Int64.fromInt(_i);
+ Int64 toInt64() => new Int64(_i);
String toString() => _i.toString();
String toHexString() => _i.toRadixString(16);
diff --git a/pkg/fixnum/lib/src/int64.dart b/pkg/fixnum/lib/src/int64.dart
index 64ca2b6..f12631c 100644
--- a/pkg/fixnum/lib/src/int64.dart
+++ b/pkg/fixnum/lib/src/int64.dart
@@ -118,14 +118,9 @@
//
/**
- * Constructs an [Int64] equal to 0.
+ * Constructs an [Int64] with a given [int] value; zero by default.
*/
- Int64() : _l = 0, _m = 0, _h = 0;
-
- /**
- * Constructs an [Int64] with a given [int] value.
- */
- factory Int64.fromInt(int value) {
+ factory Int64([int value=0]) {
int v0 = 0, v1 = 0, v2 = 0;
bool negative = false;
if (value < 0) {
@@ -153,6 +148,12 @@
return new Int64._bits(v0, v1, v2);
}
+ /**
+ * Constructs an [Int64] with a given [int] value.
+ */
+ @deprecated
+ factory Int64.fromInt(int value) => new Int64(value);
+
factory Int64.fromBytes(List<int> bytes) {
int top = bytes[7] & 0xff;
top <<= 8;
@@ -212,7 +213,7 @@
if (val is Int64) {
return val;
} else if (val is int) {
- return new Int64.fromInt(val);
+ return new Int64(val);
} else if (val is Int32) {
return val.toInt64();
}
@@ -457,7 +458,7 @@
// Since we know one of [_h] or [_m] is non-zero, if [other] fits in the
// low word then it can't be numerically equal.
if ((_MASK & other) == other) return false;
- o = new Int64.fromInt(other);
+ o = new Int64(other);
} else if (other is Int32) {
o = other.toInt64();
}
@@ -515,12 +516,25 @@
bool get isOdd => (_l & 0x1) == 1;
bool get isZero => _h == 0 && _m == 0 && _l == 0;
+ int get bitLength {
+ if (isZero) return 0;
+ int a0 = _l, a1 = _m, a2 = _h;
+ if (isNegative) {
+ a0 = _MASK & ~a0;
+ a1 = _MASK & ~a1;
+ a2 = _MASK2 & ~a2;
+ }
+ if (a2 != 0) return _BITS01 + a2.bitLength;
+ if (a1 != 0) return _BITS + a1.bitLength;
+ return a0.bitLength;
+ }
+
/**
* Returns a hash code based on all the bits of this [Int64].
*/
int get hashCode {
// TODO(sra): Should we ensure that hashCode values match corresponding int?
- // i.e. should `new Int64.fromInt(x).hashCode == x.hashCode`?
+ // i.e. should `new Int64(x).hashCode == x.hashCode`?
int bottom = ((_m & 0x3ff) << _BITS) | _l;
int top = (_h << 12) | ((_m >> 10) & 0xfff);
return bottom ^ top;
@@ -530,6 +544,14 @@
return this.isNegative ? -this : this;
}
+ Int64 clamp(lowerLimit, upperLimit) {
+ Int64 lower = _promote(lowerLimit);
+ Int64 upper = _promote(upperLimit);
+ if (this < lower) return lower;
+ if (this > upper) return upper;
+ return this;
+ }
+
/**
* Returns the number of leading zeros in this [Int64] as an [int]
* between 0 and 64.
@@ -571,6 +593,35 @@
return 64;
}
+ Int64 toSigned(int width) {
+ if (width < 1 || width > 64) throw new ArgumentError(width);
+ if (width > _BITS01) {
+ return Int64._masked(_l, _m, _h.toSigned(width - _BITS01));
+ } else if (width > _BITS) {
+ int m = _m.toSigned(width - _BITS);
+ return m.isNegative ? Int64._masked(_l, m, _MASK2) :
+ new Int64._bits(_l, m, 0);
+ } else {
+ int l = _l.toSigned(width);
+ return l.isNegative ? Int64._masked(l, _MASK, _MASK2) :
+ new Int64._bits(l, 0, 0);
+ }
+ }
+
+ Int64 toUnsigned(int width) {
+ if (width < 0 || width > 64) throw new ArgumentError(width);
+ if (width > _BITS01) {
+ int h = _h.toUnsigned(width - _BITS01);
+ return Int64._masked(_l, _m, h);
+ } else if (width > _BITS) {
+ int m = _m.toUnsigned(width - _BITS);
+ return Int64._masked(_l, m, 0);
+ } else {
+ int l = _l.toUnsigned(width);
+ return Int64._masked(l, 0, 0);
+ }
+ }
+
List<int> toBytes() {
List<int> result = new List<int>(8);
result[0] = _l & 0xff;
@@ -584,32 +635,37 @@
return result;
}
+ double toDouble() => toInt().toDouble();
+
int toInt() {
int l = _l;
int m = _m;
int h = _h;
bool negative = false;
if ((_h & _SIGN_BIT_MASK) != 0) {
- l = ~_l & _MASK;
- m = ~_m & _MASK;
- h = ~_h & _MASK2;
+ l = _MASK & ~_l;
+ m = _MASK & ~_m;
+ h = _MASK2 & ~_h;
negative = true;
}
- int result;
if (_haveBigInts) {
- result = (h << _BITS01) | (m << _BITS) | l;
+ int result = (h << _BITS01) | (m << _BITS) | l;
+ return negative ? -result - 1 : result;
} else {
- result = (h * 17592186044416) + (m * 4194304) + l;
+ if (negative) {
+ return -((l + 1) + (m * 4194304) + (h * 17592186044416));
+ } else {
+ return (l + (m * 4194304)) + (h * 17592186044416);
+ }
}
- return negative ? -result - 1 : result;
}
/**
* Returns an [Int32] containing the low 32 bits of this [Int64].
*/
Int32 toInt32() {
- return new Int32.fromInt(((_m & 0x3ff) << _BITS) | _l);
+ return new Int32(((_m & 0x3ff) << _BITS) | _l);
}
/**
@@ -627,7 +683,7 @@
if (isZero) return "0";
Int64 x = this;
String hexStr = "";
- Int64 digit_f = new Int64.fromInt(0xf);
+ Int64 digit_f = new Int64(0xf);
while (!x.isZero) {
int digit = x._l & 0xf;
hexStr = "${_hexDigit(digit)}$hexStr";
diff --git a/pkg/fixnum/lib/src/intx.dart b/pkg/fixnum/lib/src/intx.dart
index a0cd102..859cb95 100644
--- a/pkg/fixnum/lib/src/intx.dart
+++ b/pkg/fixnum/lib/src/intx.dart
@@ -129,6 +129,21 @@
/** Returns the absolute value of this integer. */
IntX abs();
+ /** Clamps this integer to be in the range [lowerLimit] - [upperLimit]. */
+ IntX clamp(IntX lowerLimit, IntX upperLimit);
+
+ /**
+ * Returns the minimum number of bits required to store this integer.
+ *
+ * The number of bits excludes the sign bit, which gives the natural length
+ * for non-negative (unsigned) values. Negative values are complemented to
+ * return the bit position of the first bit that differs from the sign bit.
+ *
+ * To find the the number of bits needed to store the value as a signed value,
+ * add one, i.e. use `x.bitLength + 1`.
+ */
+ int get bitLength;
+
/**
* Returns the number of high-order zeros in this integer's bit
* representation.
@@ -141,6 +156,33 @@
int numberOfTrailingZeros();
/**
+ * Returns the least significant [width] bits of this integer, extending the
+ * highest retained bit to the sign. This is the same as truncating the value
+ * to fit in [width] bits using an signed 2-s complement representation. The
+ * returned value has the same bit value in all positions higher than [width].
+ *
+ * If the input value fits in [width] bits without truncation, the result is
+ * the same as the input. The minimum width needed to avoid truncation of `x`
+ * is `x.bitLength + 1`, i.e.
+ *
+ * x == x.toSigned(x.bitLength + 1);
+ */
+ IntX toSigned(int width);
+
+ /**
+ * Returns the least significant [width] bits of this integer as a
+ * non-negative number (i.e. unsigned representation). The returned value has
+ * zeros in all bit positions higher than [width].
+ *
+ * If the input fits in [width] bits without truncation, the result is the
+ * same as the input. The minimum width needed to avoid truncation of `x` is
+ * given by `x.bitLength`, i.e.
+ *
+ * x == x.toUnsigned(x.bitLength);
+ */
+ IntX toUnsigned(int width);
+
+ /**
* Returns a byte-sequence representation of this integer.
*
* Returns a list of int, starting with the least significant byte.
@@ -148,6 +190,14 @@
List<int> toBytes();
/**
+ * Returns the double representation of this integer.
+ *
+ * On some platforms, inputs with large absolute values (i.e., > 2^52) may
+ * lose some of their low-order bits.
+ */
+ double toDouble();
+
+ /**
* Returns the int representation of this integer.
*
* On some platforms, inputs with large absolute values (i.e., > 2^52) may
diff --git a/pkg/fixnum/pubspec.yaml b/pkg/fixnum/pubspec.yaml
index c582394..336c9e6 100644
--- a/pkg/fixnum/pubspec.yaml
+++ b/pkg/fixnum/pubspec.yaml
@@ -2,5 +2,7 @@
author: Dart Team <misc@dartlang.org>
description: Library for 32- and 64-bit fixed size integers.
homepage: http://www.dartlang.org
+dependencies:
+ meta: any
dev_dependencies:
unittest: any
diff --git a/pkg/fixnum/test/int_32_test.dart b/pkg/fixnum/test/int_32_test.dart
index 401f533..e34f714 100644
--- a/pkg/fixnum/test/int_32_test.dart
+++ b/pkg/fixnum/test/int_32_test.dart
@@ -7,246 +7,334 @@
import 'package:unittest/unittest.dart';
void main() {
+ group("isX tests", () {
+ test("isEven", () {
+ expect((-Int32.ONE).isEven, false);
+ expect(Int32.ZERO.isEven, true);
+ expect(Int32.ONE.isEven, false);
+ expect(Int32.TWO.isEven, true);
+ });
+ test("isMaxValue", () {
+ expect(Int32.MIN_VALUE.isMaxValue, false);
+ expect(Int32.ZERO.isMaxValue, false);
+ expect(Int32.MAX_VALUE.isMaxValue, true);
+ });
+ test("isMinValue", () {
+ expect(Int32.MIN_VALUE.isMinValue, true);
+ expect(Int32.ZERO.isMinValue, false);
+ expect(Int32.MAX_VALUE.isMinValue, false);
+ });
+ test("isNegative", () {
+ expect(Int32.MIN_VALUE.isNegative, true);
+ expect(Int32.ZERO.isNegative, false);
+ expect(Int32.ONE.isNegative, false);
+ });
+ test("isOdd", () {
+ expect((-Int32.ONE).isOdd, true);
+ expect(Int32.ZERO.isOdd, false);
+ expect(Int32.ONE.isOdd, true);
+ expect(Int32.TWO.isOdd, false);
+ });
+ test("isZero", () {
+ expect(Int32.MIN_VALUE.isZero, false);
+ expect(Int32.ZERO.isZero, true);
+ expect(Int32.MAX_VALUE.isZero, false);
+ });
+ test("bitLength", () {
+ expect(new Int32(-2).bitLength, 1);
+ expect((-Int32.ONE).bitLength, 0);
+ expect(Int32.ZERO.bitLength, 0);
+ expect(Int32.ONE.bitLength, 1);
+ expect(new Int32(2).bitLength, 2);
+ expect(Int32.MAX_VALUE.bitLength, 31);
+ expect(Int32.MIN_VALUE.bitLength, 31);
+ });
+ });
+
group("arithmetic operators", () {
- Int32 n1 = new Int32.fromInt(1234);
- Int32 n2 = new Int32.fromInt(9876);
- Int32 n3 = new Int32.fromInt(-1234);
- Int32 n4 = new Int32.fromInt(-9876);
- Int32 n5 = new Int32.fromInt(0x12345678);
- Int32 n6 = new Int32.fromInt(0x22222222);
+ Int32 n1 = new Int32(1234);
+ Int32 n2 = new Int32(9876);
+ Int32 n3 = new Int32(-1234);
+ Int32 n4 = new Int32(-9876);
+ Int32 n5 = new Int32(0x12345678);
+ Int32 n6 = new Int32(0x22222222);
test("+", () {
- expect(n1 + n2, new Int32.fromInt(11110));
- expect(n3 + n2, new Int32.fromInt(8642));
- expect(n3 + n4, new Int32.fromInt(-11110));
+ expect(n1 + n2, new Int32(11110));
+ expect(n3 + n2, new Int32(8642));
+ expect(n3 + n4, new Int32(-11110));
expect(Int32.MAX_VALUE + 1, Int32.MIN_VALUE);
- expect(() => new Int32.fromInt(17) + null, throws);
+ expect(() => new Int32(17) + null, throws);
});
test("-", () {
- expect(n1 - n2, new Int32.fromInt(-8642));
- expect(n3 - n2, new Int32.fromInt(-11110));
- expect(n3 - n4, new Int32.fromInt(8642));
+ expect(n1 - n2, new Int32(-8642));
+ expect(n3 - n2, new Int32(-11110));
+ expect(n3 - n4, new Int32(8642));
expect(Int32.MIN_VALUE - 1, Int32.MAX_VALUE);
- expect(() => new Int32.fromInt(17) - null, throws);
+ expect(() => new Int32(17) - null, throws);
});
test("unary -", () {
- expect(-n1, new Int32.fromInt(-1234));
+ expect(-n1, new Int32(-1234));
expect(-Int32.ZERO, Int32.ZERO);
});
test("*", () {
- expect(n1 * n2, new Int32.fromInt(12186984));
- expect(n2 * n3, new Int32.fromInt(-12186984));
- expect(n3 * n3, new Int32.fromInt(1522756));
- expect(n3 * n2, new Int32.fromInt(-12186984));
- expect(new Int32.fromInt(0x12345678) * new Int32.fromInt(0x22222222),
- new Int32.fromInt(-899716112));
- expect((new Int32.fromInt(123456789) * new Int32.fromInt(987654321)),
- new Int32.fromInt(-67153019));
- expect(new Int32.fromInt(0x12345678) * new Int64.fromInt(0x22222222),
+ expect(n1 * n2, new Int32(12186984));
+ expect(n2 * n3, new Int32(-12186984));
+ expect(n3 * n3, new Int32(1522756));
+ expect(n3 * n2, new Int32(-12186984));
+ expect(new Int32(0x12345678) * new Int32(0x22222222),
+ new Int32(-899716112));
+ expect((new Int32(123456789) * new Int32(987654321)),
+ new Int32(-67153019));
+ expect(new Int32(0x12345678) * new Int64(0x22222222),
new Int64.fromInts(0x026D60DC, 0xCA5F6BF0));
- expect((new Int32.fromInt(123456789) * 987654321),
- new Int32.fromInt(-67153019));
- expect(() => new Int32.fromInt(17) * null, throws);
+ expect((new Int32(123456789) * 987654321),
+ new Int32(-67153019));
+ expect(() => new Int32(17) * null, throws);
});
test("~/", () {
- expect(new Int32.fromInt(829893893) ~/ new Int32.fromInt(1919),
- new Int32.fromInt(432461));
- expect(new Int32.fromInt(0x12345678) ~/ new Int32.fromInt(0x22),
- new Int32.fromInt(0x12345678 ~/ 0x22));
- expect(new Int32.fromInt(829893893) ~/ new Int64.fromInt(1919),
- new Int32.fromInt(432461));
- expect(new Int32.fromInt(0x12345678) ~/ new Int64.fromInt(0x22),
- new Int32.fromInt(0x12345678 ~/ 0x22));
- expect(new Int32.fromInt(829893893) ~/ 1919, new Int32.fromInt(432461));
- expect(() => new Int32.fromInt(17) ~/ Int32.ZERO, throws);
- expect(() => new Int32.fromInt(17) ~/ null, throws);
+ expect(new Int32(829893893) ~/ new Int32(1919), new Int32(432461));
+ expect(new Int32(0x12345678) ~/ new Int32(0x22),
+ new Int32(0x12345678 ~/ 0x22));
+ expect(new Int32(829893893) ~/ new Int64(1919), new Int32(432461));
+ expect(new Int32(0x12345678) ~/ new Int64(0x22),
+ new Int32(0x12345678 ~/ 0x22));
+ expect(new Int32(829893893) ~/ 1919, new Int32(432461));
+ expect(() => new Int32(17) ~/ Int32.ZERO, throws);
+ expect(() => new Int32(17) ~/ null, throws);
});
test("%", () {
- expect(new Int32.fromInt(0x12345678) % new Int32.fromInt(0x22),
- new Int32.fromInt(0x12345678 % 0x22));
- expect(new Int32.fromInt(0x12345678) % new Int64.fromInt(0x22),
- new Int32.fromInt(0x12345678 % 0x22));
- expect(() => new Int32.fromInt(17) % null, throws);
+ expect(new Int32(0x12345678) % new Int32(0x22),
+ new Int32(0x12345678 % 0x22));
+ expect(new Int32(0x12345678) % new Int64(0x22),
+ new Int32(0x12345678 % 0x22));
+ expect(() => new Int32(17) % null, throws);
});
test("remainder", () {
- expect(new Int32.fromInt(0x12345678).remainder(new Int32.fromInt(0x22)),
- new Int32.fromInt(0x12345678.remainder(0x22)));
- expect(new Int32.fromInt(0x12345678).remainder(new Int32.fromInt(-0x22)),
- new Int32.fromInt(0x12345678.remainder(-0x22)));
- expect(new Int32.fromInt(-0x12345678).remainder(new Int32.fromInt(-0x22)),
- new Int32.fromInt(-0x12345678.remainder(-0x22)));
- expect(new Int32.fromInt(-0x12345678).remainder(new Int32.fromInt(0x22)),
- new Int32.fromInt(-0x12345678.remainder(0x22)));
- expect(new Int32.fromInt(0x12345678).remainder(new Int64.fromInt(0x22)),
- new Int32.fromInt(0x12345678.remainder(0x22)));
- expect(() => new Int32.fromInt(17).remainder(null), throws);
+ expect(new Int32(0x12345678).remainder(new Int32(0x22)),
+ new Int32(0x12345678.remainder(0x22)));
+ expect(new Int32(0x12345678).remainder(new Int32(-0x22)),
+ new Int32(0x12345678.remainder(-0x22)));
+ expect(new Int32(-0x12345678).remainder(new Int32(-0x22)),
+ new Int32(-0x12345678.remainder(-0x22)));
+ expect(new Int32(-0x12345678).remainder(new Int32(0x22)),
+ new Int32(-0x12345678.remainder(0x22)));
+ expect(new Int32(0x12345678).remainder(new Int64(0x22)),
+ new Int32(0x12345678.remainder(0x22)));
+ expect(() => new Int32(17).remainder(null), throws);
+ });
+
+ test("clamp", () {
+ Int32 val = new Int32(17);
+ expect(val.clamp(20, 30), new Int32(20));
+ expect(val.clamp(10, 20), new Int32(17));
+ expect(val.clamp(10, 15), new Int32(15));
+
+ expect(val.clamp(new Int32(20), new Int32(30)), new Int32(20));
+ expect(val.clamp(new Int32(10), new Int32(20)), new Int32(17));
+ expect(val.clamp(new Int32(10), new Int32(15)), new Int32(15));
+
+ expect(val.clamp(new Int64(20), new Int64(30)), new Int32(20));
+ expect(val.clamp(new Int64(10), new Int64(20)), new Int32(17));
+ expect(val.clamp(new Int64(10), new Int64(15)), new Int32(15));
+ expect(val.clamp(Int64.MIN_VALUE, new Int64(30)), new Int32(17));
+ expect(val.clamp(new Int64(10), Int64.MAX_VALUE), new Int32(17));
+
+ expect(() => val.clamp(1, 'b'), throwsA(isArgumentError));
+ expect(() => val.clamp('a', 1), throwsA(isArgumentError));
});
});
group("comparison operators", () {
test("<", () {
- expect(new Int32.fromInt(17) < new Int32.fromInt(18), true);
- expect(new Int32.fromInt(17) < new Int32.fromInt(17), false);
- expect(new Int32.fromInt(17) < new Int32.fromInt(16), false);
- expect(new Int32.fromInt(17) < new Int64.fromInt(18), true);
- expect(new Int32.fromInt(17) < new Int64.fromInt(17), false);
- expect(new Int32.fromInt(17) < new Int64.fromInt(16), false);
+ expect(new Int32(17) < new Int32(18), true);
+ expect(new Int32(17) < new Int32(17), false);
+ expect(new Int32(17) < new Int32(16), false);
+ expect(new Int32(17) < new Int64(18), true);
+ expect(new Int32(17) < new Int64(17), false);
+ expect(new Int32(17) < new Int64(16), false);
expect(Int32.MIN_VALUE < Int32.MAX_VALUE, true);
expect(Int32.MAX_VALUE < Int32.MIN_VALUE, false);
- expect(() => new Int32.fromInt(17) < null, throws);
+ expect(() => new Int32(17) < null, throws);
});
test("<=", () {
- expect(new Int32.fromInt(17) <= new Int32.fromInt(18), true);
- expect(new Int32.fromInt(17) <= new Int32.fromInt(17), true);
- expect(new Int32.fromInt(17) <= new Int32.fromInt(16), false);
- expect(new Int32.fromInt(17) <= new Int64.fromInt(18), true);
- expect(new Int32.fromInt(17) <= new Int64.fromInt(17), true);
- expect(new Int32.fromInt(17) <= new Int64.fromInt(16), false);
+ expect(new Int32(17) <= new Int32(18), true);
+ expect(new Int32(17) <= new Int32(17), true);
+ expect(new Int32(17) <= new Int32(16), false);
+ expect(new Int32(17) <= new Int64(18), true);
+ expect(new Int32(17) <= new Int64(17), true);
+ expect(new Int32(17) <= new Int64(16), false);
expect(Int32.MIN_VALUE <= Int32.MAX_VALUE, true);
expect(Int32.MAX_VALUE <= Int32.MIN_VALUE, false);
- expect(() => new Int32.fromInt(17) <= null, throws);
+ expect(() => new Int32(17) <= null, throws);
});
test("==", () {
- expect(new Int32.fromInt(17) == new Int32.fromInt(18), false);
- expect(new Int32.fromInt(17) == new Int32.fromInt(17), true);
- expect(new Int32.fromInt(17) == new Int32.fromInt(16), false);
- expect(new Int32.fromInt(17) == new Int64.fromInt(18), false);
- expect(new Int32.fromInt(17) == new Int64.fromInt(17), true);
- expect(new Int32.fromInt(17) == new Int64.fromInt(16), false);
+ expect(new Int32(17) == new Int32(18), false);
+ expect(new Int32(17) == new Int32(17), true);
+ expect(new Int32(17) == new Int32(16), false);
+ expect(new Int32(17) == new Int64(18), false);
+ expect(new Int32(17) == new Int64(17), true);
+ expect(new Int32(17) == new Int64(16), false);
expect(Int32.MIN_VALUE == Int32.MAX_VALUE, false);
- expect(new Int32.fromInt(17) == new Object(), false);
- expect(new Int32.fromInt(17) == null, false);
+ expect(new Int32(17) == new Object(), false);
+ expect(new Int32(17) == null, false);
});
test(">=", () {
- expect(new Int32.fromInt(17) >= new Int32.fromInt(18), false);
- expect(new Int32.fromInt(17) >= new Int32.fromInt(17), true);
- expect(new Int32.fromInt(17) >= new Int32.fromInt(16), true);
- expect(new Int32.fromInt(17) >= new Int64.fromInt(18), false);
- expect(new Int32.fromInt(17) >= new Int64.fromInt(17), true);
- expect(new Int32.fromInt(17) >= new Int64.fromInt(16), true);
+ expect(new Int32(17) >= new Int32(18), false);
+ expect(new Int32(17) >= new Int32(17), true);
+ expect(new Int32(17) >= new Int32(16), true);
+ expect(new Int32(17) >= new Int64(18), false);
+ expect(new Int32(17) >= new Int64(17), true);
+ expect(new Int32(17) >= new Int64(16), true);
expect(Int32.MIN_VALUE >= Int32.MAX_VALUE, false);
expect(Int32.MAX_VALUE >= Int32.MIN_VALUE, true);
- expect(() => new Int32.fromInt(17) >= null, throws);
+ expect(() => new Int32(17) >= null, throws);
});
test(">", () {
- expect(new Int32.fromInt(17) > new Int32.fromInt(18), false);
- expect(new Int32.fromInt(17) > new Int32.fromInt(17), false);
- expect(new Int32.fromInt(17) > new Int32.fromInt(16), true);
- expect(new Int32.fromInt(17) > new Int64.fromInt(18), false);
- expect(new Int32.fromInt(17) > new Int64.fromInt(17), false);
- expect(new Int32.fromInt(17) > new Int64.fromInt(16), true);
+ expect(new Int32(17) > new Int32(18), false);
+ expect(new Int32(17) > new Int32(17), false);
+ expect(new Int32(17) > new Int32(16), true);
+ expect(new Int32(17) > new Int64(18), false);
+ expect(new Int32(17) > new Int64(17), false);
+ expect(new Int32(17) > new Int64(16), true);
expect(Int32.MIN_VALUE > Int32.MAX_VALUE, false);
expect(Int32.MAX_VALUE > Int32.MIN_VALUE, true);
- expect(() => new Int32.fromInt(17) > null, throws);
+ expect(() => new Int32(17) > null, throws);
});
});
group("bitwise operators", () {
test("&", () {
- expect(new Int32.fromInt(0x12345678) & new Int32.fromInt(0x22222222),
- new Int32.fromInt(0x12345678 & 0x22222222));
- expect(new Int32.fromInt(0x12345678) & new Int64.fromInt(0x22222222),
- new Int64.fromInt(0x12345678 & 0x22222222));
- expect(() => new Int32.fromInt(17) & null, throwsArgumentError);
+ expect(new Int32(0x12345678) & new Int32(0x22222222),
+ new Int32(0x12345678 & 0x22222222));
+ expect(new Int32(0x12345678) & new Int64(0x22222222),
+ new Int64(0x12345678 & 0x22222222));
+ expect(() => new Int32(17) & null, throwsArgumentError);
});
test("|", () {
- expect(new Int32.fromInt(0x12345678) | new Int32.fromInt(0x22222222),
- new Int32.fromInt(0x12345678 | 0x22222222));
- expect(new Int32.fromInt(0x12345678) | new Int64.fromInt(0x22222222),
- new Int64.fromInt(0x12345678 | 0x22222222));
- expect(() => new Int32.fromInt(17) | null, throws);
+ expect(new Int32(0x12345678) | new Int32(0x22222222),
+ new Int32(0x12345678 | 0x22222222));
+ expect(new Int32(0x12345678) | new Int64(0x22222222),
+ new Int64(0x12345678 | 0x22222222));
+ expect(() => new Int32(17) | null, throws);
});
test("^", () {
- expect(new Int32.fromInt(0x12345678) ^ new Int32.fromInt(0x22222222),
- new Int32.fromInt(0x12345678 ^ 0x22222222));
- expect(new Int32.fromInt(0x12345678) ^ new Int64.fromInt(0x22222222),
- new Int64.fromInt(0x12345678 ^ 0x22222222));
- expect(() => new Int32.fromInt(17) ^ null, throws);
+ expect(new Int32(0x12345678) ^ new Int32(0x22222222),
+ new Int32(0x12345678 ^ 0x22222222));
+ expect(new Int32(0x12345678) ^ new Int64(0x22222222),
+ new Int64(0x12345678 ^ 0x22222222));
+ expect(() => new Int32(17) ^ null, throws);
});
test("~", () {
- expect(~(new Int32.fromInt(0x12345678)), new Int32.fromInt(~0x12345678));
- expect(-(new Int32.fromInt(0x12345678)), new Int64.fromInt(-0x12345678));
+ expect(~(new Int32(0x12345678)), new Int32(~0x12345678));
+ expect(-(new Int32(0x12345678)), new Int64(-0x12345678));
});
});
group("bitshift operators", () {
test("<<", () {
- expect(new Int32.fromInt(0x12345678) << 7,
- new Int32.fromInt(0x12345678 << 7));
- expect(() => new Int32.fromInt(17) << -1, throwsArgumentError);
- expect(() => new Int32.fromInt(17) << null, throws);
+ expect(new Int32(0x12345678) << 7, new Int32(0x12345678 << 7));
+ expect(() => new Int32(17) << -1, throwsArgumentError);
+ expect(() => new Int32(17) << null, throws);
});
test(">>", () {
- expect(new Int32.fromInt(0x12345678) >> 7,
- new Int32.fromInt(0x12345678 >> 7));
- expect(() => new Int32.fromInt(17) >> -1, throwsArgumentError);
- expect(() => new Int32.fromInt(17) >> null, throws);
+ expect(new Int32(0x12345678) >> 7, new Int32(0x12345678 >> 7));
+ expect(() => new Int32(17) >> -1, throwsArgumentError);
+ expect(() => new Int32(17) >> null, throws);
});
test("shiftRightUnsigned", () {
- expect(new Int32.fromInt(0x12345678).shiftRightUnsigned(7),
- new Int32.fromInt(0x12345678 >> 7));
- expect(() => (new Int32.fromInt(17).shiftRightUnsigned(-1)),
- throwsArgumentError);
- expect(() => (new Int32.fromInt(17).shiftRightUnsigned(null)), throws);
+ expect(new Int32(0x12345678).shiftRightUnsigned(7),
+ new Int32(0x12345678 >> 7));
+ expect(() => (new Int32(17).shiftRightUnsigned(-1)), throwsArgumentError);
+ expect(() => (new Int32(17).shiftRightUnsigned(null)), throws);
});
});
- group("type conversions", () {
- expect(new Int32.fromInt(17).toInt(), 17);
- expect(new Int32.fromInt(-17).toInt(), -17);
- expect(new Int32.fromInt(17).toInt32(), new Int32.fromInt(17));
- expect(new Int32.fromInt(-17).toInt32(), new Int32.fromInt(-17));
- expect(new Int32.fromInt(17).toInt64(), new Int64.fromInt(17));
- expect(new Int32.fromInt(-17).toInt64(), new Int64.fromInt(-17));
+ group("conversions", () {
+ test("toSigned", () {
+ expect(Int32.ONE.toSigned(2), Int32.ONE);
+ expect(Int32.ONE.toSigned(1), -Int32.ONE);
+ expect(Int32.MAX_VALUE.toSigned(32), Int32.MAX_VALUE);
+ expect(Int32.MIN_VALUE.toSigned(32), Int32.MIN_VALUE);
+ expect(Int32.MAX_VALUE.toSigned(31), -Int32.ONE);
+ expect(Int32.MIN_VALUE.toSigned(31), Int32.ZERO);
+ expect(() => Int32.ONE.toSigned(0), throws);
+ expect(() => Int32.ONE.toSigned(33), throws);
+ });
+ test("toUnsigned", () {
+ expect(Int32.ONE.toUnsigned(1), Int32.ONE);
+ expect(Int32.ONE.toUnsigned(0), Int32.ZERO);
+ expect(Int32.MAX_VALUE.toUnsigned(32), Int32.MAX_VALUE);
+ expect(Int32.MIN_VALUE.toUnsigned(32), Int32.MIN_VALUE);
+ expect(Int32.MAX_VALUE.toUnsigned(31), Int32.MAX_VALUE);
+ expect(Int32.MIN_VALUE.toUnsigned(31), Int32.ZERO);
+ expect(() => Int32.ONE.toUnsigned(-1), throws);
+ expect(() => Int32.ONE.toUnsigned(33), throws);
+ });
+ test("toDouble", () {
+ expect(new Int32(17).toDouble(), same(17.0));
+ expect(new Int32(-17).toDouble(), same(-17.0));
+ });
+ test("toInt", () {
+ expect(new Int32(17).toInt(), 17);
+ expect(new Int32(-17).toInt(), -17);
+ });
+ test("toInt32", () {
+ expect(new Int32(17).toInt32(), new Int32(17));
+ expect(new Int32(-17).toInt32(), new Int32(-17));
+ });
+ test("toInt64", () {
+ expect(new Int32(17).toInt64(), new Int64(17));
+ expect(new Int32(-17).toInt64(), new Int64(-17));
+ });
});
group("string representation", () {
test("toString", () {
- expect(new Int32.fromInt(0).toString(), "0");
- expect(new Int32.fromInt(1).toString(), "1");
- expect(new Int32.fromInt(-1).toString(), "-1");
- expect(new Int32.fromInt(1000).toString(), "1000");
- expect(new Int32.fromInt(-1000).toString(), "-1000");
- expect(new Int32.fromInt(123456789).toString(), "123456789");
- expect(new Int32.fromInt(2147483647).toString(), "2147483647");
- expect(new Int32.fromInt(2147483648).toString(), "-2147483648");
- expect(new Int32.fromInt(2147483649).toString(), "-2147483647");
- expect(new Int32.fromInt(2147483650).toString(), "-2147483646");
- expect(new Int32.fromInt(-2147483648).toString(), "-2147483648");
- expect(new Int32.fromInt(-2147483649).toString(), "2147483647");
- expect(new Int32.fromInt(-2147483650).toString(), "2147483646");
+ expect(new Int32(0).toString(), "0");
+ expect(new Int32(1).toString(), "1");
+ expect(new Int32(-1).toString(), "-1");
+ expect(new Int32(1000).toString(), "1000");
+ expect(new Int32(-1000).toString(), "-1000");
+ expect(new Int32(123456789).toString(), "123456789");
+ expect(new Int32(2147483647).toString(), "2147483647");
+ expect(new Int32(2147483648).toString(), "-2147483648");
+ expect(new Int32(2147483649).toString(), "-2147483647");
+ expect(new Int32(2147483650).toString(), "-2147483646");
+ expect(new Int32(-2147483648).toString(), "-2147483648");
+ expect(new Int32(-2147483649).toString(), "2147483647");
+ expect(new Int32(-2147483650).toString(), "2147483646");
});
});
group("toHexString", () {
test("returns hexadecimal string representation", () {
- expect(new Int32.fromInt(-1).toHexString(), "-1");
- expect((new Int32.fromInt(-1) >> 8).toHexString(), "-1");
- expect((new Int32.fromInt(-1) << 8).toHexString(), "-100");
- expect(new Int32.fromInt(123456789).toHexString(), "75bcd15");
- expect(new Int32.fromInt(-1).shiftRightUnsigned(8).toHexString(),
- "ffffff");
+ expect(new Int32(-1).toHexString(), "-1");
+ expect((new Int32(-1) >> 8).toHexString(), "-1");
+ expect((new Int32(-1) << 8).toHexString(), "-100");
+ expect(new Int32(123456789).toHexString(), "75bcd15");
+ expect(new Int32(-1).shiftRightUnsigned(8).toHexString(), "ffffff");
});
});
group("toRadixString", () {
test("returns base n string representation", () {
- expect(new Int32.fromInt(123456789).toRadixString(5), "223101104124");
+ expect(new Int32(123456789).toRadixString(5), "223101104124");
});
});
}
diff --git a/pkg/fixnum/test/int_64_test.dart b/pkg/fixnum/test/int_64_test.dart
index 84323ee..891b8e7 100644
--- a/pkg/fixnum/test/int_64_test.dart
+++ b/pkg/fixnum/test/int_64_test.dart
@@ -7,46 +7,88 @@
import 'package:unittest/unittest.dart';
void main() {
+ group("is-tests", () {
+ test("isEven", () {
+ expect((-Int64.ONE).isEven, false);
+ expect(Int64.ZERO.isEven, true);
+ expect(Int64.ONE.isEven, false);
+ expect(Int64.TWO.isEven, true);
+ });
+ test("isMaxValue", () {
+ expect(Int64.MIN_VALUE.isMaxValue, false);
+ expect(Int64.ZERO.isMaxValue, false);
+ expect(Int64.MAX_VALUE.isMaxValue, true);
+ });
+ test("isMinValue", () {
+ expect(Int64.MIN_VALUE.isMinValue, true);
+ expect(Int64.ZERO.isMinValue, false);
+ expect(Int64.MAX_VALUE.isMinValue, false);
+ });
+ test("isNegative", () {
+ expect(Int64.MIN_VALUE.isNegative, true);
+ expect(Int64.ZERO.isNegative, false);
+ expect(Int64.ONE.isNegative, false);
+ });
+ test("isOdd", () {
+ expect((-Int64.ONE).isOdd, true);
+ expect(Int64.ZERO.isOdd, false);
+ expect(Int64.ONE.isOdd, true);
+ expect(Int64.TWO.isOdd, false);
+ });
+ test("isZero", () {
+ expect(Int64.MIN_VALUE.isZero, false);
+ expect(Int64.ZERO.isZero, true);
+ expect(Int64.MAX_VALUE.isZero, false);
+ });
+ test("bitLength", () {
+ expect(new Int64(-2).bitLength, 1);
+ expect((-Int64.ONE).bitLength, 0);
+ expect(Int64.ZERO.bitLength, 0);
+ expect((Int64.ONE << 21).bitLength, 22);
+ expect((Int64.ONE << 22).bitLength, 23);
+ expect((Int64.ONE << 43).bitLength, 44);
+ expect((Int64.ONE << 44).bitLength, 45);
+ expect(new Int64(2).bitLength, 2);
+ expect(Int64.MAX_VALUE.bitLength, 63);
+ expect(Int64.MIN_VALUE.bitLength, 63);
+ });
+ });
+
group("arithmetic operators", () {
- Int64 n1 = new Int64.fromInt(1234);
- Int64 n2 = new Int64.fromInt(9876);
- Int64 n3 = new Int64.fromInt(-1234);
- Int64 n4 = new Int64.fromInt(-9876);
+ Int64 n1 = new Int64(1234);
+ Int64 n2 = new Int64(9876);
+ Int64 n3 = new Int64(-1234);
+ Int64 n4 = new Int64(-9876);
Int64 n5 = new Int64.fromInts(0x12345678, 0xabcdabcd);
Int64 n6 = new Int64.fromInts(0x77773333, 0x22224444);
test("+", () {
- expect(n1 + n2, new Int64.fromInt(11110));
- expect(n3 + n2, new Int64.fromInt(8642));
- expect(n3 + n4, new Int64.fromInt(-11110));
+ expect(n1 + n2, new Int64(11110));
+ expect(n3 + n2, new Int64(8642));
+ expect(n3 + n4, new Int64(-11110));
expect(n5 + n6, new Int64.fromInts(0x89ab89ab, 0xcdeff011));
expect(Int64.MAX_VALUE + 1, Int64.MIN_VALUE);
});
test("-", () {
- expect(n1 - n2, new Int64.fromInt(-8642));
- expect(n3 - n2, new Int64.fromInt(-11110));
- expect(n3 - n4, new Int64.fromInt(8642));
+ expect(n1 - n2, new Int64(-8642));
+ expect(n3 - n2, new Int64(-11110));
+ expect(n3 - n4, new Int64(8642));
expect(n5 - n6, new Int64.fromInts(0x9abd2345, 0x89ab6789));
expect(Int64.MIN_VALUE - 1, Int64.MAX_VALUE);
});
test("unary -", () {
- expect(-n1, new Int64.fromInt(-1234));
+ expect(-n1, new Int64(-1234));
expect(-Int64.ZERO, Int64.ZERO);
});
test("*", () {
- expect(new Int64.fromInt(1111) * new Int64.fromInt(3),
- new Int64.fromInt(3333));
- expect(new Int64.fromInt(1111) * new Int64.fromInt(-3),
- new Int64.fromInt(-3333));
- expect(new Int64.fromInt(-1111) * new Int64.fromInt(3),
- new Int64.fromInt(-3333));
- expect(new Int64.fromInt(-1111) * new Int64.fromInt(-3),
- new Int64.fromInt(3333));
- expect(new Int64.fromInt(100) * Int64.ZERO,
- Int64.ZERO);
+ expect(new Int64(1111) * new Int64(3), new Int64(3333));
+ expect(new Int64(1111) * new Int64(-3), new Int64(-3333));
+ expect(new Int64(-1111) * new Int64(3), new Int64(-3333));
+ expect(new Int64(-1111) * new Int64(-3), new Int64(3333));
+ expect(new Int64(100) * Int64.ZERO, Int64.ZERO);
expect(new Int64.fromInts(0x12345678, 0x12345678) *
new Int64.fromInts(0x1234, 0x12345678),
@@ -59,45 +101,39 @@
new Int64.fromInts(0x297e3f7c, 0x1df4d840));
// RHS Int32
- expect((new Int64.fromInt(123456789) * new Int32.fromInt(987654321)),
+ expect((new Int64(123456789) * new Int32(987654321)),
new Int64.fromInts(0x1b13114, 0xfbff5385));
- expect((new Int64.fromInt(123456789) * new Int32.fromInt(987654321)),
+ expect((new Int64(123456789) * new Int32(987654321)),
new Int64.fromInts(0x1b13114, 0xfbff5385));
// Wraparound
- expect((new Int64.fromInt(123456789) * new Int64.fromInt(987654321)),
+ expect((new Int64(123456789) * new Int64(987654321)),
new Int64.fromInts(0x1b13114, 0xfbff5385));
- expect(Int64.MIN_VALUE * new Int64.fromInt(2), Int64.ZERO);
- expect(Int64.MIN_VALUE * new Int64.fromInt(1), Int64.MIN_VALUE);
- expect(Int64.MIN_VALUE * new Int64.fromInt(-1), Int64.MIN_VALUE);
+ expect(Int64.MIN_VALUE * new Int64(2), Int64.ZERO);
+ expect(Int64.MIN_VALUE * new Int64(1), Int64.MIN_VALUE);
+ expect(Int64.MIN_VALUE * new Int64(-1), Int64.MIN_VALUE);
});
test("~/", () {
Int64 deadBeef = new Int64.fromInts(0xDEADBEEF, 0xDEADBEEF);
- Int64 ten = new Int64.fromInt(10);
+ Int64 ten = new Int64(10);
expect(deadBeef ~/ ten, new Int64.fromInts(0xfcaaf97e, 0x63115fe5));
expect(Int64.ONE ~/ Int64.TWO, Int64.ZERO);
expect(Int64.MAX_VALUE ~/ Int64.TWO,
new Int64.fromInts(0x3fffffff, 0xffffffff));
- expect(Int64.ZERO ~/ new Int64.fromInt(1000), Int64.ZERO);
+ expect(Int64.ZERO ~/ new Int64(1000), Int64.ZERO);
expect(Int64.MIN_VALUE ~/ Int64.MIN_VALUE, Int64.ONE);
- expect(new Int64.fromInt(1000) ~/ Int64.MIN_VALUE, Int64.ZERO);
- expect(Int64.MIN_VALUE ~/ new Int64.fromInt(8192),
- new Int64.fromInt(-1125899906842624));
- expect(Int64.MIN_VALUE ~/ new Int64.fromInt(8193),
- new Int64.fromInt(-1125762484664320));
- expect(new Int64.fromInt(-1000) ~/ new Int64.fromInt(8192), Int64.ZERO);
- expect(new Int64.fromInt(-1000) ~/ new Int64.fromInt(8193), Int64.ZERO);
- expect(new Int64.fromInt(-1000000000) ~/ new Int64.fromInt(8192),
- new Int64.fromInt(-122070));
- expect(new Int64.fromInt(-1000000000) ~/ new Int64.fromInt(8193),
- new Int64.fromInt(-122055));
- expect(new Int64.fromInt(1000000000) ~/ new Int64.fromInt(8192),
- new Int64.fromInt(122070));
- expect(new Int64.fromInt(1000000000) ~/ new Int64.fromInt(8193),
- new Int64.fromInt(122055));
+ expect(new Int64(1000) ~/ Int64.MIN_VALUE, Int64.ZERO);
+ expect(Int64.MIN_VALUE ~/ new Int64(8192), new Int64(-1125899906842624));
+ expect(Int64.MIN_VALUE ~/ new Int64(8193), new Int64(-1125762484664320));
+ expect(new Int64(-1000) ~/ new Int64(8192), Int64.ZERO);
+ expect(new Int64(-1000) ~/ new Int64(8193), Int64.ZERO);
+ expect(new Int64(-1000000000) ~/ new Int64(8192), new Int64(-122070));
+ expect(new Int64(-1000000000) ~/ new Int64(8193), new Int64(-122055));
+ expect(new Int64(1000000000) ~/ new Int64(8192), new Int64(122070));
+ expect(new Int64(1000000000) ~/ new Int64(8193), new Int64(122055));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00000000, 0x00000400),
new Int64.fromInts(0x1fffff, 0xffffffff));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00000000, 0x00040000),
@@ -105,35 +141,28 @@
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00000000, 0x04000000),
new Int64.fromInts(0x1f, 0xffffffff));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00000004, 0x00000000),
- new Int64.fromInt(536870911));
+ new Int64(536870911));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00000400, 0x00000000),
- new Int64.fromInt(2097151));
+ new Int64(2097151));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00040000, 0x00000000),
- new Int64.fromInt(8191));
+ new Int64(8191));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x04000000, 0x00000000),
- new Int64.fromInt(31));
+ new Int64(31));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00000000, 0x00000300),
new Int64.fromInts(0x2AAAAA, 0xAAAAAAAA));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00000000, 0x30000000),
new Int64.fromInts(0x2, 0xAAAAAAAA));
expect(Int64.MAX_VALUE ~/ new Int64.fromInts(0x00300000, 0x00000000),
- new Int64.fromInt(0x2AA));
- expect(Int64.MAX_VALUE ~/ new Int64.fromInt(0x123456),
+ new Int64(0x2AA));
+ expect(Int64.MAX_VALUE ~/ new Int64(0x123456),
new Int64.fromInts(0x708, 0x002E9501));
- expect(Int64.MAX_VALUE % new Int64.fromInt(0x123456),
- new Int64.fromInt(0x3BDA9));
- expect(new Int64.fromInt(5) ~/ new Int64.fromInt(5),
- new Int64.fromInt(1));
- expect(new Int64.fromInt(1000) ~/ new Int64.fromInt(3),
- new Int64.fromInt(333));
- expect(new Int64.fromInt(1000) ~/ new Int64.fromInt(-3),
- new Int64.fromInt(-333));
- expect(new Int64.fromInt(-1000) ~/ new Int64.fromInt(3),
- new Int64.fromInt(-333));
- expect(new Int64.fromInt(-1000) ~/ new Int64.fromInt(-3),
- new Int64.fromInt(333));
- expect(new Int64.fromInt(3) ~/ new Int64.fromInt(1000),
- Int64.ZERO);
+ expect(Int64.MAX_VALUE % new Int64(0x123456), new Int64(0x3BDA9));
+ expect(new Int64(5) ~/ new Int64(5), Int64.ONE);
+ expect(new Int64(1000) ~/ new Int64(3), new Int64(333));
+ expect(new Int64(1000) ~/ new Int64(-3), new Int64(-333));
+ expect(new Int64(-1000) ~/ new Int64(3), new Int64(-333));
+ expect(new Int64(-1000) ~/ new Int64(-3), new Int64(333));
+ expect(new Int64(3) ~/ new Int64(1000), Int64.ZERO);
expect(new Int64.fromInts( 0x12345678, 0x12345678) ~/
new Int64.fromInts(0x0, 0x123),
new Int64.fromInts(0x1003d0, 0xe84f5ae8));
@@ -146,43 +175,32 @@
expect(new Int64.fromInts(0xf2345678, 0x12345678) ~/
new Int64.fromInts(0xffff1234, 0x12345678),
new Int64.fromInts(0x0, 0xeda));
- expect(new Int64.fromInt(829893893) ~/ new Int32.fromInt(1919),
- new Int32.fromInt(432461));
- expect(new Int64.fromInt(829893893) ~/ new Int64.fromInt(1919),
- new Int32.fromInt(432461));
- expect(new Int64.fromInt(829893893) ~/ 1919,
- new Int32.fromInt(432461));
- expect(() => new Int64.fromInt(1) ~/ Int64.ZERO,
+ expect(new Int64(829893893) ~/ new Int32(1919), new Int32(432461));
+ expect(new Int64(829893893) ~/ new Int64(1919), new Int32(432461));
+ expect(new Int64(829893893) ~/ 1919, new Int32(432461));
+ expect(() => new Int64(1) ~/ Int64.ZERO,
throwsA(new isInstanceOf<IntegerDivisionByZeroException>()));
- expect(Int64.MIN_VALUE ~/ new Int64.fromInt(2),
+ expect(Int64.MIN_VALUE ~/ new Int64(2),
new Int64.fromInts(0xc0000000, 0x00000000));
- expect(Int64.MIN_VALUE ~/ new Int64.fromInt(1), Int64.MIN_VALUE);
- expect(Int64.MIN_VALUE ~/ new Int64.fromInt(-1), Int64.MIN_VALUE);
- expect(() => new Int64.fromInt(17) ~/ Int64.ZERO, throws);
- expect(() => new Int64.fromInt(17) ~/ null, throwsArgumentError);
+ expect(Int64.MIN_VALUE ~/ new Int64(1), Int64.MIN_VALUE);
+ expect(Int64.MIN_VALUE ~/ new Int64(-1), Int64.MIN_VALUE);
+ expect(() => new Int64(17) ~/ Int64.ZERO, throws);
+ expect(() => new Int64(17) ~/ null, throwsArgumentError);
});
test("%", () {
// Define % as Euclidean mod, with positive result for all arguments
- expect(Int64.ZERO % new Int64.fromInt(1000), Int64.ZERO);
+ expect(Int64.ZERO % new Int64(1000), Int64.ZERO);
expect(Int64.MIN_VALUE % Int64.MIN_VALUE, Int64.ZERO);
- expect(new Int64.fromInt(1000) % Int64.MIN_VALUE,
- new Int64.fromInt(1000));
- expect(Int64.MIN_VALUE % new Int64.fromInt(8192), Int64.ZERO);
- expect(Int64.MIN_VALUE % new Int64.fromInt(8193),
- new Int64.fromInt(6145));
- expect(new Int64.fromInt(-1000) % new Int64.fromInt(8192),
- new Int64.fromInt(7192));
- expect(new Int64.fromInt(-1000) % new Int64.fromInt(8193),
- new Int64.fromInt(7193));
- expect(new Int64.fromInt(-1000000000) % new Int64.fromInt(8192),
- new Int64.fromInt(5632));
- expect(new Int64.fromInt(-1000000000) % new Int64.fromInt(8193),
- new Int64.fromInt(4808));
- expect(new Int64.fromInt(1000000000) % new Int64.fromInt(8192),
- new Int64.fromInt(2560));
- expect(new Int64.fromInt(1000000000) % new Int64.fromInt(8193),
- new Int64.fromInt(3385));
+ expect(new Int64(1000) % Int64.MIN_VALUE, new Int64(1000));
+ expect(Int64.MIN_VALUE % new Int64(8192), Int64.ZERO);
+ expect(Int64.MIN_VALUE % new Int64(8193), new Int64(6145));
+ expect(new Int64(-1000) % new Int64(8192), new Int64(7192));
+ expect(new Int64(-1000) % new Int64(8193), new Int64(7193));
+ expect(new Int64(-1000000000) % new Int64(8192), new Int64(5632));
+ expect(new Int64(-1000000000) % new Int64(8193), new Int64(4808));
+ expect(new Int64(1000000000) % new Int64(8192), new Int64(2560));
+ expect(new Int64(1000000000) % new Int64(8193), new Int64(3385));
expect(Int64.MAX_VALUE % new Int64.fromInts(0x00000000, 0x00000400),
new Int64.fromInts(0x0, 0x3ff));
expect(Int64.MAX_VALUE % new Int64.fromInts(0x00000000, 0x00040000),
@@ -197,32 +215,52 @@
new Int64.fromInts(0x3ffff, 0xffffffff));
expect(Int64.MAX_VALUE % new Int64.fromInts(0x04000000, 0x00000000),
new Int64.fromInts(0x3ffffff, 0xffffffff));
- expect(new Int64.fromInt(0x12345678).remainder(new Int64.fromInt(0x22)),
- new Int64.fromInt(0x12345678.remainder(0x22)));
- expect(new Int64.fromInt(0x12345678).remainder(new Int64.fromInt(-0x22)),
- new Int64.fromInt(0x12345678.remainder(-0x22)));
- expect(new Int64.fromInt(-0x12345678).remainder(new Int64.fromInt(-0x22)),
- new Int64.fromInt(-0x12345678.remainder(-0x22)));
- expect(new Int64.fromInt(-0x12345678).remainder(new Int64.fromInt(0x22)),
- new Int64.fromInt(-0x12345678.remainder(0x22)));
- expect(new Int32.fromInt(0x12345678).remainder(new Int64.fromInt(0x22)),
- new Int64.fromInt(0x12345678.remainder(0x22)));
+ expect(new Int64(0x12345678).remainder(new Int64(0x22)),
+ new Int64(0x12345678.remainder(0x22)));
+ expect(new Int64(0x12345678).remainder(new Int64(-0x22)),
+ new Int64(0x12345678.remainder(-0x22)));
+ expect(new Int64(-0x12345678).remainder(new Int64(-0x22)),
+ new Int64(-0x12345678.remainder(-0x22)));
+ expect(new Int64(-0x12345678).remainder(new Int64(0x22)),
+ new Int64(-0x12345678.remainder(0x22)));
+ expect(new Int32(0x12345678).remainder(new Int64(0x22)),
+ new Int64(0x12345678.remainder(0x22)));
+ });
+
+ test("clamp", () {
+ Int64 val = new Int64(17);
+ expect(val.clamp(20, 30), new Int64(20));
+ expect(val.clamp(10, 20), new Int64(17));
+ expect(val.clamp(10, 15), new Int64(15));
+
+ expect(val.clamp(new Int32(20), new Int32(30)), new Int64(20));
+ expect(val.clamp(new Int32(10), new Int32(20)), new Int64(17));
+ expect(val.clamp(new Int32(10), new Int32(15)), new Int64(15));
+
+ expect(val.clamp(new Int64(20), new Int64(30)), new Int64(20));
+ expect(val.clamp(new Int64(10), new Int64(20)), new Int64(17));
+ expect(val.clamp(new Int64(10), new Int64(15)), new Int64(15));
+ expect(val.clamp(Int64.MIN_VALUE, new Int64(30)), new Int64(17));
+ expect(val.clamp(new Int64(10), Int64.MAX_VALUE), new Int64(17));
+
+ expect(() => val.clamp(1, 'b'), throwsA(isArgumentError));
+ expect(() => val.clamp('a', 1), throwsA(isArgumentError));
});
});
group("comparison operators", () {
Int64 largeNeg = new Int64.fromInts(0x82341234, 0x0);
Int64 largePos = new Int64.fromInts(0x12341234, 0x0);
- Int64 largePosPlusOne = largePos + new Int64.fromInt(1);
+ Int64 largePosPlusOne = largePos + new Int64(1);
test("<", () {
- expect(new Int64.fromInt(10) < new Int64.fromInt(11), true);
- expect(new Int64.fromInt(10) < new Int64.fromInt(10), false);
- expect(new Int64.fromInt(10) < new Int64.fromInt(9), false);
- expect(new Int64.fromInt(10) < new Int32.fromInt(11), true);
- expect(new Int64.fromInt(10) < new Int32.fromInt(10), false);
- expect(new Int64.fromInt(10) < new Int32.fromInt(9), false);
- expect(new Int64.fromInt(-10) < new Int64.fromInt(-11), false);
+ expect(new Int64(10) < new Int64(11), true);
+ expect(new Int64(10) < new Int64(10), false);
+ expect(new Int64(10) < new Int64(9), false);
+ expect(new Int64(10) < new Int32(11), true);
+ expect(new Int64(10) < new Int32(10), false);
+ expect(new Int64(10) < new Int32(9), false);
+ expect(new Int64(-10) < new Int64(-11), false);
expect(Int64.MIN_VALUE < Int64.ZERO, true);
expect(largeNeg < largePos, true);
expect(largePos < largePosPlusOne, true);
@@ -230,18 +268,18 @@
expect(largePosPlusOne < largePos, false);
expect(Int64.MIN_VALUE < Int64.MAX_VALUE, true);
expect(Int64.MAX_VALUE < Int64.MIN_VALUE, false);
- expect(() => new Int64.fromInt(17) < null, throwsArgumentError);
+ expect(() => new Int64(17) < null, throwsArgumentError);
});
test("<=", () {
- expect(new Int64.fromInt(10) <= new Int64.fromInt(11), true);
- expect(new Int64.fromInt(10) <= new Int64.fromInt(10), true);
- expect(new Int64.fromInt(10) <= new Int64.fromInt(9), false);
- expect(new Int64.fromInt(10) <= new Int32.fromInt(11), true);
- expect(new Int64.fromInt(10) <= new Int32.fromInt(10), true);
- expect(new Int64.fromInt(10) <= new Int64.fromInt(9), false);
- expect(new Int64.fromInt(-10) <= new Int64.fromInt(-11), false);
- expect(new Int64.fromInt(-10) <= new Int64.fromInt(-10), true);
+ expect(new Int64(10) <= new Int64(11), true);
+ expect(new Int64(10) <= new Int64(10), true);
+ expect(new Int64(10) <= new Int64(9), false);
+ expect(new Int64(10) <= new Int32(11), true);
+ expect(new Int64(10) <= new Int32(10), true);
+ expect(new Int64(10) <= new Int64(9), false);
+ expect(new Int64(-10) <= new Int64(-11), false);
+ expect(new Int64(-10) <= new Int64(-10), true);
expect(largeNeg <= largePos, true);
expect(largePos <= largeNeg, false);
expect(largePos <= largePosPlusOne, true);
@@ -249,35 +287,35 @@
expect(largePosPlusOne <= largePos, false);
expect(Int64.MIN_VALUE <= Int64.MAX_VALUE, true);
expect(Int64.MAX_VALUE <= Int64.MIN_VALUE, false);
- expect(() => new Int64.fromInt(17) <= null, throwsArgumentError);
+ expect(() => new Int64(17) <= null, throwsArgumentError);
});
test("==", () {
- expect(new Int64.fromInt(10) == new Int64.fromInt(11), false);
- expect(new Int64.fromInt(10) == new Int64.fromInt(10), true);
- expect(new Int64.fromInt(10) == new Int64.fromInt(9), false);
- expect(new Int64.fromInt(10) == new Int32.fromInt(11), false);
- expect(new Int64.fromInt(10) == new Int32.fromInt(10), true);
- expect(new Int64.fromInt(10) == new Int32.fromInt(9), false);
- expect(new Int64.fromInt(-10) == new Int64.fromInt(-10), true);
- expect(new Int64.fromInt(-10) != new Int64.fromInt(-10), false);
+ expect(new Int64(10) == new Int64(11), false);
+ expect(new Int64(10) == new Int64(10), true);
+ expect(new Int64(10) == new Int64(9), false);
+ expect(new Int64(10) == new Int32(11), false);
+ expect(new Int64(10) == new Int32(10), true);
+ expect(new Int64(10) == new Int32(9), false);
+ expect(new Int64(-10) == new Int64(-10), true);
+ expect(new Int64(-10) != new Int64(-10), false);
expect(largePos == largePos, true);
expect(largePos == largePosPlusOne, false);
expect(largePosPlusOne == largePos, false);
expect(Int64.MIN_VALUE == Int64.MAX_VALUE, false);
- expect(new Int64.fromInt(17) == new Object(), false);
- expect(new Int64.fromInt(17) == null, false);
+ expect(new Int64(17) == new Object(), false);
+ expect(new Int64(17) == null, false);
});
test(">=", () {
- expect(new Int64.fromInt(10) >= new Int64.fromInt(11), false);
- expect(new Int64.fromInt(10) >= new Int64.fromInt(10), true);
- expect(new Int64.fromInt(10) >= new Int64.fromInt(9), true);
- expect(new Int64.fromInt(10) >= new Int32.fromInt(11), false);
- expect(new Int64.fromInt(10) >= new Int32.fromInt(10), true);
- expect(new Int64.fromInt(10) >= new Int32.fromInt(9), true);
- expect(new Int64.fromInt(-10) >= new Int64.fromInt(-11), true);
- expect(new Int64.fromInt(-10) >= new Int64.fromInt(-10), true);
+ expect(new Int64(10) >= new Int64(11), false);
+ expect(new Int64(10) >= new Int64(10), true);
+ expect(new Int64(10) >= new Int64(9), true);
+ expect(new Int64(10) >= new Int32(11), false);
+ expect(new Int64(10) >= new Int32(10), true);
+ expect(new Int64(10) >= new Int32(9), true);
+ expect(new Int64(-10) >= new Int64(-11), true);
+ expect(new Int64(-10) >= new Int64(-10), true);
expect(largePos >= largeNeg, true);
expect(largeNeg >= largePos, false);
expect(largePos >= largePosPlusOne, false);
@@ -285,19 +323,19 @@
expect(largePosPlusOne >= largePos, true);
expect(Int64.MIN_VALUE >= Int64.MAX_VALUE, false);
expect(Int64.MAX_VALUE >= Int64.MIN_VALUE, true);
- expect(() => new Int64.fromInt(17) >= null, throwsArgumentError);
+ expect(() => new Int64(17) >= null, throwsArgumentError);
});
test(">", () {
- expect(new Int64.fromInt(10) > new Int64.fromInt(11), false);
- expect(new Int64.fromInt(10) > new Int64.fromInt(10), false);
- expect(new Int64.fromInt(10) > new Int64.fromInt(9), true);
- expect(new Int64.fromInt(10) > new Int32.fromInt(11), false);
- expect(new Int64.fromInt(10) > new Int32.fromInt(10), false);
- expect(new Int64.fromInt(10) > new Int32.fromInt(9), true);
- expect(new Int64.fromInt(-10) > new Int64.fromInt(-11), true);
- expect(new Int64.fromInt(10) > new Int64.fromInt(-11), true);
- expect(new Int64.fromInt(-10) > new Int64.fromInt(11), false);
+ expect(new Int64(10) > new Int64(11), false);
+ expect(new Int64(10) > new Int64(10), false);
+ expect(new Int64(10) > new Int64(9), true);
+ expect(new Int64(10) > new Int32(11), false);
+ expect(new Int64(10) > new Int32(10), false);
+ expect(new Int64(10) > new Int32(9), true);
+ expect(new Int64(-10) > new Int64(-11), true);
+ expect(new Int64(10) > new Int64(-11), true);
+ expect(new Int64(-10) > new Int64(11), false);
expect(largePos > largeNeg, true);
expect(largeNeg > largePos, false);
expect(largePos > largePosPlusOne, false);
@@ -306,46 +344,46 @@
expect(Int64.ZERO > Int64.MIN_VALUE, true);
expect(Int64.MIN_VALUE > Int64.MAX_VALUE, false);
expect(Int64.MAX_VALUE > Int64.MIN_VALUE, true);
- expect(() => new Int64.fromInt(17) > null, throwsArgumentError);
+ expect(() => new Int64(17) > null, throwsArgumentError);
});
});
group("bitwise operators", () {
- Int64 n1 = new Int64.fromInt(1234);
- Int64 n2 = new Int64.fromInt(9876);
- Int64 n3 = new Int64.fromInt(-1234);
- Int64 n4 = new Int64.fromInt(0x1234) << 32;
- Int64 n5 = new Int64.fromInt(0x9876) << 32;
+ Int64 n1 = new Int64(1234);
+ Int64 n2 = new Int64(9876);
+ Int64 n3 = new Int64(-1234);
+ Int64 n4 = new Int64(0x1234) << 32;
+ Int64 n5 = new Int64(0x9876) << 32;
test("&", () {
- expect(n1 & n2, new Int64.fromInt(1168));
- expect(n3 & n2, new Int64.fromInt(8708));
- expect(n4 & n5, new Int64.fromInt(0x1034) << 32);
+ expect(n1 & n2, new Int64(1168));
+ expect(n3 & n2, new Int64(8708));
+ expect(n4 & n5, new Int64(0x1034) << 32);
expect(() => n1 & null, throwsArgumentError);
});
test("|", () {
- expect(n1 | n2, new Int64.fromInt(9942));
- expect(n3 | n2, new Int64.fromInt(-66));
- expect(n4 | n5, new Int64.fromInt(0x9a76) << 32);
+ expect(n1 | n2, new Int64(9942));
+ expect(n3 | n2, new Int64(-66));
+ expect(n4 | n5, new Int64(0x9a76) << 32);
expect(() => n1 | null, throwsArgumentError);
});
test("^", () {
- expect(n1 ^ n2, new Int64.fromInt(8774));
- expect(n3 ^ n2, new Int64.fromInt(-8774));
- expect(n4 ^ n5, new Int64.fromInt(0x8a42) << 32);
+ expect(n1 ^ n2, new Int64(8774));
+ expect(n3 ^ n2, new Int64(-8774));
+ expect(n4 ^ n5, new Int64(0x8a42) << 32);
expect(() => n1 ^ null, throwsArgumentError);
});
test("~", () {
- expect(-new Int64.fromInt(1), new Int64.fromInt(-1));
- expect(-new Int64.fromInt(-1), new Int64.fromInt(1));
+ expect(-new Int64(1), new Int64(-1));
+ expect(-new Int64(-1), new Int64(1));
expect(-Int64.MIN_VALUE, Int64.MIN_VALUE);
- expect(~n1, new Int64.fromInt(-1235));
- expect(~n2, new Int64.fromInt(-9877));
- expect(~n3, new Int64.fromInt(1233));
+ expect(~n1, new Int64(-1235));
+ expect(~n2, new Int64(-9877));
+ expect(~n3, new Int64(1233));
expect(~n4, new Int64.fromInts(0xffffedcb, 0xffffffff));
expect(~n5, new Int64.fromInts(0xffff6789, 0xffffffff));
});
@@ -357,10 +395,10 @@
new Int64.fromInts(0xd048d115, 0x9d159c00));
expect(new Int64.fromInts(0x92341234, 0x45674567) << 10,
new Int64.fromInts(0xd048d115, 0x9d159c00));
- expect(new Int64.fromInt(-1) << 5, new Int64.fromInt(-32));
- expect(new Int64.fromInt(-1) << 0, new Int64.fromInt(-1));
- expect(() => new Int64.fromInt(17) << -1, throwsArgumentError);
- expect(() => new Int64.fromInt(17) << null, throws);
+ expect(new Int64(-1) << 5, new Int64(-32));
+ expect(new Int64(-1) << 0, new Int64(-1));
+ expect(() => new Int64(17) << -1, throwsArgumentError);
+ expect(() => new Int64(17) << null, throws);
});
test(">>", () {
@@ -370,9 +408,9 @@
expect(new Int64.fromInts(0x92341234, 0x45674567) >> 10,
new Int64.fromInts(0xffe48d04, 0x8d1159d1));
expect(new Int64.fromInts(0xFFFFFFF, 0xFFFFFFFF) >> 34,
- new Int64.fromInt(67108863));
+ new Int64(67108863));
for (int n = 0; n <= 66; n++) {
- expect(new Int64.fromInt(-1) >> n, new Int64.fromInt(-1));
+ expect(new Int64(-1) >> n, new Int64(-1));
}
expect(new Int64.fromInts(0x72345678, 0x9abcdef0) >> 8,
new Int64.fromInts(0x00723456, 0x789abcde));
@@ -410,8 +448,8 @@
new Int64.fromInts(0xffffffff, 0xfff92345));
expect(new Int64.fromInts(0x92345678, 0x9abcdef0) >> 48,
new Int64.fromInts(0xffffffff, 0xffff9234));
- expect(() => new Int64.fromInt(17) >> -1, throwsArgumentError);
- expect(() => new Int64.fromInt(17) >> null, throws);
+ expect(() => new Int64(17) >> -1, throwsArgumentError);
+ expect(() => new Int64(17) >> null, throws);
});
test("shiftRightUnsigned", () {
@@ -455,17 +493,17 @@
new Int64.fromInts(0x00000000, 0x00092345));
expect(new Int64.fromInts(0x00000000, 0x00009234),
new Int64.fromInts(0x92345678, 0x9abcdef0).shiftRightUnsigned(48));
- expect(() => new Int64.fromInt(17).shiftRightUnsigned(-1),
+ expect(() => new Int64(17).shiftRightUnsigned(-1),
throwsArgumentError);
- expect(() => new Int64.fromInt(17).shiftRightUnsigned(null), throws);
+ expect(() => new Int64(17).shiftRightUnsigned(null), throws);
});
test("overflow", () {
- expect((new Int64.fromInt(1) << 63) >> 1,
+ expect((new Int64(1) << 63) >> 1,
-new Int64.fromInts(0x40000000, 0x00000000));
- expect((new Int64.fromInt(-1) << 32) << 32, new Int64.fromInt(0));
+ expect((new Int64(-1) << 32) << 32, new Int64(0));
expect(Int64.MIN_VALUE << 0, Int64.MIN_VALUE);
- expect(Int64.MIN_VALUE << 1, new Int64.fromInt(0));
+ expect(Int64.MIN_VALUE << 1, new Int64(0));
expect((-new Int64.fromInts(8, 0)) >> 1,
new Int64.fromInts(0xfffffffc, 0x00000000));
expect((-new Int64.fromInts(8, 0)).shiftRightUnsigned(1),
@@ -473,66 +511,138 @@
});
});
- group("type conversions", () {
+ group("conversions", () {
+ test("toSigned", () {
+ expect((Int64.ONE << 44).toSigned(46), Int64.ONE << 44);
+ expect((Int64.ONE << 44).toSigned(45), -(Int64.ONE << 44));
+ expect((Int64.ONE << 22).toSigned(24), Int64.ONE << 22);
+ expect((Int64.ONE << 22).toSigned(23), -(Int64.ONE << 22));
+ expect(Int64.ONE.toSigned(2), Int64.ONE);
+ expect(Int64.ONE.toSigned(1), -Int64.ONE);
+ expect(Int64.MAX_VALUE.toSigned(64), Int64.MAX_VALUE);
+ expect(Int64.MIN_VALUE.toSigned(64), Int64.MIN_VALUE);
+ expect(Int64.MAX_VALUE.toSigned(63), -Int64.ONE);
+ expect(Int64.MIN_VALUE.toSigned(63), Int64.ZERO);
+ expect(() => Int64.ONE.toSigned(0), throws);
+ expect(() => Int64.ONE.toSigned(65), throws);
+ });
+ test("toUnsigned", () {
+ expect((Int64.ONE << 44).toUnsigned(45), Int64.ONE << 44);
+ expect((Int64.ONE << 44).toUnsigned(44), Int64.ZERO);
+ expect((Int64.ONE << 22).toUnsigned(23), Int64.ONE << 22);
+ expect((Int64.ONE << 22).toUnsigned(22), Int64.ZERO);
+ expect(Int64.ONE.toUnsigned(1), Int64.ONE);
+ expect(Int64.ONE.toUnsigned(0), Int64.ZERO);
+ expect(Int64.MAX_VALUE.toUnsigned(64), Int64.MAX_VALUE);
+ expect(Int64.MIN_VALUE.toUnsigned(64), Int64.MIN_VALUE);
+ expect(Int64.MAX_VALUE.toUnsigned(63), Int64.MAX_VALUE);
+ expect(Int64.MIN_VALUE.toUnsigned(63), Int64.ZERO);
+ expect(() => Int64.ONE.toUnsigned(-1), throws);
+ expect(() => Int64.ONE.toUnsigned(65), throws);
+ });
+ test("toDouble", () {
+ expect(new Int64(0).toDouble(), same(0.0));
+ expect(new Int64(100).toDouble(), same(100.0));
+ expect(new Int64(-100).toDouble(), same(-100.0));
+ expect(new Int64(2147483647).toDouble(), same(2147483647.0));
+ expect(new Int64(2147483648).toDouble(), same(2147483648.0));
+ expect(new Int64(-2147483647).toDouble(), same(-2147483647.0));
+ expect(new Int64(-2147483648).toDouble(), same(-2147483648.0));
+ expect(new Int64(4503599627370495).toDouble(), same(4503599627370495.0));
+ expect(new Int64(4503599627370496).toDouble(), same(4503599627370496.0));
+ expect(new Int64(-4503599627370495).toDouble(),
+ same(-4503599627370495.0));
+ expect(new Int64(-4503599627370496).toDouble(),
+ same(-4503599627370496.0));
+ expect(Int64.parseInt("-10000000000000000").toDouble().toStringAsFixed(1),
+ "-10000000000000000.0");
+ expect(Int64.parseInt("-10000000000000001").toDouble().toStringAsFixed(1),
+ "-10000000000000000.0");
+ expect(Int64.parseInt("-10000000000000002").toDouble().toStringAsFixed(1),
+ "-10000000000000002.0");
+ expect(Int64.parseInt("-10000000000000003").toDouble().toStringAsFixed(1),
+ "-10000000000000004.0");
+ expect(Int64.parseInt("-10000000000000004").toDouble().toStringAsFixed(1),
+ "-10000000000000004.0");
+ expect(Int64.parseInt("-10000000000000005").toDouble().toStringAsFixed(1),
+ "-10000000000000004.0");
+ expect(Int64.parseInt("-10000000000000006").toDouble().toStringAsFixed(1),
+ "-10000000000000006.0");
+ expect(Int64.parseInt("-10000000000000007").toDouble().toStringAsFixed(1),
+ "-10000000000000008.0");
+ expect(Int64.parseInt("-10000000000000008").toDouble().toStringAsFixed(1),
+ "-10000000000000008.0");
+ });
+
test("toInt", () {
- expect(new Int64.fromInt(0).toInt(), 0);
- expect(new Int64.fromInt(100).toInt(), 100);
- expect(new Int64.fromInt(-100).toInt(), -100);
- expect(new Int64.fromInt(2147483647).toInt(), 2147483647);
- expect(new Int64.fromInt(2147483648).toInt(), 2147483648);
- expect(new Int64.fromInt(-2147483647).toInt(), -2147483647);
- expect(new Int64.fromInt(-2147483648).toInt(), -2147483648);
- expect(new Int64.fromInt(4503599627370495).toInt(), 4503599627370495);
- expect(new Int64.fromInt(4503599627370496).toInt(), 4503599627370496);
- expect(new Int64.fromInt(-4503599627370495).toInt(), -4503599627370495);
- expect(new Int64.fromInt(-4503599627370496).toInt(), -4503599627370496);
+ expect(new Int64(0).toInt(), 0);
+ expect(new Int64(100).toInt(), 100);
+ expect(new Int64(-100).toInt(), -100);
+ expect(new Int64(2147483647).toInt(), 2147483647);
+ expect(new Int64(2147483648).toInt(), 2147483648);
+ expect(new Int64(-2147483647).toInt(), -2147483647);
+ expect(new Int64(-2147483648).toInt(), -2147483648);
+ expect(new Int64(4503599627370495).toInt(), 4503599627370495);
+ expect(new Int64(4503599627370496).toInt(), 4503599627370496);
+ expect(new Int64(-4503599627370495).toInt(), -4503599627370495);
+ expect(new Int64(-4503599627370496).toInt(), -4503599627370496);
+ expect(Int64.parseInt("-10000000000000000").toInt(),
+ same(-10000000000000000));
+ expect(Int64.parseInt("-10000000000000001").toInt(),
+ same(-10000000000000001));
+ expect(Int64.parseInt("-10000000000000002").toInt(),
+ same(-10000000000000002));
+ expect(Int64.parseInt("-10000000000000003").toInt(),
+ same(-10000000000000003));
+ expect(Int64.parseInt("-10000000000000004").toInt(),
+ same(-10000000000000004));
+ expect(Int64.parseInt("-10000000000000005").toInt(),
+ same(-10000000000000005));
+ expect(Int64.parseInt("-10000000000000006").toInt(),
+ same(-10000000000000006));
+ expect(Int64.parseInt("-10000000000000007").toInt(),
+ same(-10000000000000007));
+ expect(Int64.parseInt("-10000000000000008").toInt(),
+ same(-10000000000000008));
});
test("toInt32", () {
- expect(new Int64.fromInt(0).toInt32(), new Int32.fromInt(0));
- expect(new Int64.fromInt(1).toInt32(), new Int32.fromInt(1));
- expect(new Int64.fromInt(-1).toInt32(), new Int32.fromInt(-1));
- expect(new Int64.fromInt(2147483647).toInt32(),
- new Int32.fromInt(2147483647));
- expect(new Int64.fromInt(2147483648).toInt32(),
- new Int32.fromInt(-2147483648));
- expect(new Int64.fromInt(2147483649).toInt32(),
- new Int32.fromInt(-2147483647));
- expect(new Int64.fromInt(2147483650).toInt32(),
- new Int32.fromInt(-2147483646));
- expect(new Int64.fromInt(-2147483648).toInt32(),
- new Int32.fromInt(-2147483648));
- expect(new Int64.fromInt(-2147483649).toInt32(),
- new Int32.fromInt(2147483647));
- expect(new Int64.fromInt(-2147483650).toInt32(),
- new Int32.fromInt(2147483646));
- expect(new Int64.fromInt(-2147483651).toInt32(),
- new Int32.fromInt(2147483645));
+ expect(new Int64(0).toInt32(), new Int32(0));
+ expect(new Int64(1).toInt32(), new Int32(1));
+ expect(new Int64(-1).toInt32(), new Int32(-1));
+ expect(new Int64(2147483647).toInt32(), new Int32(2147483647));
+ expect(new Int64(2147483648).toInt32(), new Int32(-2147483648));
+ expect(new Int64(2147483649).toInt32(), new Int32(-2147483647));
+ expect(new Int64(2147483650).toInt32(), new Int32(-2147483646));
+ expect(new Int64(-2147483648).toInt32(), new Int32(-2147483648));
+ expect(new Int64(-2147483649).toInt32(), new Int32(2147483647));
+ expect(new Int64(-2147483650).toInt32(), new Int32(2147483646));
+ expect(new Int64(-2147483651).toInt32(), new Int32(2147483645));
});
});
test("JavaScript 53-bit integer boundary", () {
Int64 _factorial(Int64 n) {
if (n.isZero) {
- return new Int64.fromInt(1);
+ return new Int64(1);
} else {
- return n * _factorial(n - new Int64.fromInt(1));
+ return n * _factorial(n - new Int64(1));
}
}
- Int64 fact18 = _factorial(new Int64.fromInt(18));
- Int64 fact17 = _factorial(new Int64.fromInt(17));
- expect(fact18 ~/ fact17, new Int64.fromInt(18));
+ Int64 fact18 = _factorial(new Int64(18));
+ Int64 fact17 = _factorial(new Int64(17));
+ expect(fact18 ~/ fact17, new Int64(18));
});
test("min, max values", () {
- expect(new Int64.fromInt(1) << 63, Int64.MIN_VALUE);
- expect(-(Int64.MIN_VALUE + new Int64.fromInt(1)), Int64.MAX_VALUE);
+ expect(new Int64(1) << 63, Int64.MIN_VALUE);
+ expect(-(Int64.MIN_VALUE + new Int64(1)), Int64.MAX_VALUE);
});
group("parse", () {
test("parseRadix10", () {
checkInt(int x) {
- expect(Int64.parseRadix('$x', 10), new Int64.fromInt(x));
+ expect(Int64.parseRadix('$x', 10), new Int64(x));
}
checkInt(0);
checkInt(1);
@@ -573,20 +683,20 @@
group("string representation", () {
test("toString", () {
- expect(new Int64.fromInt(0).toString(), "0");
- expect(new Int64.fromInt(1).toString(), "1");
- expect(new Int64.fromInt(-1).toString(), "-1");
- expect(new Int64.fromInt(-10).toString(), "-10");
+ expect(new Int64(0).toString(), "0");
+ expect(new Int64(1).toString(), "1");
+ expect(new Int64(-1).toString(), "-1");
+ expect(new Int64(-10).toString(), "-10");
expect(Int64.MIN_VALUE.toString(), "-9223372036854775808");
expect(Int64.MAX_VALUE.toString(), "9223372036854775807");
int top = 922337201;
int bottom = 967490662;
- Int64 fullnum = (new Int64.fromInt(1000000000) * new Int64.fromInt(top)) +
- new Int64.fromInt(bottom);
+ Int64 fullnum = (new Int64(1000000000) * new Int64(top)) +
+ new Int64(bottom);
expect(fullnum.toString(), "922337201967490662");
expect((-fullnum).toString(), "-922337201967490662");
- expect(new Int64.fromInt(123456789).toString(), "123456789");
+ expect(new Int64(123456789).toString(), "123456789");
});
test("toHexString", () {
@@ -595,11 +705,11 @@
expect(deadbeef12341234.toHexString(), "DEADBEEF12341234");
expect(new Int64.fromInts(0x17678A7, 0xDEF01234).toHexString(),
"17678A7DEF01234");
- expect(new Int64.fromInt(123456789).toHexString(), "75BCD15");
+ expect(new Int64(123456789).toHexString(), "75BCD15");
});
test("toRadixString", () {
- expect(new Int64.fromInt(123456789).toRadixString(5), "223101104124");
+ expect(new Int64(123456789).toRadixString(5), "223101104124");
expect(Int64.MIN_VALUE.toRadixString(2),
"-1000000000000000000000000000000000000000000000000000000000000000");
expect(Int64.MIN_VALUE.toRadixString(3),
diff --git a/pkg/http_server/test/http_body_test.dart b/pkg/http_server/test/http_body_test.dart
index 7f510e7..150f1e5 100644
--- a/pkg/http_server/test/http_body_test.dart
+++ b/pkg/http_server/test/http_body_test.dart
@@ -238,8 +238,8 @@
test('application/x-www-form-urlencoded',
'%E5%B9%B3%3D%E4%BB%AE%E5%90%8D=%E5%B9%B3%E4%BB%AE%E5%90%8D&b'
'=%E5%B9%B3%E4%BB%AE%E5%90%8D'.codeUnits,
- { 'b' : '平仮名',
- '平=仮名' : '平仮名'},
+ { '平=仮名' : '平仮名',
+ 'b' : '平仮名' },
"form");
test('application/x-www-form-urlencoded',
diff --git a/pkg/intl/lib/date_format.dart b/pkg/intl/lib/date_format.dart
index 17aca41..0a53f48 100644
--- a/pkg/intl/lib/date_format.dart
+++ b/pkg/intl/lib/date_format.dart
@@ -486,10 +486,10 @@
// e.g. in "hh:mm:ss" will match hh, mm, and ss. But in "hms" would
// match each letter individually.
new RegExp(
- "^(?:G+|y+|M+|k+|S+|E+|a+|h+|K+|H+|c+|L+|Q+|d+|m+|s+|v+|z+|Z+)"),
+ "^(?:G+|y+|M+|k+|S+|E+|a+|h+|K+|H+|c+|L+|Q+|d+|D+|m+|s+|v+|z+|Z+)"),
// Everything else - A sequence that is not quotes or field characters.
// e.g. in "hh:mm:ss" will match the colons.
- new RegExp("^[^\'GyMkSEahKHcLQdmsvzZ]+")
+ new RegExp("^[^\'GyMkSEahKHcLQdDmsvzZ]+")
];
/**
diff --git a/pkg/intl/lib/src/date_format_field.dart b/pkg/intl/lib/src/date_format_field.dart
index fb8274c..14990e6 100644
--- a/pkg/intl/lib/src/date_format_field.dart
+++ b/pkg/intl/lib/src/date_format_field.dart
@@ -130,6 +130,8 @@
case 'a': parseAmPm(input, builder); break;
case 'c': parseStandaloneDay(input); break;
case 'd': handleNumericField(input, builder.setDay); break; // day
+ // Day of year. Setting month=January with any day of the year works
+ case 'D': handleNumericField(input, builder.setDay); break; // dayofyear
case 'E': parseDayOfWeek(input); break;
case 'G': break; // era
case 'h': parse1To12Hours(input, builder); break;
@@ -157,6 +159,7 @@
case 'a': return formatAmPm(date);
case 'c': return formatStandaloneDay(date);
case 'd': return formatDayOfMonth(date);
+ case 'D': return formatDayOfYear(date);
case 'E': return formatDayOfWeek(date);
case 'G': return formatEra(date);
case 'h': return format1To12Hours(date);
@@ -356,6 +359,32 @@
return padTo(width, date.day);
}
+ String formatDayOfYear(DateTime date) => padTo(width, dayNumberInYear(date));
+
+ /** Return the ordinal day, i.e. the day number in the year. */
+ int dayNumberInYear(DateTime date) {
+ if (date.month == 1) return date.day;
+ if (date.month == 2) return date.day + 31;
+ return ordinalDayFromMarchFirst(date) + 59 + (isLeapYear(date) ? 1 : 0);
+ }
+
+ /**
+ * Return the day of the year counting March 1st as 1, after which the
+ * number of days per month is constant, so it's easier to calculate.
+ * Formula from http://en.wikipedia.org/wiki/Ordinal_date
+ */
+ int ordinalDayFromMarchFirst(DateTime date) =>
+ ((30.6 * date.month) - 91.4).floor() + date.day;
+
+ /**
+ * Return true if this is a leap year. Rely on [DateTime] to do the
+ * underlying calculation, even though it doesn't expose the test to us.
+ */
+ bool isLeapYear(DateTime date) {
+ var feb29 = new DateTime(date.year, 2, 29);
+ return feb29.month == 2;
+ }
+
String formatDayOfWeek(DateTime date) {
// Note that Dart's weekday returns 1 for Monday and 7 for Sunday.
return (width >= 4 ? symbols.WEEKDAYS :
diff --git a/pkg/intl/test/date_time_format_test_core.dart b/pkg/intl/test/date_time_format_test_core.dart
index b39372d..757bb6b 100644
--- a/pkg/intl/test/date_time_format_test_core.dart
+++ b/pkg/intl/test/date_time_format_test_core.dart
@@ -292,19 +292,19 @@
if (subset.length <= 1) return;
var aDate = new DateTime(2012, 1, 27, 20, 58, 59, 0);
// An explicit format that doesn't conform to any skeleton
- var us = new DateFormat(r'yy //// :D \\\\ dd:ss ^&@ M');
- expect(us.format(aDate), equals(r"12 //// :D \\\\ 27:59 ^&@ 1"));
+ var us = new DateFormat(r'yy //// :W \\\\ dd:ss ^&@ M');
+ expect(us.format(aDate), equals(r"12 //// :W \\\\ 27:59 ^&@ 1"));
// The result won't change with locale unless we use fields that are words.
- var greek = new DateFormat(r'yy //// :D \\\\ dd:ss ^&@ M', 'el_GR');
- expect(greek.format(aDate), equals(r"12 //// :D \\\\ 27:59 ^&@ 1"));
- var usWithWords = new DateFormat('yy / :D \\ dd:ss ^&@ MMM', 'en_US');
- var greekWithWords = new DateFormat('yy / :D \\ dd:ss ^&@ MMM', 'el_GR');
+ var greek = new DateFormat(r'yy //// :W \\\\ dd:ss ^&@ M', 'el_GR');
+ expect(greek.format(aDate), equals(r"12 //// :W \\\\ 27:59 ^&@ 1"));
+ var usWithWords = new DateFormat('yy / :W \\ dd:ss ^&@ MMM', 'en_US');
+ var greekWithWords = new DateFormat('yy / :W \\ dd:ss ^&@ MMM', 'el_GR');
expect(
usWithWords.format(aDate),
- equals(r"12 / :D \ 27:59 ^&@ Jan"));
+ equals(r"12 / :W \ 27:59 ^&@ Jan"));
expect(
greekWithWords.format(aDate),
- equals(r"12 / :D \ 27:59 ^&@ Ιαν"));
+ equals(r"12 / :W \ 27:59 ^&@ Ιαν"));
var escaped = new DateFormat(r"hh 'o''clock'");
expect(escaped.format(aDate), equals(r"08 o'clock"));
var reParsed = escaped.parse(escaped.format(aDate));
@@ -369,4 +369,36 @@
expect(formatted, quarters[i]);
}
});
+
+ /**
+ * Generate a map from day numbers in the given [year] (where Jan 1 == 1)
+ * to a Date object. If [year] is a leap year, then pass 1 for
+ * [leapDay], otherwise pass 0.
+ */
+ Map<int, DateTime> generateDates(int year, int leapDay) =>
+ new Iterable.generate(365 + leapDay, (n) => n + 1)
+ .map((day) => new DateTime(year, 1, day)).toList().asMap();
+
+ void verifyOrdinals(Map dates) {
+ var f = new DateFormat("D");
+ var withYear = new DateFormat("yyyy D");
+ dates.forEach((number, date) {
+ var formatted = f.format(date);
+ expect(formatted, (number + 1).toString());
+ var formattedWithYear = withYear.format(date);
+ var parsed = withYear.parse(formattedWithYear);
+ expect(parsed, date);
+ });
+ }
+
+ test('Ordinal Date', () {
+ var f = new DateFormat("D");
+ var dates = generateDates(2012, 1);
+ var nonLeapDates = generateDates(2013, 0);
+ verifyOrdinals(dates);
+ verifyOrdinals(nonLeapDates);
+ // Check one hard-coded just to be on the safe side.
+ var aDate = new DateTime(2012, 4, 27, 13, 58, 59, 012);
+ expect(f.format(aDate), "118");
+ });
}
\ No newline at end of file
diff --git a/pkg/pkg.status b/pkg/pkg.status
index adbdf3b..9ff7d8d 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -14,7 +14,7 @@
scheduled_test/lib/*: Skip
polymer/example/scoped_style/*: Skip
-scheduled_test/test/scheduled_server_test: Pass, Fail, Slow, Crash # Issue 9231, 9582
+scheduled_test/test/scheduled_server_test: Pass, Slow, Fail # Issue 9231, 13524
scheduled_test/test/scheduled_process_test: Pass, Slow # Issue 9231
# Skip test not runnable via test.dart
@@ -22,27 +22,22 @@
third_party/html5lib/test/browser/browser_test: Skip
[ $compiler == dart2js ]
-analyzer_experimental/test/generated/ast_test: Fail #Issue 12341
+analyzer_experimental/test/generated/ast_test: RuntimeError #Issue 12341
[ $compiler == dart2js && $checked && $runtime == ie9 ]
crypto/test/base64_test: Timeout # Issue 12486
-[ $compiler == dart2js && $runtime == drt ]
-crypto/test/hmac_sha256_test: Pass, Fail # v8 bug: Issue 12293
-crypto/test/sha1_test: Pass, Fail # v8 bug: Issue 12293
-crypto/test/sha256_test: Pass, Fail # v8 bug: Issue 12293
-path/test/relative_test: Pass, Fail # v8 bug: Issue 12293
-
[ $runtime == d8 || $runtime == jsshell ]
-unittest/test/unittest_nested_groups_setup_teardown_test: Pass, Fail # http://dartbug.com/10109
-stack_trace/test/vm_test: Fail, OK # VM-specific traces
-sequence_zip/test/stream_test: Fail, OK # Timers are not supported.
+unittest/test/unittest_nested_groups_setup_teardown_test: Pass, RuntimeError # http://dartbug.com/10109
+stack_trace/test/vm_test: RuntimeError, OK # VM-specific traces
+sequence_zip/test/stream_test: RuntimeError, OK # Timers are not supported.
+unittest/test/missing_tick_test: Fail # Timer interface not supported: dartbug.com/7728.
[$compiler == dart2dart]
*: Skip
[ $compiler == dart2js || $compiler == dart2dart ]
-source_maps/test/vlq_test: Fail # A VLQ test checks for large numbers that
+source_maps/test/vlq_test: RuntimeError # A VLQ test checks for large numbers that
# overflow in JS (numbers slightly larger than
# 32 bits where we do bitwise operations).
@@ -65,9 +60,6 @@
polymer/test/events_test: Fail # Issue 12865, 13197
polymer/test/event_path_test: Fail # Issue 12865, 13197
-[ $runtime == ff ]
-polymer/test/event_path_test: Fail # Issue 12865, 13197
-
[ $runtime == ie9 || $runtime == ie10 ]
polymer/test/events_test: Fail, Timeout # Issue 12865, 13197, 13260
polymer/test/event_path_test: Fail, Timeout # Issue 12865, 13197, 13260
@@ -217,6 +209,7 @@
[ $runtime == safari || $runtime == chrome || $runtime == ie9 || $runtime == ff || $runtime == dartium || $runtime == drt ]
docgen/test/single_library_test: Skip # Uses dart:io
+scheduled_test/test/scheduled_server_test: Skip # Uses dart:io
[ $browser || $runtime == vm ]
unittest/test/missing_tick_test: Fail, OK # This test should fail, not time out.
@@ -224,3 +217,9 @@
# Issue http://dartbug.com/12930
[ $runtime == vm ]
intl/test/message_extraction/message_extraction_test: Pass, Fail # Issue 12930
+
+[ $compiler == none && $runtime == vm ]
+observe/test/observe_test: Pass, Fail # Issue 13543
+
+[ $compiler == none && $runtime == vm && $checked ]
+intl/test/message_extraction/failed_extraction_test: Pass, Fail # Issue 13543
diff --git a/pkg/polymer/lib/builder.dart b/pkg/polymer/lib/builder.dart
index eb5ee43..cb1a1c6 100644
--- a/pkg/polymer/lib/builder.dart
+++ b/pkg/polymer/lib/builder.dart
@@ -4,7 +4,7 @@
/**
* Common logic to make it easy to run the polymer linter and deploy tool.
- *
+ *
* The functions in this library are designed to make it easier to create
* `build.dart` files. A `build.dart` file is a Dart script that can be invoked
* from the command line, but that can also invoked automatically by the Dart
@@ -39,7 +39,7 @@
* import 'package:polymer/builder.dart';
*
* main() {
- * lint().then(() => deploy());
+ * lint().then((_) => deploy());
* }
*
* **Example 3**: Runs the linter, but conditionally does the deploy step. See
@@ -51,7 +51,7 @@
*
* main() {
* var options = parseOptions();
- * lint().then(() {
+ * lint().then((_) {
* if (options.forceDeploy) deploy();
* });
* }
@@ -97,7 +97,7 @@
* The [entryPoints] list contains files under web/ that should be treated as
* entry points. Each entry on this list is a relative path from the package
* root (for example 'web/index.html'). If null, all files under 'web/' are
- * treated as possible entry points.
+ * treated as possible entry points.
*
* Options are read from the command line arguments, but you can override them
* passing the [options] argument. The deploy operation is run only when the
@@ -123,13 +123,13 @@
/**
- * Runs the polymer linter on any relevant file in your package,
+ * Runs the polymer linter on any relevant file in your package,
* such as any .html file under 'lib/', 'asset/', and 'web/'.
*
* The [entryPoints] list contains files under web/ that should be treated as
* entry points. Each entry on this list is a relative path from the package
* root (for example 'web/index.html'). If null, all files under 'web/' are
- * treated as possible entry points.
+ * treated as possible entry points.
*
* Options are read from the command line arguments, but you can override them
* passing the [options] argument.
@@ -184,7 +184,7 @@
* The [entryPoints] list contains files under web/ that should be treated as
* entry points. Each entry on this list is a relative path from the package
* root (for example 'web/index.html'). If null, all files under 'web/' are
- * treated as possible entry points.
+ * treated as possible entry points.
*
* Options are read from the command line arguments, but you can override them
* passing the [options] list.
diff --git a/pkg/polymer/test/event_path_test.dart b/pkg/polymer/test/event_path_test.dart
index 550731c..3037822 100644
--- a/pkg/polymer/test/event_path_test.dart
+++ b/pkg/polymer/test/event_path_test.dart
@@ -14,7 +14,7 @@
test('bubbling in the right order', () {
// TODO(sigmund): this should change once we port over the
// 'WebComponentsReady' event.
- runAsync(expectAsync0(() {
+ return new Future.delayed(Duration.ZERO).then((_) {
var item1 = query('#item1');
var menuButton = query('#menuButton');
// Note: polymer uses automatic node finding (menuButton.$.menu)
@@ -22,14 +22,13 @@
// from the parent shadow (menu.$.selectorContent instead of
// menu.$.menuShadow.$.selectorContent)
var menu = menuButton.shadowRoot.query('#menu');
- var selector = menu.shadowRoot.query("#menuShadow");
var overlay = menuButton.shadowRoot.query('#overlay');
var expectedPath = <Node>[
item1,
menuButton.shadowRoot.query('#menuButtonContent'),
- selector.olderShadowRoot.query('#selectorContent'),
- selector.olderShadowRoot.query('#selectorDiv'),
- menu.shadowRoot.query('#menuShadow').olderShadowRoot,
+ menu.shadowRoot.olderShadowRoot.query('#selectorContent'),
+ menu.shadowRoot.olderShadowRoot.query('#selectorDiv'),
+ menu.shadowRoot.olderShadowRoot,
menu.shadowRoot.query('#menuShadow'),
menu.shadowRoot.query('#menuDiv'),
menu.shadowRoot,
@@ -56,6 +55,6 @@
}
item1.dispatchEvent(new Event('x', canBubble: true));
- }));
+ });
});
}
diff --git a/pkg/polymer/test/event_path_test.html b/pkg/polymer/test/event_path_test.html
index 3e5af21..3eb3e06 100644
--- a/pkg/polymer/test/event_path_test.html
+++ b/pkg/polymer/test/event_path_test.html
@@ -58,14 +58,14 @@
<polymer-element name="x-menu-button">
<template>
- <div>
- <x-overlay id="overlay">
- <div id="menuButtonDiv">
- <x-menu id="menu">
- <content id="menuButtonContent"></content>
- </x-menu>
- </div>
- </x-overlay>
+ <div>
+ <x-overlay id="overlay">
+ <div id="menuButtonDiv">
+ <x-menu id="menu">
+ <content id="menuButtonContent"></content>
+ </x-menu>
+ </div>
+ </x-overlay>
</div>
</template>
<script type="application/dart">
diff --git a/pkg/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
index 4768c68..4b28309 100644
--- a/pkg/scheduled_test/lib/scheduled_process.dart
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -183,8 +183,8 @@
exitCodeCompleter.complete(exitCode);
if (!_endExpected) {
- throw "Process '$description' ended earlier than scheduled "
- "with exit code $exitCode.";
+ fail("Process '$description' ended earlier than scheduled "
+ "with exit code $exitCode.");
}
}), "waiting to reach shouldExit() or kill() for process "
"'$description'");
diff --git a/pkg/scheduled_test/lib/scheduled_server.dart b/pkg/scheduled_test/lib/scheduled_server.dart
index 8c1ad81..13dd340 100644
--- a/pkg/scheduled_test/lib/scheduled_server.dart
+++ b/pkg/scheduled_test/lib/scheduled_server.dart
@@ -38,7 +38,7 @@
ScheduledServer._(this._server, this.description);
/// Creates a new server listening on an automatically-allocated port on
- /// localhost. [description] is used to refer to the server in debugging
+ /// 127.0.0.1. [description] is used to refer to the server in debugging
/// messages.
factory ScheduledServer([String description]) {
var id = _count++;
@@ -46,7 +46,7 @@
var scheduledServer;
scheduledServer = new ScheduledServer._(schedule(() {
- return SafeHttpServer.bind("localhost", 0).then((server) {
+ return SafeHttpServer.bind("127.0.0.1", 0).then((server) {
server.listen(scheduledServer._handleRequest,
onError: (e) => currentSchedule.signalError(e));
currentSchedule.onComplete.schedule(server.close);
@@ -60,7 +60,7 @@
Future<int> get port => _server.then((s) => s.port);
/// The base URL of the server, including its port.
- Future<Uri> get url => port.then((p) => Uri.parse("http://localhost:$p"));
+ Future<Uri> get url => port.then((p) => Uri.parse("http://127.0.0.1:$p"));
/// Schedules [handler] to handle a request to the server with [method] and
/// [path]. The schedule will wait until an HTTP request is received. If that
@@ -91,8 +91,8 @@
void _handleRequest(HttpRequest request) {
wrapFuture(new Future.sync(() {
if (_handlers.isEmpty) {
- throw "'$description' received ${request.method} ${request.uri.path} "
- "when no more requests were expected.";
+ fail("'$description' received ${request.method} ${request.uri.path} "
+ "when no more requests were expected.");
}
return _handlers.removeFirst().fn(request);
}).catchError((e) {
diff --git a/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
index a1d6358..e5baf44 100644
--- a/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
@@ -42,7 +42,7 @@
if (parent == null) parent = defaultRoot;
var fullPath = path.join(parent, name);
if (!new Directory(fullPath).existsSync()) {
- throw "Directory not found: '$fullPath'.";
+ fail("Directory not found: '$fullPath'.");
}
return Future.wait(contents.map((entry) {
@@ -77,11 +77,11 @@
var adjective = requiresReadable ? 'readable' : 'loadable';
if (matchingEntries.length == 0) {
- throw "Couldn't find a $adjective entry named '${split.first}' within "
- "'$name'.";
+ fail("Couldn't find a $adjective entry named '${split.first}' within "
+ "'$name'.");
} else if (matchingEntries.length > 1) {
- throw "Found multiple $adjective entries named '${split.first}' within "
- "'$name'.";
+ fail("Found multiple $adjective entries named '${split.first}' within "
+ "'$name'.");
} else {
var remainingPath = split.sublist(1);
if (remainingPath.isEmpty) {
diff --git a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
index eca863a..9111b3d 100644
--- a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
@@ -59,7 +59,7 @@
if (parent == null) parent = defaultRoot;
var fullPath = path.join(parent, name);
if (!new File(fullPath).existsSync()) {
- throw "File not found: '$fullPath'.";
+ fail("File not found: '$fullPath'.");
}
return new File(fullPath).readAsBytes().then(_validateNow);
@@ -84,7 +84,7 @@
Future _validateNow(List<int> actualContents) {
if (orderedIterableEquals(contents, actualContents)) return null;
// TODO(nweiz): show a hex dump here if the data is small enough.
- throw "File '$name' didn't contain the expected binary data.";
+ fail("File '$name' didn't contain the expected binary data.");
}
}
diff --git a/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
index 8a80be2..590a1ce 100644
--- a/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
@@ -27,10 +27,9 @@
if (parent == null) parent = defaultRoot;
var fullPath = path.join(parent, name);
if (new File(fullPath).existsSync()) {
- throw "Expected nothing to exist at '$fullPath', but found a file.";
+ fail("Expected nothing to exist at '$fullPath', but found a file.");
} else if (new Directory(fullPath).existsSync()) {
- throw "Expected nothing to exist at '$fullPath', but found a "
- "directory.";
+ fail("Expected nothing to exist at '$fullPath', but found a directory.");
} else {
return;
}
diff --git a/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
index 32af689..7039639 100644
--- a/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
@@ -55,7 +55,7 @@
matchingEntries.sort();
if (matchingEntries.isEmpty) {
- throw "No entry found in '$parent' matching ${_patternDescription}.";
+ fail("No entry found in '$parent' matching ${_patternDescription}.");
}
return Future.wait(matchingEntries.map((entry) {
@@ -76,9 +76,9 @@
return prefixLines(result.last, firstPrefix: '* ', prefix: ' ');
}).join('\n');
- throw "Multiple valid entries found in '$parent' matching "
- "$_patternDescription:\n"
- "$resultString";
+ fail("Multiple valid entries found in '$parent' matching "
+ "$_patternDescription:\n"
+ "$resultString");
}
// If no entries matching [pattern] validated, that's also bad.
@@ -91,9 +91,9 @@
firstPrefix: '* ', prefix: ' ');
}).join('\n');
- throw "No valid entries found in '$parent' matching "
- "$_patternDescription:\n"
- "$resultString";
+ fail("No valid entries found in '$parent' matching "
+ "$_patternDescription:\n"
+ "$resultString");
});
}
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/handler.dart b/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
index 8f61be1..316d536 100644
--- a/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
+++ b/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
@@ -45,8 +45,8 @@
_fn = (request) {
return _waitForTask().then((_) {
if (!ready) {
- throw "'${server.description}' received $method $path earlier than "
- "expected.";
+ fail("'${server.description}' received "
+ "$method $path earlier than expected.");
}
// Use a nested call to [schedule] to help the user tell the difference
@@ -55,8 +55,8 @@
chainToCompleter(schedule(() {
return new Future.sync(() {
if (request.method != method || request.uri.path != path) {
- throw "'${server.description}' expected $method $path, "
- "but got ${request.method} ${request.uri.path}.";
+ fail("'${server.description}' expected $method $path, "
+ "but got ${request.method} ${request.uri.path}.");
}
return fn(request);
diff --git a/pkg/scheduled_test/test/descriptor/async_test.dart b/pkg/scheduled_test/test/descriptor/async_test.dart
index b4fde98..15763bb 100644
--- a/pkg/scheduled_test/test/descriptor/async_test.dart
+++ b/pkg/scheduled_test/test/descriptor/async_test.dart
@@ -70,10 +70,9 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error,
- matches(r"^File not found: '[^']+[\\/]name\.txt'\.$"));
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
+ matches(r"^File not found: '[^']+[\\/]name\.txt'\.$"));
});
}, passing: ['test 2']);
@@ -113,9 +112,8 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error,
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^Directory not found: '[^']+[\\/]dir'\.$"));
});
}, passing: ['test 2']);
diff --git a/pkg/scheduled_test/test/descriptor/directory_test.dart b/pkg/scheduled_test/test/descriptor/directory_test.dart
index a8051cc..82c6d8d 100644
--- a/pkg/scheduled_test/test/descriptor/directory_test.dart
+++ b/pkg/scheduled_test/test/descriptor/directory_test.dart
@@ -125,9 +125,8 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error.toString(),
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^Directory not found: '[^']+[\\/]dir[\\/]subdir'\.$"));
});
}, passing: ['test 2']);
@@ -167,9 +166,8 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error.toString(),
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^File not found: '[^']+[\\/]dir[\\/]file2\.txt'\.$"));
});
}, passing: ['test 2']);
@@ -208,9 +206,8 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error.toString(), matches(
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(), matches(
r"^\* File not found: '[^']+[\\/]dir[\\/]subdir[\\/]subfile1\.txt'\."
r"\n"
r"\* File 'subfile2\.txt' should contain:\n"
@@ -259,13 +256,12 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.map((e) => e.error.toString()), equals([
- "File 'subfile1.txt' should contain:\n"
- "| subcontents1\n"
- "but actually contained:\n"
- "X wrongtents1"
- ]));
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(), equals(
+ "File 'subfile1.txt' should contain:\n"
+ "| subcontents1\n"
+ "but actually contained:\n"
+ "X wrongtents1"));
});
}, passing: ['test 2']);
@@ -300,9 +296,9 @@
d.file('name.txt', 'contents')
]);
- expect(dir.load('subdir').toList(),
- throwsA(equals("Couldn't find a readable entry named 'subdir' within "
- "'dir'.")));
+ expect(dir.load('subdir').toList(), throwsA(predicate(
+ (x) => x.toString() == "Couldn't find a readable entry named "
+ "'subdir' within 'dir'.")));
});
});
@@ -331,9 +327,9 @@
test('test', () {
var dir = d.dir('dir', [d.file('name.txt', 'contents')]);
- expect(dir.load('not-name.txt').toList(),
- throwsA(equals("Couldn't find a readable entry named 'not-name.txt' "
- "within 'dir'.")));
+ expect(dir.load('not-name.txt').toList(), throwsA(predicate(
+ (x) => x.toString() == "Couldn't find a readable entry named "
+ "'not-name.txt' within 'dir'.")));
});
});
@@ -345,9 +341,9 @@
d.file('name.txt', 'contents')
]);
- expect(dir.load('name.txt').toList(),
- throwsA(equals("Found multiple readable entries named 'name.txt' "
- "within 'dir'.")));
+ expect(dir.load('name.txt').toList(), throwsA(predicate(
+ (x) => x.toString() == "Found multiple readable entries named "
+ "'name.txt' within 'dir'.")));
});
});
@@ -412,4 +408,4 @@
expect(d.dir('dir').describe(), equals('dir'));
});
});
-}
\ No newline at end of file
+}
diff --git a/pkg/scheduled_test/test/descriptor/file_test.dart b/pkg/scheduled_test/test/descriptor/file_test.dart
index e22a992..0b2a90f 100644
--- a/pkg/scheduled_test/test/descriptor/file_test.dart
+++ b/pkg/scheduled_test/test/descriptor/file_test.dart
@@ -75,13 +75,12 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.map((e) => e.error), equals([
- "File 'name.txt' should contain:\n"
- "| contents\n"
- "but actually contained:\n"
- "X wrongtents"
- ]), verbose: true);
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(), equals(
+ "File 'name.txt' should contain:\n"
+ "| contents\n"
+ "but actually contained:\n"
+ "X wrongtents"));
});
}, passing: ['test 2']);
@@ -98,9 +97,8 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error,
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^File not found: '[^']+[\\/]name\.txt'\.$"));
});
}, passing: ['test 2']);
@@ -165,10 +163,9 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.map((e) => e.error), equals([
- "File 'name.bin' didn't contain the expected binary data."
- ]), verbose: true);
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(), equals(
+ "File 'name.bin' didn't contain the expected binary data."));
});
}, passing: ['test 2']);
@@ -218,11 +215,10 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.map((e) => e.error.message), equals([
- "Expected: contains 'baaz'\n"
- " Actual: 'barfoobaz'\n"
- ]), verbose: true);
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(), equals(
+ "Expected: contains 'baaz'\n"
+ " Actual: 'barfoobaz'\n"));
});
}, passing: ['test 2']);
@@ -259,11 +255,10 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.map((e) => e.error.message), equals([
- "Expected: contains <12>\n"
- " Actual: [98, 97, 114, 102, 111, 111, 98, 97, 122]\n"
- ]), verbose: true);
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(), equals(
+ "Expected: contains <12>\n"
+ " Actual: [98, 97, 114, 102, 111, 111, 98, 97, 122]\n"));
});
}, passing: ['test 2']);
}
diff --git a/pkg/scheduled_test/test/descriptor/nothing_test.dart b/pkg/scheduled_test/test/descriptor/nothing_test.dart
index 5d14592..b3a74d1 100644
--- a/pkg/scheduled_test/test/descriptor/nothing_test.dart
+++ b/pkg/scheduled_test/test/descriptor/nothing_test.dart
@@ -54,11 +54,10 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error,
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^Expected nothing to exist at '[^']+[\\/]name.txt', but "
- r"found a file\.$"));
+ r"found a file\.$"));
});
}, passing: ['test 2']);
@@ -76,11 +75,10 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error,
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^Expected nothing to exist at '[^']+[\\/]dir', but found a "
r"directory\.$"));
});
}, passing: ['test 2']);
-}
\ No newline at end of file
+}
diff --git a/pkg/scheduled_test/test/descriptor/pattern_test.dart b/pkg/scheduled_test/test/descriptor/pattern_test.dart
index 7bd33a3..4056425 100644
--- a/pkg/scheduled_test/test/descriptor/pattern_test.dart
+++ b/pkg/scheduled_test/test/descriptor/pattern_test.dart
@@ -66,9 +66,8 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error,
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^No entry found in '[^']+' matching /f\.\./\.$"));
});
}, passing: ['test 2']);
@@ -88,9 +87,8 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error,
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^Caught error\n"
r"| File 'foo' should contain:\n"
r"| | bar\n"
@@ -121,9 +119,8 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error,
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(),
matches(r"^Caught error\n"
r"| File 'bar' should contain:\n"
r"| | baz\n"
@@ -152,14 +149,13 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error, matches(
- r"^Multiple valid entries found in '[^']+' matching "
- r"\/f\.\./:\n"
- r"\* faa\n"
- r"\* fee\n"
- r"\* foo$"));
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(), matches(
+ r"^Multiple valid entries found in '[^']+' matching "
+ r"\/f\.\./:\n"
+ r"\* faa\n"
+ r"\* fee\n"
+ r"\* foo$"));
});
}, passing: ['test 2']);
}
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
index 5aaae60..92ebfad 100644
--- a/pkg/scheduled_test/test/scheduled_process_test.dart
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -63,9 +63,7 @@
});
test('test 2', () {
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.length, equals(1));
- expect(errors.first.error, new isInstanceOf<TestFailure>());
+ expect(errors.single, new isInstanceOf<ScheduleError>());
});
}, passing: ['test 2']);
@@ -143,7 +141,7 @@
// Whether or not this error appears depends on how quickly the "no
// elements" error is handled.
if (errors.length == 2) {
- expect(errors[1].error, matches(r"^Process "
+ expect(errors[1].error.toString(), matches(r"^Process "
r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with "
r"exit code 0\."));
}
@@ -196,7 +194,7 @@
// Whether or not this error appears depends on how quickly the "no
// elements" error is handled.
if (errors.length == 2) {
- expect(errors[1].error, matches(r"^Process "
+ expect(errors[1].error.toString(), matches(r"^Process "
r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with "
r"exit code 0\."));
}
@@ -240,7 +238,7 @@
// Whether or not this error appears depends on how quickly the "no
// elements" error is handled.
if (errors.length == 2) {
- expect(errors[1].error, matches(r"^Process "
+ expect(errors[1].error.toString(), matches(r"^Process "
r"'[^']+[\\/]dart(\.exe)? [^']+' ended earlier than scheduled with "
r"exit code 0\."));
}
diff --git a/pkg/scheduled_test/test/scheduled_server_test.dart b/pkg/scheduled_test/test/scheduled_server_test.dart
index b4cd897..4170874 100644
--- a/pkg/scheduled_test/test/scheduled_server_test.dart
+++ b/pkg/scheduled_test/test/scheduled_server_test.dart
@@ -37,18 +37,10 @@
test('test 2', () {
expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- // TODO(nweiz): There can be three errors due to issue 9151. The
- // HttpException is reported without a stack trace, and so when it's
- // wrapped twice it registers as a different exception each time (because
- // it's given an ad-hoc stack trace). Always expect two exceptions when
- // issue 9151 is fixed.
- expect(errors.length, inInclusiveRange(2, 3));
- expect(errors[0].error, equals("'scheduled server 0' received GET /hello "
- "when no more requests were expected."));
+ expect(errors.length, 2);
+ expect(errors[0].error.toString(), equals("'scheduled server 0' received "
+ "GET /hello when no more requests were expected."));
expect(errors[1].error, new isInstanceOf<HttpException>());
- if (errors.length > 2) {
- expect(errors[2].error, new isInstanceOf<HttpException>());
- }
});
}, passing: ['test 2']);
@@ -115,8 +107,8 @@
// it's given an ad-hoc stack trace). Always expect two exceptions when
// issue 9151 is fixed.
expect(errors.length, inInclusiveRange(2, 3));
- expect(errors[0].error, equals("'scheduled server 0' received GET /hello "
- "earlier than expected."));
+ expect(errors[0].error.toString(), equals(
+ "'scheduled server 0' received GET /hello earlier than expected."));
expect(errors[1].error, new isInstanceOf<HttpException>());
if (errors.length > 2) {
expect(errors[2].error, new isInstanceOf<HttpException>());
@@ -165,18 +157,10 @@
});
test('test 2', () {
- // TODO(nweiz): There can be three errors due to issue 9151. The
- // HttpException is reported without a stack trace, and so when it's
- // wrapped twice it registers as a different exception each time (because
- // it's given an ad-hoc stack trace). Always expect two exceptions when
- // issue 9151 is fixed.
- expect(errors.length, inInclusiveRange(2, 3));
- expect(errors[0].error, equals("'scheduled server 0' expected GET "
- "/goodbye, but got GET /hello."));
+ expect(errors.length, 2);
+ expect(errors[0].error.toString(), equals(
+ "'scheduled server 0' expected GET /goodbye, but got GET /hello."));
expect(errors[1].error, new isInstanceOf<HttpException>());
- if (errors.length > 2) {
- expect(errors[2].error, new isInstanceOf<HttpException>());
- }
});
}, passing: ['test 2']);
@@ -198,18 +182,10 @@
});
test('test 2', () {
- // TODO(nweiz): There can be three errors due to issue 9151. The
- // HttpException is reported without a stack trace, and so when it's
- // wrapped twice it registers as a different exception each time (because
- // it's given an ad-hoc stack trace). Always expect two exceptions when
- // issue 9151 is fixed.
- expect(errors.length, inInclusiveRange(2, 3));
- expect(errors[0].error, equals("'scheduled server 0' expected GET "
- "/hello, but got HEAD /hello."));
+ expect(errors.length, 2);
+ expect(errors[0].error.toString(), equals(
+ "'scheduled server 0' expected GET /hello, but got HEAD /hello."));
expect(errors[1].error, new isInstanceOf<HttpException>());
- if (errors.length > 2) {
- expect(errors[2].error, new isInstanceOf<HttpException>());
- }
});
}, passing: ['test 2']);
@@ -235,9 +211,9 @@
test('test 2', () {
expect(clock.time, equals(2));
- expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.map((e) => e.error), equals(["The schedule timed out after "
- "0:00:00.002000 of inactivity."]));
+ expect(errors.single, new isInstanceOf<ScheduleError>());
+ expect(errors.single.error.toString(), equals(
+ "The schedule timed out after 0:00:00.002000 of inactivity."));
});
}, passing: ['test 2']);
@@ -303,18 +279,10 @@
});
test('test 2', () {
- // TODO(nweiz): There can be three errors due to issue 9151. The
- // HttpException is reported without a stack trace, and so when it's
- // wrapped twice it registers as a different exception each time (because
- // it's given an ad-hoc stack trace). Always expect two exceptions when
- // issue 9151 is fixed.
- expect(errors.length, inInclusiveRange(2, 3));
- expect(errors[0].error, equals("'scheduled server 0' received GET "
- "/hello/3 when no more requests were expected."));
+ expect(errors.length, 2);
+ expect(errors[0].error.toString(), equals("'scheduled server 0' received "
+ "GET /hello/3 when no more requests were expected."));
expect(errors[1].error, new isInstanceOf<HttpException>());
- if (errors.length > 2) {
- expect(errors[2].error, new isInstanceOf<HttpException>());
- }
});
}, passing: ['test 2']);
@@ -330,22 +298,14 @@
completion(equals('Hello, test!')));
server.handle('GET', '/hello', (request) {
- throw 'oh no';
+ fail('oh no');
});
});
test('test 2', () {
- // TODO(nweiz): There can be three errors due to issue 9151. The
- // HttpException is reported without a stack trace, and so when it's
- // wrapped twice it registers as a different exception each time (because
- // it's given an ad-hoc stack trace). Always expect two exceptions when
- // issue 9151 is fixed.
- expect(errors.length, inInclusiveRange(2, 3));
- expect(errors[0].error, equals('oh no'));
+ expect(errors.length, 2);
+ expect(errors[0].error.toString(), equals('oh no'));
expect(errors[1].error, new isInstanceOf<HttpException>());
- if (errors.length > 2) {
- expect(errors[2].error, new isInstanceOf<HttpException>());
- }
});
}, passing: ['test 2']);
}
diff --git a/pkg/shadow_dom/lib/shadow_dom.debug.js b/pkg/shadow_dom/lib/shadow_dom.debug.js
index b889a5e..447f29c 100644
--- a/pkg/shadow_dom/lib/shadow_dom.debug.js
+++ b/pkg/shadow_dom/lib/shadow_dom.debug.js
@@ -1,6 +1,5 @@
-if ((!HTMLElement.prototype.createShadowRoot &&
- !HTMLElement.prototype.webkitCreateShadowRoot) ||
- window.__forceShadowDomPolyfill) {
+if (!HTMLElement.prototype.createShadowRoot
+ || window.__forceShadowDomPolyfill) {
/*
* Copyright 2013 The Polymer Authors. All rights reserved.
@@ -725,6 +724,10 @@
this.observed = [];
this.values = [];
+ this.value = undefined;
+ this.oldValue = undefined;
+ this.oldValues = undefined;
+ this.changeFlags = undefined;
this.started = false;
}
@@ -760,6 +763,18 @@
var value = path.getValueFrom(object, this.observedSet);
var oldValue = this.values[i/2];
if (!areSameValue(value, oldValue)) {
+ if (!anyChanged && !this.valueFn) {
+ this.oldValues = this.oldValues || [];
+ this.changeFlags = this.changeFlags || [];
+ for (var j = 0; j < this.values.length; j++) {
+ this.oldValues[j] = this.values[j];
+ this.changeFlags[j] = false;
+ }
+ }
+
+ if (!this.valueFn)
+ this.changeFlags[i/2] = true;
+
this.values[i/2] = value;
anyChanged = true;
}
@@ -775,22 +790,29 @@
if (!this.getValues())
return;
- this.value = this.valueFn(this.values);
+ if (this.valueFn) {
+ this.value = this.valueFn(this.values);
- if (areSameValue(this.value, this.oldValue))
- return false;
+ if (areSameValue(this.value, this.oldValue))
+ return false;
- this.reportArgs = [this.value, this.oldValue];
+ this.reportArgs = [this.value, this.oldValue];
+ } else {
+ this.reportArgs = [this.values, this.oldValues, this.changeFlags];
+ }
+
return true;
},
sync: function(hard) {
if (hard) {
this.getValues();
- this.value = this.valueFn(this.values);
+ if (this.valueFn)
+ this.value = this.valueFn(this.values);
}
- this.oldValue = this.value;
+ if (this.valueFn)
+ this.oldValue = this.value;
},
close: function() {
@@ -2894,7 +2916,11 @@
* the renderer as needed.
* @private
*/
- nodeWasAdded_: function() {},
+ nodeWasAdded_: function() {
+ for (var child = this.firstChild; child; child = child.nextSibling) {
+ child.nodeWasAdded_();
+ }
+ },
hasChildNodes: function() {
return this.firstChild === null;
@@ -3217,10 +3243,8 @@
var registerWrapper = scope.registerWrapper;
var wrappers = scope.wrappers;
- var shadowRootTable = new WeakMap();
var OriginalElement = window.Element;
-
var matchesName = oneOf(OriginalElement.prototype, [
'matches',
'mozMatchesSelector',
@@ -3248,7 +3272,7 @@
mixin(Element.prototype, {
createShadowRoot: function() {
var newShadowRoot = new wrappers.ShadowRoot(this);
- shadowRootTable.set(this, newShadowRoot);
+ this.impl.polymerShadowRoot_ = newShadowRoot;
var renderer = scope.getRendererForHost(this);
renderer.invalidate();
@@ -3257,7 +3281,7 @@
},
get shadowRoot() {
- return shadowRootTable.get(this) || null;
+ return this.impl.polymerShadowRoot_ || null;
},
setAttribute: function(name, value) {
@@ -3872,7 +3896,6 @@
var eventParentsTable = new WeakMap();
var insertionParentTable = new WeakMap();
var rendererForHostTable = new WeakMap();
- var shadowDOMRendererTable = new WeakMap();
function distributeChildToInsertionPoint(child, insertionPoint) {
getDistributedChildNodes(insertionPoint).push(child);
@@ -4325,7 +4348,7 @@
},
associateNode: function(node) {
- shadowDOMRendererTable.set(node, this);
+ node.impl.polymerShadowRenderer_ = this;
}
};
@@ -4384,7 +4407,7 @@
* This gets called when a node was added or removed to it.
*/
Node.prototype.invalidateShadowRenderer = function(force) {
- var renderer = shadowDOMRendererTable.get(this);
+ var renderer = this.impl.polymerShadowRenderer_;
if (renderer) {
renderer.invalidate();
return true;
@@ -4394,9 +4417,9 @@
};
HTMLContentElement.prototype.getDistributedNodes = function() {
- var renderer = shadowDOMRendererTable.get(this);
- if (renderer)
- renderer.render();
+ // TODO(arv): We should only rerender the dirty ancestor renderers (from
+ // the root and down).
+ renderAllPending();
return getDistributedChildNodes(this);
};
@@ -4409,7 +4432,7 @@
var renderer;
if (shadowRoot)
renderer = getRendererForShadowRoot(shadowRoot);
- shadowDOMRendererTable.set(this, renderer);
+ this.impl.polymerShadowRenderer_ = renderer;
if (renderer)
renderer.invalidate();
};
@@ -5135,8 +5158,10 @@
// TODO(jmesserly): do we still need these?
if (obj instanceof NodeList) return 'NodeList';
if (obj instanceof ShadowRoot) return 'ShadowRoot';
- if (obj instanceof MutationRecord) return 'MutationRecord';
- if (obj instanceof MutationObserver) return 'MutationObserver';
+ if (window.MutationRecord && (obj instanceof MutationRecord))
+ return 'MutationRecord';
+ if (window.MutationObserver && (obj instanceof MutationObserver))
+ return 'MutationObserver';
var unwrapped = unwrapIfNeeded(obj);
if (obj !== unwrapped) {
diff --git a/pkg/shadow_dom/lib/shadow_dom.min.js b/pkg/shadow_dom/lib/shadow_dom.min.js
index 16bf09b..b380191 100644
--- a/pkg/shadow_dom/lib/shadow_dom.min.js
+++ b/pkg/shadow_dom/lib/shadow_dom.min.js
@@ -1,2 +1,2 @@
-if(!HTMLElement.prototype.createShadowRoot&&!HTMLElement.prototype.webkitCreateShadowRoot||window.__forceShadowDomPolyfill){!function(){Element.prototype.webkitCreateShadowRoot&&(Element.prototype.webkitCreateShadowRoot=function(){return window.ShadowDOMPolyfill.wrapIfNeeded(this).createShadowRoot()})}(),function(a){"use strict";function b(){function a(a){"splice"===a[0].type&&"splice"===a[1].type&&(b=!0)}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=!1,c=[0];return Array.observe(c,a),c[1]=1,c.length=0,Object.deliverChangeRecords(a),b}function c(){if(a.document&&"securityPolicy"in a.document&&!a.document.securityPolicy.allowsEval)return!1;try{var b=new Function("","return true;");return b()}catch(c){return!1}}function d(a){return+a===a>>>0}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:H(a)&&H(b)?!0:a!==a&&b!==b}function h(a){return"string"!=typeof a?!1:(a=a.trim(),""==a?!0:"."==a[0]?!1:P.test(a))}function i(a,b){if(b!==Q)throw Error("Use Path.get to retrieve path objects");return""==a.trim()?this:d(a)?(this.push(a),this):(a.split(/\s*\.\s*/).filter(function(a){return a}).forEach(function(a){this.push(a)},this),G&&!F&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn()),void 0)}function j(a){if(a instanceof i)return a;null==a&&(a=""),"string"!=typeof a&&(a=String(a));var b=R[a];if(b)return b;if(!h(a))return S;var b=new i(a,Q);return R[a]=b,b}function k(b){for(var c=0;T>c&&b.check();)b.report(),c++;a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=c)}function l(a){for(var b in a)return!1;return!0}function m(a){return l(a.added)&&l(a.removed)&&l(a.changed)}function n(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function o(a,b){var c=b||(Array.isArray(a)?[]:{});for(var d in a)c[d]=a[d];return Array.isArray(a)&&(c.length=a.length),c}function p(a,b,c,d){if(this.closed=!1,this.object=a,this.callback=b,this.target=c,this.token=d,this.reporting=!0,F){var e=this;this.boundInternalCallback=function(a){e.internalCallback(a)}}q(this)}function q(a){V&&(U.push(a),p._allObserversCount++)}function r(a,b,c,d){p.call(this,a,b,c,d),this.connect(),this.sync(!0)}function s(a,b,c,d){if(!Array.isArray(a))throw Error("Provided object is not an Array");r.call(this,a,b,c,d)}function t(a){this.arr=[],this.callback=a,this.isObserved=!0}function u(a,b,c,d,e,g,h){var b=b instanceof i?b:j(b);return b&&b.length&&f(a)?(p.call(this,a,c,d,e),this.valueFn=g,this.setValueFn=h,this.path=b,this.connect(),this.sync(!0),void 0):(this.value_=b?b.getValueFrom(a):void 0,this.value=g?g(this.value_):this.value_,this.closed=!0,void 0)}function v(a,b,c,d){p.call(this,void 0,a,b,c),this.valueFn=d,this.observed=[],this.values=[],this.started=!1}function w(a,b){if("function"==typeof Object.observe){var c=Object.getNotifier(a);return function(d,e){var f={object:a,type:d,name:b};2===arguments.length&&(f.oldValue=e),c.notify(f)}}}function x(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];$[g.type]?(g.name in c||(c[g.name]=g.oldValue),"updated"!=g.type&&("new"!=g.type?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function y(a,b,c){return{index:a,removed:b,addedCount:c}}function z(){}function A(a,b,c,d,e,f){return db.calcSplices(a,b,c,d,e,f)}function B(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function C(a,b,c,d){for(var e=y(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=B(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function D(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case"splice":C(c,g.index,g.removed.slice(),g.addedCount);break;case"new":case"updated":case"deleted":if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;C(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function E(a,b){var c=[];return D(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?(b.removed[0]!==a[b.index]&&c.push(b),void 0):(c=c.concat(A(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)),void 0)}),c}var F=b(),G=c(),H=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},I="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},J="[$_a-zA-Z]",K="[$_a-zA-Z0-9]",L=J+"+"+K+"*",M="(?:[0-9]|[1-9]+[0-9]+)",N="(?:"+L+"|"+M+")",O="(?:"+N+")(?:\\s*\\.\\s*"+N+")*",P=new RegExp("^"+O+"$"),Q={},R={};i.get=j,i.prototype=I({__proto__:[],valid:!0,toString:function(){return this.join(".")},getValueFrom:function(a,b){for(var c=0;c<this.length;c++){if(null==a)return;b&&b.observe(a),a=a[this[c]]}return a},compiledGetValueFromFn:function(){var a=this.map(function(a){return d(a)?'["'+a+'"]':"."+a}),b="",c="obj";b+="if (obj != null";for(var e=0;e<this.length-1;e++)this[e],c+=a[e],b+=" &&\n "+c+" != null";return b+=")\n",c+=a[e],b+=" return "+c+";\nelse\n return undefined;",new Function("obj",b)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var S=new i("",Q);S.valid=!1,S.getValueFrom=S.setValueFrom=function(){};var T=1e3;p.prototype={internalCallback:function(a){this.closed||this.reporting&&this.check(a)&&(this.report(),this.testingResults&&(this.testingResults.anyChanged=!0))},close:function(){this.closed||(this.object&&"function"==typeof this.object.close&&this.object.close(),this.disconnect(),this.object=void 0,this.closed=!0)},deliver:function(a){this.closed||(F?(this.testingResults=a,Object.deliverChangeRecords(this.boundInternalCallback),this.testingResults=void 0):k(this))},report:function(){this.reporting&&(this.sync(!1),this.callback&&(this.reportArgs.push(this.token),this.invokeCallback(this.reportArgs)),this.reportArgs=void 0)},invokeCallback:function(a){try{this.callback.apply(this.target,a)}catch(b){p._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},reset:function(){this.closed||(F&&(this.reporting=!1,Object.deliverChangeRecords(this.boundInternalCallback),this.reporting=!0),this.sync(!0))}};var U,V=!F||a.forceCollectObservers;p._allObserversCount=0,V&&(U=[]);var W=!1,X="function"==typeof Object.deliverAllChangeRecords;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!W){if(X)return Object.deliverAllChangeRecords(),void 0;if(V){W=!0;var b=0,c={};do{b++;var d=U;U=[],c.anyChanged=!1;for(var e=0;e<d.length;e++){var f=d[e];f.closed||(F?f.deliver(c):f.check()&&(c.anyChanged=!0,f.report()),U.push(f))}}while(T>b&&c.anyChanged);a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=b),p._allObserversCount=U.length,W=!1}}},V&&(a.Platform.clearObservers=function(){U=[]}),r.prototype=I({__proto__:p.prototype,connect:function(){F&&Object.observe(this.object,this.boundInternalCallback)},sync:function(){F||(this.oldObject=o(this.object))},check:function(a){var b,c;if(F){if(!a)return!1;c={},b=x(this.object,a,c)}else c=this.oldObject,b=n(this.object,this.oldObject);return m(b)?!1:(this.reportArgs=[b.added||{},b.removed||{},b.changed||{}],this.reportArgs.push(function(a){return c[a]}),!0)},disconnect:function(){F?this.object&&Object.unobserve(this.object,this.boundInternalCallback):this.oldObject=void 0}}),s.prototype=I({__proto__:r.prototype,connect:function(){F&&Array.observe(this.object,this.boundInternalCallback)},sync:function(){F||(this.oldObject=this.object.slice())},check:function(a){var b;if(F){if(!a)return!1;b=E(this.object,a)}else b=A(this.object,0,this.object.length,this.oldObject,0,this.oldObject.length);return b&&b.length?(this.reportArgs=[b],!0):!1}}),s.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})};var Y=Object.getPrototypeOf({}),Z=Object.getPrototypeOf([]);t.prototype={reset:function(){this.isObserved=!this.isObserved},observe:function(a){if(f(a)&&a!==Y&&a!==Z){var b=this.arr.indexOf(a);b>=0&&this.arr[b+1]===this.isObserved||(0>b&&(b=this.arr.length,this.arr[b]=a,Object.observe(a,this.callback)),this.arr[b+1]=this.isObserved,this.observe(Object.getPrototypeOf(a)))}},cleanup:function(){for(var a=0,b=0,c=this.isObserved;b<this.arr.length;){var d=this.arr[b];this.arr[b+1]==c?(b>a&&(this.arr[a]=d,this.arr[a+1]=c),a+=2):Object.unobserve(d,this.callback),b+=2}this.arr.length=a}},u.prototype=I({__proto__:p.prototype,connect:function(){F&&(this.observedSet=new t(this.boundInternalCallback))},disconnect:function(){this.value=void 0,this.value_=void 0,this.observedSet&&(this.observedSet.reset(),this.observedSet.cleanup(),this.observedSet=void 0)},check:function(){return this.observedSet&&this.observedSet.reset(),this.value_=this.path.getValueFrom(this.object,this.observedSet),this.observedSet&&this.observedSet.cleanup(),g(this.value_,this.oldValue_)?!1:(this.value=this.valueFn?this.valueFn(this.value_):this.value_,this.reportArgs=[this.value,this.oldValue],!0)},sync:function(a){a&&(this.observedSet&&this.observedSet.reset(),this.value_=this.path.getValueFrom(this.object,this.observedSet),this.value=this.valueFn?this.valueFn(this.value_):this.value_,this.observedSet&&this.observedSet.cleanup()),this.oldValue_=this.value_,this.oldValue=this.value},setValue:function(a){this.path&&("function"==typeof this.setValueFn&&(a=this.setValueFn(a)),this.path.setValueFrom(this.object,a))}}),v.prototype=I({__proto__:u.prototype,addPath:function(a,b){if(this.started)throw Error("Cannot add more paths once started.");var b=b instanceof i?b:j(b),c=b?b.getValueFrom(a):void 0;this.observed.push(a,b),this.values.push(c)},start:function(){this.connect(),this.sync(!0)},getValues:function(){this.observedSet&&this.observedSet.reset();for(var a=!1,b=0;b<this.observed.length;b+=2){var c=this.observed[b+1];if(c){var d=this.observed[b],e=c.getValueFrom(d,this.observedSet),f=this.values[b/2];g(e,f)||(this.values[b/2]=e,a=!0)}}return this.observedSet&&this.observedSet.cleanup(),a},check:function(){return this.getValues()?(this.value=this.valueFn(this.values),g(this.value,this.oldValue)?!1:(this.reportArgs=[this.value,this.oldValue],!0)):void 0},sync:function(a){a&&(this.getValues(),this.value=this.valueFn(this.values)),this.oldValue=this.value},close:function(){if(this.observed){for(var a=0;a<this.observed.length;a+=2){var b=this.observed[a];b&&"function"==typeof b.close&&b.close()}this.observed=void 0,this.values=void 0}p.prototype.close.call(this)}});var $={"new":!0,updated:!0,deleted:!0};u.defineProperty=function(a,b,c){var d=c.object,e=j(c.path),f=w(a,b),g=new u(d,c.path,function(a,b){f&&f("updated",b)});return Object.defineProperty(a,b,{get:function(){return e.getValueFrom(d)},set:function(a){e.setValueFrom(d,a)},configurable:!0}),{close:function(){var c=e.getValueFrom(d);f&&g.deliver(),g.close(),Object.defineProperty(a,b,{value:c,writable:!0,configurable:!0})}}};var _=0,ab=1,bb=2,cb=3;z.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(_):(e.push(ab),d=g),b--,c--):f==h?(e.push(cb),b--,d=h):(e.push(bb),c--,d=i)}else e.push(cb),b--;else e.push(bb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,0==c-b&&0==f-e)return[];if(b==c){for(var j=y(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[y(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case _:j&&(l.push(j),j=void 0),m++,n++;break;case ab:j||(j=y(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case bb:j||(j=y(m,[],0)),j.addedCount++,m++;break;case cb:j||(j=y(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var db=new z;a.Observer=p,a.Observer.hasObjectObserve=F,a.ArrayObserver=s,a.ArrayObserver.calculateSplices=function(a,b){return db.calculateSplices(a,b)},a.ArraySplice=z,a.ObjectObserver=r,a.PathObserver=u,a.CompoundPathObserver=v,a.Path=i}("undefined"!=typeof global&&global?global:this),("undefined"==typeof WeakMap||navigator.userAgent.indexOf("Firefox/")>-1)&&!function(){var a=Object.defineProperty,b=Date.now()%1e9,c=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")};c.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]:void 0},"delete":function(a){this.set(a,void 0)}},window.WeakMap=c}();var ShadowDOMPolyfill={};!function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a,b){return Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))}),a}function d(a,b){return Object.getOwnPropertyNames(b).forEach(function(c){switch(c){case"arguments":case"caller":case"length":case"name":case"prototype":case"toString":return}Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))}),a}function e(a,b){for(var c=0;c<b.length;c++)if(b[c]in a)return b[c]}function f(a){var b=a.__proto__||Object.getPrototypeOf(a),c=C.get(b);if(c)return c;var d=f(b),e=r(d);return o(b,e,a),e}function g(a,b){m(a,b,!0)}function h(a,b){m(b,a,!1)}function i(a){return/^on[a-z]+$/.test(a)}function j(a){return F?new Function("return this.impl."+a):function(){return this.impl[a]}}function k(a){return F?new Function("v","this.impl."+a+" = v"):function(b){this.impl[a]=b}}function l(a){return F?new Function("return this.impl."+a+".apply(this.impl, arguments)"):function(){return this.impl[a].apply(this.impl,arguments)}}function m(b,c,d){Object.getOwnPropertyNames(b).forEach(function(e){if(!(e in c)){I&&b.__lookupGetter__(e);var f;try{f=Object.getOwnPropertyDescriptor(b,e)}catch(g){f=J}var h,m;if(d&&"function"==typeof f.value)return c[e]=l(e),void 0;var n=i(e);h=n?a.getEventHandlerGetter(e):j(e),(f.writable||f.set)&&(m=n?a.getEventHandlerSetter(e):k(e)),Object.defineProperty(c,e,{get:h,set:m,configurable:f.configurable,enumerable:f.enumerable})}})}function n(a,b,c){var e=a.prototype;o(e,b,c),d(b,a)}function o(a,c,d){var e=c.prototype;b(void 0===C.get(a)),C.set(a,c),D.set(e,a),g(a,e),d&&h(e,d)}function p(a,b){return C.get(b.prototype)===a}function q(a){var b=Object.getPrototypeOf(a),c=f(b),d=r(c);return o(b,d,a),d}function r(a){function b(b){a.call(this,b)}return b.prototype=Object.create(a.prototype),b.prototype.constructor=b,b}function s(a){return a instanceof E.EventTarget||a instanceof E.Event||a instanceof E.Range||a instanceof E.DOMImplementation}function t(a){return a instanceof M||a instanceof L||a instanceof N||a instanceof O||a instanceof K}function u(a){return null===a?null:(b(t(a)),a.polymerWrapper_||(a.polymerWrapper_=new(f(a))(a)))}function v(a){return null===a?null:(b(s(a)),a.impl)}function w(a){return a&&s(a)?v(a):a}function x(a){return a&&!s(a)?u(a):a}function y(a,c){null!==c&&(b(t(a)),b(void 0===c||s(c)),a.polymerWrapper_=c)}function z(a,b,c){Object.defineProperty(a.prototype,b,{get:c,configurable:!0,enumerable:!0})}function A(a,b){z(a,b,function(){return u(this.impl[b])})}function B(a,b){a.forEach(function(a){b.forEach(function(b){a.prototype[b]=function(){var a=x(this);return a[b].apply(a,arguments)}})})}var C=new WeakMap,D=new WeakMap,E=Object.create(null),F=!("securityPolicy"in document)||document.securityPolicy.allowsEval;if(F)try{var G=new Function("","return true;");F=G()}catch(H){}Object.getOwnPropertyNames(window);var I=/Firefox/.test(navigator.userAgent),J={get:function(){},set:function(){},configurable:!0,enumerable:!0},K=DOMImplementation,L=Event,M=Node,N=Window,O=Range;a.assert=b,a.constructorTable=C,a.defineGetter=z,a.defineWrapGetter=A,a.forwardMethodsToWrapper=B,a.isWrapperFor=p,a.mixin=c,a.nativePrototypeTable=D,a.oneOf=e,a.registerObject=q,a.registerWrapper=n,a.rewrap=y,a.unwrap=v,a.unwrapIfNeeded=w,a.wrap=u,a.wrapIfNeeded=x,a.wrappers=E}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a instanceof N.ShadowRoot}function c(a){var b=a.localName;return"content"===b||"shadow"===b}function d(a){return!!a.shadowRoot}function e(a){var b;return a.parentNode||(b=a.defaultView)&&M(b)||null}function f(f,g,h){if(h.length)return h.shift();if(b(f))return j(f)||a.getHostForShadowRoot(f);var i=a.eventParentsTable.get(f);if(i){for(var k=1;k<i.length;k++)h[k-1]=i[k];return i[0]}if(g&&c(f)){var l=f.parentNode;if(l&&d(l))for(var m=a.getShadowTrees(l),n=j(g),k=0;k<m.length;k++)if(m[k].contains(n))return n}return e(f)}function g(a){for(var d=[],e=a,g=[],i=[];e;){var j=null;if(c(e)){j=h(d);var k=d[d.length-1]||e;d.push(k)}else d.length||d.push(e);var l=d[d.length-1];g.push({target:l,currentTarget:e}),b(e)&&d.pop(),e=f(e,j,i)}return g}function h(a){for(var b=a.length-1;b>=0;b--)if(!c(a[b]))return a[b];return null}function i(d,e){for(var g=[];d;){for(var i=[],j=e,l=void 0;j;){var n=null;if(i.length){if(c(j)&&(n=h(i),k(l))){var o=i[i.length-1];i.push(o)}}else i.push(j);if(m(j,d))return i[i.length-1];b(j)&&i.pop(),l=j,j=f(j,n,g)}d=b(d)?a.getHostForShadowRoot(d):d.parentNode}}function j(b){return a.insertionParentTable.get(b)}function k(a){return j(a)}function l(a){for(var b;b=a.parentNode;)a=b;return a}function m(a,b){return l(a)===l(b)}function n(b,c){if(b===c)return!0;if(b instanceof N.ShadowRoot){var d=a.getHostForShadowRoot(b);return n(l(d),c)}return!1}function o(a){switch(a){case"DOMAttrModified":case"DOMAttributeNameChanged":case"DOMCharacterDataModified":case"DOMElementNameChanged":case"DOMNodeInserted":case"DOMNodeInsertedIntoDocument":case"DOMNodeRemoved":case"DOMNodeRemovedFromDocument":case"DOMSubtreeModified":return!0}return!1}function p(b){if(!P.get(b)){P.set(b,!0),o(b.type)||a.renderAllPending();var c=M(b.target),d=M(b);return q(d,c)}}function q(a,b){var c=g(b);return"load"===a.type&&2===c.length&&c[0].target instanceof N.Document&&c.shift(),X.set(a,c),r(a,c)&&s(a,c)&&t(a,c),T.set(a,w.NONE),R.set(a,null),a.defaultPrevented}function r(a,b){for(var c,d=b.length-1;d>0;d--){var e=b[d].target,f=b[d].currentTarget;if(e!==f&&(c=w.CAPTURING_PHASE,!u(b[d],a,c)))return!1}return!0}function s(a,b){var c=w.AT_TARGET;return u(b[0],a,c)}function t(a,b){for(var c,d=a.bubbles,e=1;e<b.length;e++){var f=b[e].target,g=b[e].currentTarget;if(f===g)c=w.AT_TARGET;else{if(!d||V.get(a))continue;c=w.BUBBLING_PHASE}if(!u(b[e],a,c))return}}function u(a,b,c){var d=a.target,e=a.currentTarget,f=O.get(e);if(!f)return!0;if("relatedTarget"in b){var g=L(b),h=M(g.relatedTarget),j=i(e,h);if(j===d)return!0;S.set(b,j)}T.set(b,c);var k=b.type,l=!1;Q.set(b,d),R.set(b,e);for(var m=0;m<f.length;m++){var n=f[m];if(n.removed)l=!0;else if(!(n.type!==k||!n.capture&&c===w.CAPTURING_PHASE||n.capture&&c===w.BUBBLING_PHASE))try{if("function"==typeof n.handler?n.handler.call(e,b):n.handler.handleEvent(b),V.get(b))return!1}catch(o){window.onerror?window.onerror(o.message):console.error(o)}}if(l){var p=f.slice();f.length=0;for(var m=0;m<p.length;m++)p[m].removed||f.push(p[m])}return!U.get(b)}function v(a,b,c){this.type=a,this.handler=b,this.capture=Boolean(c)}function w(a,b){return a instanceof Y?(this.impl=a,void 0):M(A(Y,"Event",a,b))}function x(a){return a&&a.relatedTarget?Object.create(a,{relatedTarget:{value:L(a.relatedTarget)}}):a}function y(a,b,c){var d=window[a],e=function(b,c){return b instanceof d?(this.impl=b,void 0):M(A(d,a,b,c))};return e.prototype=Object.create(b.prototype),c&&J(e.prototype,c),d&&(d.prototype["init"+a]?K(d,e,document.createEvent(a)):K(d,e,new d("temp"))),e}function z(a,b){return function(){arguments[b]=L(arguments[b]);var c=L(this);c[a].apply(c,arguments)}}function A(a,b,c,d){if(gb)return new a(c,x(d));var e=L(document.createEvent(b)),f=fb[b],g=[c];return Object.keys(f).forEach(function(a){var b=null!=d&&a in d?d[a]:f[a];"relatedTarget"===a&&(b=L(b)),g.push(b)}),e["init"+b].apply(e,g),e}function B(a){return"function"==typeof a?!0:a&&a.handleEvent}function C(a){this.impl=a}function D(b){return b instanceof N.ShadowRoot&&(b=a.getHostForShadowRoot(b)),L(b)}function E(a){I(a,jb)}function F(b,c,d,e){a.renderAllPending();for(var f=M(kb.call(c.impl,d,e)),h=g(f,this),i=0;i<h.length;i++){var j=h[i];if(j.currentTarget===b)return j.target}return null}function G(a){return function(){var b=W.get(this);return b&&b[a]&&b[a].value||null}}function H(a){var b=a.slice(2);return function(c){var d=W.get(this);d||(d=Object.create(null),W.set(this,d));var e=d[a];if(e&&this.removeEventListener(b,e.wrapped,!1),"function"==typeof c){var f=function(b){var d=c.call(this,b);d===!1?b.preventDefault():"onbeforeunload"===a&&"string"==typeof d&&(b.returnValue=d)};this.addEventListener(b,f,!1),d[a]={value:c,wrapped:f}}}}var I=a.forwardMethodsToWrapper,J=a.mixin,K=a.registerWrapper,L=a.unwrap,M=a.wrap,N=a.wrappers;new WeakMap;var O=new WeakMap,P=new WeakMap,Q=new WeakMap,R=new WeakMap,S=new WeakMap,T=new WeakMap,U=new WeakMap,V=new WeakMap,W=new WeakMap,X=new WeakMap;v.prototype={equals:function(a){return this.handler===a.handler&&this.type===a.type&&this.capture===a.capture},get removed(){return null===this.handler},remove:function(){this.handler=null}};var Y=window.Event;w.prototype={get target(){return Q.get(this)},get currentTarget(){return R.get(this)},get eventPhase(){return T.get(this)},get path(){var a=new N.NodeList,b=X.get(this);if(b){for(var c=0,d=b.length-1,e=l(R.get(this)),f=0;d>=f;f++){var g=b[f].currentTarget,h=l(g);n(e,h)&&(f!==d||g instanceof N.Node)&&(a[c++]=g)}a.length=c}return a},stopPropagation:function(){U.set(this,!0)},stopImmediatePropagation:function(){U.set(this,!0),V.set(this,!0)}},K(Y,w,document.createEvent("Event"));var Z=y("UIEvent",w),$=y("CustomEvent",w),_={get relatedTarget(){return S.get(this)||M(L(this).relatedTarget)}},ab=J({initMouseEvent:z("initMouseEvent",14)},_),bb=J({initFocusEvent:z("initFocusEvent",5)},_),cb=y("MouseEvent",Z,ab),db=y("FocusEvent",Z,bb),eb=y("MutationEvent",w,{initMutationEvent:z("initMutationEvent",3),get relatedNode(){return M(this.impl.relatedNode)}}),fb=Object.create(null),gb=function(){try{new window.MouseEvent("click")}catch(a){return!1}return!0}();if(!gb){var hb=function(a,b,c){if(c){var d=fb[c];b=J(J({},d),b)}fb[a]=b};hb("Event",{bubbles:!1,cancelable:!1}),hb("CustomEvent",{detail:null},"Event"),hb("UIEvent",{view:null,detail:0},"Event"),hb("MouseEvent",{screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:null},"UIEvent"),hb("FocusEvent",{relatedTarget:null},"UIEvent")}var ib=window.EventTarget,jb=["addEventListener","removeEventListener","dispatchEvent"];[Node,Window].forEach(function(a){var b=a.prototype;jb.forEach(function(a){Object.defineProperty(b,a+"_",{value:b[a]})})}),C.prototype={addEventListener:function(a,b,c){if(B(b)){var d=new v(a,b,c),e=O.get(this);if(e){for(var f=0;f<e.length;f++)if(d.equals(e[f]))return}else e=[],O.set(this,e);e.push(d);var g=D(this);g.addEventListener_(a,p,!0)}},removeEventListener:function(a,b,c){c=Boolean(c);var d=O.get(this);if(d){for(var e=0,f=!1,g=0;g<d.length;g++)d[g].type===a&&d[g].capture===c&&(e++,d[g].handler===b&&(f=!0,d[g].remove()));if(f&&1===e){var h=D(this);h.removeEventListener_(a,p,!0)}}},dispatchEvent:function(a){var b=D(this);return b.dispatchEvent_(L(a))}},ib&&K(ib,C);var kb=document.elementFromPoint;a.adjustRelatedTarget=i,a.elementFromPoint=F,a.getEventHandlerGetter=G,a.getEventHandlerSetter=H,a.wrapEventTargetMethods=E,a.wrappers.CustomEvent=$,a.wrappers.Event=w,a.wrappers.EventTarget=C,a.wrappers.FocusEvent=db,a.wrappers.MouseEvent=cb,a.wrappers.MutationEvent=eb,a.wrappers.UIEvent=Z}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a,b){Object.defineProperty(a,b,{enumerable:!1})}function c(){this.length=0,b(this,"length")}function d(a){if(null==a)return a;for(var b=new c,d=0,e=a.length;e>d;d++)b[d]=f(a[d]);return b.length=e,b}function e(a,b){a.prototype[b]=function(){return d(this.impl[b].apply(this.impl,arguments))}}var f=a.wrap;c.prototype={item:function(a){return this[a]}},b(c.prototype,"item"),a.wrappers.NodeList=c,a.addWrapNodeListMethod=e,a.wrapNodeList=d}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){o(a instanceof k)}function c(a,b,c,d){if(!(a instanceof DocumentFragment))return a.parentNode&&a.parentNode.removeChild(a),a.parentNode_=b,a.previousSibling_=c,a.nextSibling_=d,c&&(c.nextSibling_=a),d&&(d.previousSibling_=a),[a];for(var e,f=[];e=a.firstChild;)a.removeChild(e),f.push(e),e.parentNode_=b;for(var g=0;g<f.length;g++)f[g].previousSibling_=f[g-1]||c,f[g].nextSibling_=f[g+1]||d;return c&&(c.nextSibling_=f[0]),d&&(d.previousSibling_=f[f.length-1]),f}function d(a){if(a instanceof DocumentFragment){for(var b=[],c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b}return[a]}function e(a){for(var b=0;b<a.length;b++)a[b].nodeWasAdded_()}function f(a,b){var c=a.nodeType===k.DOCUMENT_NODE?a:a.ownerDocument;c!==b.ownerDocument&&c.adoptNode(b)}function g(b,c){if(c.length){var d=b.ownerDocument;if(d!==c[0].ownerDocument)for(var e=0;e<c.length;e++)a.adoptNodeNoRemove(c[e],d)}}function h(a,b){g(a,b);var c=b.length;if(1===c)return r(b[0]);for(var d=r(a.ownerDocument.createDocumentFragment()),e=0;c>e;e++)d.appendChild(r(b[e]));return d}function i(a){if(a.invalidateShadowRenderer()){for(var b=a.firstChild;b;){o(b.parentNode===a);var c=b.nextSibling,d=r(b),e=d.parentNode;e&&y.call(e,d),b.previousSibling_=b.nextSibling_=b.parentNode_=null,b=c}a.firstChild_=a.lastChild_=null}else for(var c,f=r(a),g=f.firstChild;g;)c=g.nextSibling,y.call(f,g),g=c}function j(a){var b=a.parentNode;return b&&b.invalidateShadowRenderer()}function k(a){o(a instanceof u),l.call(this,a),this.parentNode_=void 0,this.firstChild_=void 0,this.lastChild_=void 0,this.nextSibling_=void 0,this.previousSibling_=void 0}var l=a.wrappers.EventTarget,m=a.wrappers.NodeList,n=a.defineWrapGetter,o=a.assert,p=a.mixin,q=a.registerWrapper,r=a.unwrap,s=a.wrap,t=a.wrapIfNeeded,u=window.Node,v=u.prototype.appendChild,w=u.prototype.insertBefore,x=u.prototype.replaceChild,y=u.prototype.removeChild,z=u.prototype.compareDocumentPosition;k.prototype=Object.create(l.prototype),p(k.prototype,{appendChild:function(a){b(a);var g;if(this.invalidateShadowRenderer()||j(a)){var i=this.lastChild,k=null;g=c(a,this,i,k),this.lastChild_=g[g.length-1],i||(this.firstChild_=g[0]),v.call(this.impl,h(this,g))}else g=d(a),f(this,a),v.call(this.impl,r(a));return e(g),a},insertBefore:function(a,i){if(!i)return this.appendChild(a);b(a),b(i),o(i.parentNode===this);var k;if(this.invalidateShadowRenderer()||j(a)){var l=i.previousSibling,m=i;k=c(a,this,l,m),this.firstChild===i&&(this.firstChild_=k[0]);var n=r(i),p=n.parentNode;p?w.call(p,h(this,k),n):g(this,k)}else k=d(a),f(this,a),w.call(this.impl,r(a),r(i));return e(k),a},removeChild:function(a){if(b(a),a.parentNode!==this)throw new Error("NotFoundError");var c=r(a);if(this.invalidateShadowRenderer()){var d=this.firstChild,e=this.lastChild,f=a.nextSibling,g=a.previousSibling,h=c.parentNode;h&&y.call(h,c),d===a&&(this.firstChild_=f),e===a&&(this.lastChild_=g),g&&(g.nextSibling_=f),f&&(f.previousSibling_=g),a.previousSibling_=a.nextSibling_=a.parentNode_=void 0}else y.call(this.impl,c);return a},replaceChild:function(a,g){if(b(a),b(g),g.parentNode!==this)throw new Error("NotFoundError");var i,k=r(g);if(this.invalidateShadowRenderer()||j(a)){var l=g.previousSibling,m=g.nextSibling;m===a&&(m=a.nextSibling),i=c(a,this,l,m),this.firstChild===g&&(this.firstChild_=i[0]),this.lastChild===g&&(this.lastChild_=i[i.length-1]),g.previousSibling_=g.nextSibling_=g.parentNode_=void 0,k.parentNode&&x.call(k.parentNode,h(this,i),k)}else i=d(a),f(this,a),x.call(this.impl,r(a),k);return e(i),g},nodeWasAdded_:function(){},hasChildNodes:function(){return null===this.firstChild},get parentNode(){return void 0!==this.parentNode_?this.parentNode_:s(this.impl.parentNode)},get firstChild(){return void 0!==this.firstChild_?this.firstChild_:s(this.impl.firstChild)},get lastChild(){return void 0!==this.lastChild_?this.lastChild_:s(this.impl.lastChild)},get nextSibling(){return void 0!==this.nextSibling_?this.nextSibling_:s(this.impl.nextSibling)},get previousSibling(){return void 0!==this.previousSibling_?this.previousSibling_:s(this.impl.previousSibling)},get parentElement(){for(var a=this.parentNode;a&&a.nodeType!==k.ELEMENT_NODE;)a=a.parentNode;return a},get textContent(){for(var a="",b=this.firstChild;b;b=b.nextSibling)a+=b.textContent;return a},set textContent(a){if(this.invalidateShadowRenderer()){if(i(this),""!==a){var b=this.impl.ownerDocument.createTextNode(a);this.appendChild(b)}}else this.impl.textContent=a},get childNodes(){for(var a=new m,b=0,c=this.firstChild;c;c=c.nextSibling)a[b++]=c;return a.length=b,a},cloneNode:function(a){if(!this.invalidateShadowRenderer())return s(this.impl.cloneNode(a));var b=s(this.impl.cloneNode(!1));if(a)for(var c=this.firstChild;c;c=c.nextSibling)b.appendChild(c.cloneNode(!0));return b},contains:function(a){if(!a)return!1;if(a=t(a),a===this)return!0;var b=a.parentNode;return b?this.contains(b):!1},compareDocumentPosition:function(a){return z.call(this.impl,r(a))}}),n(k,"ownerDocument"),q(u,k,document.createDocumentFragment()),delete k.prototype.querySelector,delete k.prototype.querySelectorAll,k.prototype=p(Object.create(l.prototype),k.prototype),a.wrappers.Node=k}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a,c){for(var d,e=a.firstElementChild;e;){if(e.matches(c))return e;if(d=b(e,c))return d;e=e.nextElementSibling}return null}function c(a,b,d){for(var e=a.firstElementChild;e;)e.matches(b)&&(d[d.length++]=e),c(e,b,d),e=e.nextElementSibling;return d}var d={querySelector:function(a){return b(this,a)},querySelectorAll:function(a){return c(this,a,new NodeList)}},e={getElementsByTagName:function(a){return this.querySelectorAll(a)},getElementsByClassName:function(a){return this.querySelectorAll("."+a)},getElementsByTagNameNS:function(a,b){if("*"===a)return this.getElementsByTagName(b);for(var c=new NodeList,d=this.getElementsByTagName(b),e=0,f=0;e<d.length;e++)d[e].namespaceURI===a&&(c[f++]=d[e]);
-return c.length=f,c}};a.GetElementsByInterface=e,a.SelectorsInterface=d}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}function c(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}var d=a.wrappers.NodeList,e={get firstElementChild(){return b(this.firstChild)},get lastElementChild(){return c(this.lastChild)},get childElementCount(){for(var a=0,b=this.firstElementChild;b;b=b.nextElementSibling)a++;return a},get children(){for(var a=new d,b=0,c=this.firstElementChild;c;c=c.nextElementSibling)a[b++]=c;return a.length=b,a}},f={get nextElementSibling(){return b(this.nextSibling)},get previousElementSibling(){return c(this.previousSibling)}};a.ChildNodeInterface=f,a.ParentNodeInterface=e}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}var c=a.ChildNodeInterface,d=a.wrappers.Node,e=a.mixin,f=a.registerWrapper,g=window.CharacterData;b.prototype=Object.create(d.prototype),e(b.prototype,{get textContent(){return this.data},set textContent(a){this.data=a}}),e(b.prototype,c),f(g,b,document.createTextNode("")),a.wrappers.CharacterData=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(b,c){var d=b.parentNode;if(d&&d.shadowRoot){var e=a.getRendererForHost(d);e.dependsOnAttribute(c)&&e.invalidate()}}function c(a){g.call(this,a)}function d(a,c,d){var e=d||c;Object.defineProperty(a,c,{get:function(){return this.impl[c]},set:function(a){this.impl[c]=a,b(this,e)},configurable:!0,enumerable:!0})}var e=a.ChildNodeInterface,f=a.GetElementsByInterface,g=a.wrappers.Node,h=a.ParentNodeInterface,i=a.SelectorsInterface;a.addWrapNodeListMethod;var j=a.mixin,k=a.oneOf,l=a.registerWrapper,m=a.wrappers,n=new WeakMap,o=window.Element,p=k(o.prototype,["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"]),q=o.prototype[p];c.prototype=Object.create(g.prototype),j(c.prototype,{createShadowRoot:function(){var b=new m.ShadowRoot(this);n.set(this,b);var c=a.getRendererForHost(this);return c.invalidate(),b},get shadowRoot(){return n.get(this)||null},setAttribute:function(a,c){this.impl.setAttribute(a,c),b(this,a)},removeAttribute:function(a){this.impl.removeAttribute(a),b(this,a)},matches:function(a){return q.call(this.impl,a)}}),c.prototype[p]=function(a){return this.matches(a)},o.prototype.webkitCreateShadowRoot&&(c.prototype.webkitCreateShadowRoot=c.prototype.createShadowRoot),d(c.prototype,"id"),d(c.prototype,"className","class"),j(c.prototype,e),j(c.prototype,f),j(c.prototype,h),j(c.prototype,i),l(o,c),a.matchesName=p,a.wrappers.Element=c}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a){case"&":return"&";case"<":return"<";case'"':return"""}}function c(a){return a.replace(p,b)}function d(a){switch(a.nodeType){case Node.ELEMENT_NODE:for(var b,d=a.tagName.toLowerCase(),f="<"+d,g=a.attributes,h=0;b=g[h];h++)f+=" "+b.name+'="'+c(b.value)+'"';return f+=">",q[d]?f:f+e(a)+"</"+d+">";case Node.TEXT_NODE:return c(a.nodeValue);case Node.COMMENT_NODE:return"<!--"+c(a.nodeValue)+"-->";default:throw console.error(a),new Error("not implemented")}}function e(a){for(var b="",c=a.firstChild;c;c=c.nextSibling)b+=d(c);return b}function f(a,b,c){var d=c||"div";a.textContent="";var e=n(a.ownerDocument.createElement(d));e.innerHTML=b;for(var f;f=e.firstChild;)a.appendChild(o(f))}function g(a){j.call(this,a)}function h(b){k(g,b,function(){return a.renderAllPending(),this.impl[b]})}function i(b){Object.defineProperty(g.prototype,b,{value:function(){return a.renderAllPending(),this.impl[b].apply(this.impl,arguments)},configurable:!0,enumerable:!0})}var j=a.wrappers.Element,k=a.defineGetter,l=a.mixin,m=a.registerWrapper,n=a.unwrap,o=a.wrap,p=/&|<|"/g,q={area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},r=window.HTMLElement;g.prototype=Object.create(j.prototype),l(g.prototype,{get innerHTML(){return e(this)},set innerHTML(a){this.invalidateShadowRenderer()?f(this,a,this.tagName):this.impl.innerHTML=a},get outerHTML(){return d(this)},set outerHTML(a){var b=this.parentNode;b&&(b.invalidateShadowRenderer(),this.impl.outerHTML=a)}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollLeft","scrollTop","scrollWidth"].forEach(h),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(i),m(r,g,document.createElement("b")),a.wrappers.HTMLElement=g,a.getInnerHTML=e,a.setInnerHTML=f}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLContentElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get select(){return this.getAttribute("select")},set select(a){this.setAttribute("select",a)},setAttribute:function(a,b){c.prototype.setAttribute.call(this,a,b),"select"===String(a).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),f&&e(f,b),a.wrappers.HTMLContentElement=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLShadowElement;b.prototype=Object.create(c.prototype),d(b.prototype,{}),f&&e(f,b),a.wrappers.HTMLShadowElement=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){if(!a.defaultView)return a;var b=m.get(a);if(!b){for(b=a.implementation.createHTMLDocument("");b.lastChild;)b.removeChild(b.lastChild);m.set(a,b)}return b}function c(a){for(var c,d=b(a.ownerDocument),e=j(d.createDocumentFragment());c=a.firstChild;)e.appendChild(c);return e}function d(a){if(e.call(this,a),!n){var b=c(a);l.set(this,k(b))}}var e=a.wrappers.HTMLElement,f=a.getInnerHTML,g=a.mixin,h=a.registerWrapper,i=a.setInnerHTML,j=a.unwrap,k=a.wrap,l=new WeakMap,m=new WeakMap,n=window.HTMLTemplateElement;d.prototype=Object.create(e.prototype),g(d.prototype,{get content(){return n?k(this.impl.content):l.get(this)},get innerHTML(){return f(this.content)},set innerHTML(a){i(this.content,a)}}),n&&h(n,d),a.wrappers.HTMLTemplateElement=d}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a.localName){case"content":return new c(a);case"shadow":return new e(a);case"template":return new f(a)}d.call(this,a)}var c=a.wrappers.HTMLContentElement,d=a.wrappers.HTMLElement,e=a.wrappers.HTMLShadowElement,f=a.wrappers.HTMLTemplateElement;a.mixin;var g=a.registerWrapper,h=window.HTMLUnknownElement;b.prototype=Object.create(d.prototype),g(h,b),a.wrappers.HTMLUnknownElement=b}(this.ShadowDOMPolyfill),function(a){"use strict";var b=a.GetElementsByInterface,c=a.ParentNodeInterface,d=a.SelectorsInterface,e=a.mixin,f=a.registerObject,g=f(document.createDocumentFragment());e(g.prototype,c),e(g.prototype,d),e(g.prototype,b);var h=f(document.createTextNode("")),i=f(document.createComment(""));a.wrappers.Comment=i,a.wrappers.DocumentFragment=g,a.wrappers.Text=h}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=i(a.impl.ownerDocument.createDocumentFragment());c.call(this,b),g(b,this);var d=a.shadowRoot;k.set(this,d),j.set(this,a)}var c=a.wrappers.DocumentFragment,d=a.elementFromPoint,e=a.getInnerHTML,f=a.mixin,g=a.rewrap,h=a.setInnerHTML,i=a.unwrap,j=new WeakMap,k=new WeakMap;b.prototype=Object.create(c.prototype),f(b.prototype,{get innerHTML(){return e(this)},set innerHTML(a){h(this,a),this.invalidateShadowRenderer()},get olderShadowRoot(){return k.get(this)||null},invalidateShadowRenderer:function(){return j.get(this).invalidateShadowRenderer()},elementFromPoint:function(a,b){return d(this,this.ownerDocument,a,b)},getElementById:function(a){return this.querySelector("#"+a)}}),a.wrappers.ShadowRoot=b,a.getHostForShadowRoot=function(a){return j.get(a)}}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){a.previousSibling_=a.previousSibling,a.nextSibling_=a.nextSibling,a.parentNode_=a.parentNode}function c(a,c,e){var f=G(a),g=G(c),h=e?G(e):null;if(d(c),b(c),e)a.firstChild===e&&(a.firstChild_=e),e.previousSibling_=e.previousSibling;else{a.lastChild_=a.lastChild,a.lastChild===a.firstChild&&(a.firstChild_=a.firstChild);var i=H(f.lastChild);i&&(i.nextSibling_=i.nextSibling)}f.insertBefore(g,h)}function d(a){var c=G(a),d=c.parentNode;if(d){var e=H(d);b(a),a.previousSibling&&(a.previousSibling.nextSibling_=a),a.nextSibling&&(a.nextSibling.previousSibling_=a),e.lastChild===a&&(e.lastChild_=a),e.firstChild===a&&(e.firstChild_=a),d.removeChild(c)}}function e(a,b){g(b).push(a),x(a,b);var c=J.get(a);c||J.set(a,c=[]),c.push(b)}function f(a){I.set(a,[])}function g(a){return I.get(a)}function h(a){for(var b=[],c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b}function i(a,b,c){for(var d=a.firstChild;d;d=d.nextSibling)if(b(d)){if(c(d)===!1)return}else i(d,b,c)}function j(a,b){var c=b.getAttribute("select");if(!c)return!0;if(c=c.trim(),!c)return!0;if(!(a instanceof y))return!1;if(!N.test(c))return!1;if(":"===c[0]&&!O.test(c))return!1;try{return a.matches(c)}catch(d){return!1}}function k(){for(var a=0;a<Q.length;a++)Q[a].render();Q=[]}function l(){E=null,k()}function m(a){var b=L.get(a);return b||(b=new q(a),L.set(a,b)),b}function n(a){for(;a;a=a.parentNode)if(a instanceof C)return a;return null}function o(a){return m(D(a))}function p(a){this.skip=!1,this.node=a,this.childNodes=[]}function q(a){this.host=a,this.dirty=!1,this.invalidateAttributes(),this.associateNode(a)}function r(a){return a instanceof z}function s(a){return a instanceof z}function t(a){return a instanceof A}function u(a){return a instanceof A}function v(a){return a.shadowRoot}function w(a){for(var b=[],c=a.shadowRoot;c;c=c.olderShadowRoot)b.push(c);return b}function x(a,b){K.set(a,b)}var y=a.wrappers.Element,z=a.wrappers.HTMLContentElement,A=a.wrappers.HTMLShadowElement,B=a.wrappers.Node,C=a.wrappers.ShadowRoot;a.assert;var D=a.getHostForShadowRoot;a.mixin;var E,F=a.oneOf,G=a.unwrap,H=a.wrap,I=new WeakMap,J=new WeakMap,K=new WeakMap,L=new WeakMap,M=new WeakMap,N=/^[*.:#[a-zA-Z_|]/,O=new RegExp("^:("+["link","visited","target","enabled","disabled","checked","indeterminate","nth-child","nth-last-child","nth-of-type","nth-last-of-type","first-child","last-child","first-of-type","last-of-type","only-of-type"].join("|")+")"),P=F(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","setTimeout"]),Q=[],R=new ArraySplice;R.equals=function(a,b){return G(a.node)===b},p.prototype={append:function(a){var b=new p(a);return this.childNodes.push(b),b},sync:function(a){if(!this.skip){for(var b=this.node,e=this.childNodes,f=h(G(b)),g=a||new WeakMap,i=R.calculateSplices(e,f),j=0,k=0,l=0,m=0;m<i.length;m++){for(var n=i[m];l<n.index;l++)k++,e[j++].sync(g);for(var o=n.removed.length,p=0;o>p;p++){var q=H(f[k++]);g.get(q)||d(q)}for(var r=n.addedCount,s=f[k]&&H(f[k]),p=0;r>p;p++){var t=e[j++],u=t.node;c(b,u,s),g.set(u,!0),t.sync(g)}l+=r}for(var m=l;m<e.length;m++)e[m++].sync(g)}}},q.prototype={render:function(a){if(this.dirty){this.invalidateAttributes(),this.treeComposition();var b=this.host,c=b.shadowRoot;this.associateNode(b);for(var d=!e,e=a||new p(b),f=c.firstChild;f;f=f.nextSibling)this.renderNode(c,e,f,!1);d&&e.sync(),this.dirty=!1}},invalidate:function(){if(!this.dirty){if(this.dirty=!0,Q.push(this),E)return;E=window[P](l,0)}},renderNode:function(a,b,c,d){if(v(c)){b=b.append(c);var e=m(c);e.dirty=!0,e.render(b)}else r(c)?this.renderInsertionPoint(a,b,c,d):t(c)?this.renderShadowInsertionPoint(a,b,c):this.renderAsAnyDomTree(a,b,c,d)},renderAsAnyDomTree:function(a,b,c,d){if(b=b.append(c),v(c)){var e=m(c);b.skip=!e.dirty,e.render(b)}else for(var f=c.firstChild;f;f=f.nextSibling)this.renderNode(a,b,f,d)},renderInsertionPoint:function(a,b,c,d){var e=g(c);if(e.length){this.associateNode(c);for(var f=0;f<e.length;f++){var h=e[f];r(h)&&d?this.renderInsertionPoint(a,b,h,d):this.renderAsAnyDomTree(a,b,h,d)}}else this.renderFallbackContent(a,b,c);this.associateNode(c.parentNode)},renderShadowInsertionPoint:function(a,b,c){var d=a.olderShadowRoot;if(d){x(d,c),this.associateNode(c.parentNode);for(var e=d.firstChild;e;e=e.nextSibling)this.renderNode(d,b,e,!0)}else this.renderFallbackContent(a,b,c)},renderFallbackContent:function(a,b,c){this.associateNode(c),this.associateNode(c.parentNode);for(var d=c.firstChild;d;d=d.nextSibling)this.renderAsAnyDomTree(a,b,d,!1)},invalidateAttributes:function(){this.attributes=Object.create(null)},updateDependentAttributes:function(a){if(a){var b=this.attributes;/\.\w+/.test(a)&&(b["class"]=!0),/#\w+/.test(a)&&(b.id=!0),a.replace(/\[\s*([^\s=\|~\]]+)/g,function(a,c){b[c]=!0})}},dependsOnAttribute:function(a){return this.attributes[a]},distribute:function(a,b){var c=this;i(a,s,function(a){f(a),c.updateDependentAttributes(a.getAttribute("select"));for(var d=0;d<b.length;d++){var g=b[d];void 0!==g&&j(g,a)&&(e(g,a),b[d]=void 0)}})},treeComposition:function(){for(var a=this.host,b=a.shadowRoot,c=[],d=a.firstChild;d;d=d.nextSibling)if(r(d)){var e=g(d);e&&e.length||(e=h(d)),c.push.apply(c,e)}else c.push(d);for(var f,j;b;){if(f=void 0,i(b,u,function(a){return f=a,!1}),j=f,this.distribute(b,c),j){var k=b.olderShadowRoot;if(k){b=k,x(b,j);continue}break}break}},associateNode:function(a){M.set(a,this)}},B.prototype.invalidateShadowRenderer=function(){var a=M.get(this);return a?(a.invalidate(),!0):!1},z.prototype.getDistributedNodes=function(){var a=M.get(this);return a&&a.render(),g(this)},A.prototype.nodeWasAdded_=z.prototype.nodeWasAdded_=function(){this.invalidateShadowRenderer();var a,b=n(this);b&&(a=o(b)),M.set(this,a),a&&a.invalidate()},a.eventParentsTable=J,a.getRendererForHost=m,a.getShadowTrees=w,a.insertionParentTable=K,a.renderAllPending=k,a.visual={insertBefore:c,remove:d}}(this.ShadowDOMPolyfill),function(a){"use strict";function b(b){if(window[b]){d(!a.wrappers[b]);var i=function(a){c.call(this,a)};i.prototype=Object.create(c.prototype),e(i.prototype,{get form(){return h(g(this).form)}}),f(window[b],i,document.createElement(b.slice(4,-7))),a.wrappers[b]=i}}var c=a.wrappers.HTMLElement,d=a.assert,e=a.mixin,f=a.registerWrapper,g=a.unwrap,h=a.wrap,i=["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLKeygenElement","HTMLLabelElement","HTMLLegendElement","HTMLObjectElement","HTMLOptionElement","HTMLOutputElement","HTMLSelectElement","HTMLTextAreaElement"];i.forEach(b)}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){k.call(this,a)}function c(a){var c=document[a];b.prototype[a]=function(){return v(c.apply(this.impl,arguments))}}function d(a,b){y.call(b.impl,u(a)),e(a,b)}function e(a,b){a.shadowRoot&&b.adoptNode(a.shadowRoot),a instanceof n&&f(a,b);for(var c=a.firstChild;c;c=c.nextSibling)e(c,b)}function f(a,b){var c=a.olderShadowRoot;c&&b.adoptNode(c)}function g(a){this.impl=a}function h(a,b){var c=document.implementation[b];a.prototype[b]=function(){return v(c.apply(this.impl,arguments))}}function i(a,b){var c=document.implementation[b];a.prototype[b]=function(){return c.apply(this.impl,arguments)}}var j=a.GetElementsByInterface,k=a.wrappers.Node,l=a.ParentNodeInterface,m=a.SelectorsInterface,n=a.wrappers.ShadowRoot,o=a.defineWrapGetter,p=a.elementFromPoint,q=a.forwardMethodsToWrapper,r=a.matchesName,s=a.mixin,t=a.registerWrapper,u=a.unwrap,v=a.wrap,w=a.wrapEventTargetMethods;a.wrapNodeList;var x=new WeakMap;b.prototype=Object.create(k.prototype),o(b,"documentElement"),o(b,"body"),o(b,"head"),["createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","getElementById"].forEach(c);var y=document.adoptNode;if(s(b.prototype,{adoptNode:function(a){return a.parentNode&&a.parentNode.removeChild(a),d(a,this),a},elementFromPoint:function(a,b){return p(this,this,a,b)}}),document.register){var z=document.register;b.prototype.register=function(b,c){function d(a){return a?(this.impl=a,void 0):document.createElement(b)}var e=c.prototype;if(a.nativePrototypeTable.get(e))throw new Error("NotSupportedError");for(var f,g=Object.getPrototypeOf(e),h=[];g&&!(f=a.nativePrototypeTable.get(g));)h.push(g),g=Object.getPrototypeOf(g);if(!f)throw new Error("NotSupportedError");for(var i=Object.create(f),j=h.length-1;j>=0;j--)i=Object.create(i);return["createdCallback","enteredDocumentCallback","leftDocumentCallback","attributeChangedCallback"].forEach(function(a){var b=e[a];b&&(i[a]=function(){b.apply(v(this),arguments)})}),z.call(u(this),b,{prototype:i}),d.prototype=e,d.prototype.constructor=d,a.constructorTable.set(i,d),a.nativePrototypeTable.set(e,i),d},q([window.HTMLDocument||window.Document],["register"])}q([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild",r]),q([window.HTMLDocument||window.Document],["adoptNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById"]),s(b.prototype,j),s(b.prototype,l),s(b.prototype,m),s(b.prototype,{get implementation(){var a=x.get(this);return a?a:(a=new g(u(this).implementation),x.set(this,a),a)}}),t(window.Document,b,document.implementation.createHTMLDocument("")),window.HTMLDocument&&t(window.HTMLDocument,b),w([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),h(g,"createDocumentType"),h(g,"createDocument"),h(g,"createHTMLDocument"),i(g,"hasFeature"),t(window.DOMImplementation,g),q([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),a.adoptNodeNoRemove=d,a.wrappers.DOMImplementation=g,a.wrappers.Document=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.EventTarget,d=a.mixin,e=a.registerWrapper,f=a.unwrap,g=a.unwrapIfNeeded,h=a.wrap,i=a.renderAllPending,j=window.Window;b.prototype=Object.create(c.prototype);var k=window.getComputedStyle;j.prototype.getComputedStyle=function(a,b){return i(),k.call(this||window,g(a),b)},["addEventListener","removeEventListener","dispatchEvent"].forEach(function(a){j.prototype[a]=function(){var b=h(this||window);return b[a].apply(b,arguments)}}),d(b.prototype,{getComputedStyle:function(a,b){return k.call(f(this),g(a),b)}}),e(j,b),a.wrappers.Window=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}function c(a){return new b(a)}function d(a){return a.map(c)}function e(a){var b=this;this.impl=new k(function(c){a.call(b,d(c),b)})}var f=a.defineGetter,g=a.defineWrapGetter,h=a.registerWrapper,i=a.unwrapIfNeeded,j=a.wrapNodeList;a.wrappers;var k=window.MutationObserver||window.WebKitMutationObserver;if(k){var l=window.MutationRecord;b.prototype={get addedNodes(){return j(this.impl.addedNodes)},get removedNodes(){return j(this.impl.removedNodes)}},["target","previousSibling","nextSibling"].forEach(function(a){g(b,a)}),["type","attributeName","attributeNamespace","oldValue"].forEach(function(a){f(b,a,function(){return this.impl[a]})}),l&&h(l,b),window.Node,e.prototype={observe:function(a,b){this.impl.observe(i(a),b)},disconnect:function(){this.impl.disconnect()},takeRecords:function(){return d(this.impl.takeRecords())}},a.wrappers.MutationObserver=e,a.wrappers.MutationRecord=b}}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.registerWrapper,d=a.unwrap,e=a.unwrapIfNeeded,f=a.wrap,g=window.Range;b.prototype={get startContainer(){return f(this.impl.startContainer)},get endContainer(){return f(this.impl.endContainer)},get commonAncestorContainer(){return f(this.impl.commonAncestorContainer)},setStart:function(a,b){this.impl.setStart(e(a),b)},setEnd:function(a,b){this.impl.setEnd(e(a),b)},setStartBefore:function(a){this.impl.setStartBefore(e(a))},setStartAfter:function(a){this.impl.setStartAfter(e(a))},setEndBefore:function(a){this.impl.setEndBefore(e(a))},setEndAfter:function(a){this.impl.setEndAfter(e(a))},selectNode:function(a){this.impl.selectNode(e(a))},selectNodeContents:function(a){this.impl.selectNodeContents(e(a))},compareBoundaryPoints:function(a,b){return this.impl.compareBoundaryPoints(a,d(b))},extractContents:function(){return f(this.impl.extractContents())},cloneContents:function(){return f(this.impl.cloneContents())},insertNode:function(a){this.impl.insertNode(e(a))},surroundContents:function(a){this.impl.surroundContents(e(a))},cloneRange:function(){return f(this.impl.cloneRange())},isPointInRange:function(a,b){return this.impl.isPointInRange(e(a),b)},comparePoint:function(a,b){return this.impl.comparePoint(e(a),b)},intersectsNode:function(a){return this.impl.intersectsNode(e(a))}},g.prototype.createContextualFragment&&(b.prototype.createContextualFragment=function(a){return f(this.impl.createContextualFragment(a))}),c(window.Range,b),a.wrappers.Range=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=c[a],d=window[b];if(d){var e=document.createElement(a),f=e.constructor;window[b]=f}}a.isWrapperFor;var c={a:"HTMLAnchorElement",applet:"HTMLAppletElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",br:"HTMLBRElement",base:"HTMLBaseElement",body:"HTMLBodyElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",dl:"HTMLDListElement",datalist:"HTMLDataListElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",hr:"HTMLHRElement",head:"HTMLHeadElement",h1:"HTMLHeadingElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",input:"HTMLInputElement",li:"HTMLLIElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",link:"HTMLLinkElement",map:"HTMLMapElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",del:"HTMLModElement",ol:"HTMLOListElement",object:"HTMLObjectElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",table:"HTMLTableElement",tr:"HTMLTableRowElement",thead:"HTMLTableSectionElement",tbody:"HTMLTableSectionElement",textarea:"HTMLTextAreaElement",title:"HTMLTitleElement",ul:"HTMLUListElement",video:"HTMLVideoElement"};Object.keys(c).forEach(b),Object.getOwnPropertyNames(a.wrappers).forEach(function(b){window[b]=a.wrappers[b]}),a.knownElements=c}(this.ShadowDOMPolyfill),function(){var a=window.ShadowDOMPolyfill;a.wrap,Object.defineProperties(HTMLElement.prototype,{webkitShadowRoot:{get:function(){return this.shadowRoot}}}),HTMLElement.prototype.webkitCreateShadowRoot=HTMLElement.prototype.createShadowRoot,window.dartExperimentalFixupGetTag=function(b){function c(a){if(a instanceof d)return"NodeList";if(a instanceof e)return"ShadowRoot";if(a instanceof MutationRecord)return"MutationRecord";if(a instanceof MutationObserver)return"MutationObserver";var c=f(a);if(a!==c){var g=a.constructor;if(g===c.constructor){var h=g._ShadowDOMPolyfill$cacheTag_;return h||(h=Object.prototype.toString.call(c),h=h.substring(8,h.length-1),g._ShadowDOMPolyfill$cacheTag_=h),h}a=c}return b(a)}var d=a.wrappers.NodeList,e=a.wrappers.ShadowRoot,f=a.unwrapIfNeeded;return c}}();var Platform={};!function(a){function b(a,b){var c="";return Array.prototype.forEach.call(a,function(a){c+=a.textContent+"\n\n"}),b||(c=c.replace(m,"")),c}function c(a){var b=document.createElement("style");b.textContent=a,document.head.appendChild(b);var c=b.sheet.cssRules;return b.parentNode.removeChild(b),c}function d(a){for(var b=0,c=[];b<a.length;b++)c.push(a[b].cssText);return c.join("\n\n")}function e(a){a&&f().appendChild(document.createTextNode(a))}function f(){return g||(g=document.createElement("style"),g.setAttribute("ShadowCSSShim","")),g}var g,h={strictStyling:!1,registry:{},shimStyling:function(a,b,c){if(a){var d=this.registerDefinition(a,b,c);this.strictStyling&&this.applyScopeToContent(a,b),this.shimPolyfillDirectives(d.rootStyles,b),this.applyShimming(d.scopeStyles,b)}},shimShadowDOMStyling:function(a,b){this.shimPolyfillDirectives(a,b),this.applyShimming(a,b)},registerDefinition:function(a,b,c){var d=this.registry[b]={root:a,name:b,extendsName:c},e=a.querySelectorAll("style");e=e?Array.prototype.slice.call(e,0):[],d.rootStyles=e,d.scopeStyles=d.rootStyles;var f=this.registry[d.extendsName];return f&&(d.scopeStyles=d.scopeStyles.concat(f.scopeStyles)),d},applyScopeToContent:function(a,b){a&&(Array.prototype.forEach.call(a.querySelectorAll("*"),function(a){a.setAttribute(b,"")}),Array.prototype.forEach.call(a.querySelectorAll("template"),function(a){this.applyScopeToContent(a.content,b)},this))},shimPolyfillDirectives:function(a,b){a&&Array.prototype.forEach.call(a,function(a){a.textContent=this.convertPolyfillDirectives(a.textContent,b)},this)},convertPolyfillDirectives:function(a,b){for(var c,d,e="",f=0;c=n.exec(a);)e+=a.substring(f,c.index),d=c[1].slice(0,-2).replace(q,b),e+=this.scopeSelector(d,b)+"{",f=n.lastIndex;return e+=a.substring(f,a.length)},applyShimming:function(a,b){var c=this.shimAtHost(a,b);c+=this.shimScoping(a,b),e(c)},shimAtHost:function(a,b){return a?this.convertAtHostStyles(a,b):void 0},convertAtHostStyles:function(a,e){for(var f,g=b(a),h="",j=0;f=i.exec(g);)h+=g.substring(j,f.index),h+=this.scopeHostCss(f[1],e),j=i.lastIndex;h+=g.substring(j,g.length);var k=new RegExp("^"+e+p,"m"),g=d(this.findAtHostRules(c(h),k));return g},scopeHostCss:function(a,b){for(var c,d="";c=j.exec(a);)d+=this.scopeHostSelector(c[1],b)+" "+c[2]+"\n ";return d},scopeHostSelector:function(a,b){var c=[],d=a.split(","),e="[is="+b+"]";return d.forEach(function(a){a=a.trim(),a.match(k)?a=a.replace(k,b+"$1$3, "+e+"$1$3"):a.match(l)&&(a=b+a+", "+e+a),c.push(a)},this),c.join(", ")},findAtHostRules:function(a,b){return Array.prototype.filter.call(a,this.isHostRule.bind(this,b))},isHostRule:function(a,b){return b.selectorText&&b.selectorText.match(a)||b.cssRules&&this.findAtHostRules(b.cssRules,a).length||b.type==CSSRule.WEBKIT_KEYFRAMES_RULE},shimScoping:function(a,b){return a?this.convertScopedStyles(a,b):void 0},convertScopedStyles:function(a,d){Array.prototype.forEach.call(a,function(a){a.parentNode&&a.parentNode.removeChild(a)});var e=b(a).replace(i,"");e=this.convertPseudos(e);var f=c(e);return e=this.scopeRules(f,d)},convertPseudos:function(a){return a.replace(o," [pseudo=$1]")},scopeRules:function(a,b){var c="";return Array.prototype.forEach.call(a,function(a){a.selectorText&&a.style&&a.style.cssText?(c+=this.scopeSelector(a.selectorText,b,this.strictStyling)+" {\n ",c+=this.propertiesFromRule(a)+"\n}\n\n"):a.media?(c+="@media "+a.media.mediaText+" {\n",c+=this.scopeRules(a.cssRules,b),c+="\n}\n\n"):a.cssText&&(c+=a.cssText+"\n\n")},this),c},scopeSelector:function(a,b,c){var d=[],e=a.split(",");return e.forEach(function(a){a=a.trim(),this.selectorNeedsScoping(a,b)&&(a=c?this.applyStrictSelectorScope(a,b):this.applySimpleSelectorScope(a,b)),d.push(a)},this),d.join(", ")},selectorNeedsScoping:function(a,b){var c="("+b+"|\\[is="+b+"\\])",d=new RegExp("^"+c+p,"m");return!a.match(d)},applySimpleSelectorScope:function(a,b){return b+" "+a+", "+"[is="+b+"] "+a},applyStrictSelectorScope:function(a,b){var c=[" ",">","+","~"],d=a,e="["+b+"]";return c.forEach(function(a){var b=d.split(a);d=b.map(function(a){var b=a.trim();return b&&c.indexOf(b)<0&&b.indexOf(e)<0&&(a=b.replace(/([^:]*)(:*)(.*)/,"$1"+e+"$2$3")),a}).join(a)}),d},propertiesFromRule:function(a){var b=a.style.cssText;return a.style.content&&!a.style.content.match(/['"]+/)&&(b="content: '"+a.style.content+"';\n"+a.style.cssText.replace(/content:[^;]*;/g,"")),b}},i=/@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,j=/([^{]*)({[\s\S]*?})/gim,k=/(.*)((?:\*)|(?:\:scope))(.*)/,l=/^[.\[:]/,m=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,n=/\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,o=/::(x-[^\s{,(]*)/gim,p="([>\\s~+[.,{:][\\s\\S]*)?$",q=/@host/gim;if(window.ShadowDOMPolyfill){e("style { display: none !important; }\n");var r=document.querySelector("head");r.insertBefore(f(),r.childNodes[0])}a.ShadowCSS=h}(window.Platform),function(a){function b(a,b){if(window.ShadowDOMPolyfill){for(var h,i=this.convertPolyfillDirectives(a,b),j="",k=0;h=e.exec(i);)j+=i.substring(k,h.index),j+=this.scopeHostCss(h[1],b),k=e.lastIndex;j+=i.substring(k,i.length);var l=new RegExp("^"+b+g,"m"),m=d(this.findAtHostRules(c(j),l));i=i.replace(f,""),i=this.convertPseudos(i);var n=c(i),o=this.scopeRules(n,b);return m+o}}function c(a){var b=document.createElement("style");b.textContent=a,document.head.appendChild(b);var c=b.sheet.cssRules;return b.parentNode.removeChild(b),c}function d(a){for(var b=0,c=[];b<a.length;b++)c.push(a[b].cssText);return c.join("\n\n")}var e=/@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,f=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,g="([>\\s~+[.,{:][\\s\\S]*)?$";a.ShadowCSS.shimShadowDOMStyling2=b}(window.Platform)}
\ No newline at end of file
+if(!HTMLElement.prototype.createShadowRoot||window.__forceShadowDomPolyfill){!function(){Element.prototype.webkitCreateShadowRoot&&(Element.prototype.webkitCreateShadowRoot=function(){return window.ShadowDOMPolyfill.wrapIfNeeded(this).createShadowRoot()})}(),function(a){"use strict";function b(){function a(a){"splice"===a[0].type&&"splice"===a[1].type&&(b=!0)}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=!1,c=[0];return Array.observe(c,a),c[1]=1,c.length=0,Object.deliverChangeRecords(a),b}function c(){if(a.document&&"securityPolicy"in a.document&&!a.document.securityPolicy.allowsEval)return!1;try{var b=new Function("","return true;");return b()}catch(c){return!1}}function d(a){return+a===a>>>0}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:H(a)&&H(b)?!0:a!==a&&b!==b}function h(a){return"string"!=typeof a?!1:(a=a.trim(),""==a?!0:"."==a[0]?!1:P.test(a))}function i(a,b){if(b!==Q)throw Error("Use Path.get to retrieve path objects");return""==a.trim()?this:d(a)?(this.push(a),this):(a.split(/\s*\.\s*/).filter(function(a){return a}).forEach(function(a){this.push(a)},this),G&&!F&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn()),void 0)}function j(a){if(a instanceof i)return a;null==a&&(a=""),"string"!=typeof a&&(a=String(a));var b=R[a];if(b)return b;if(!h(a))return S;var b=new i(a,Q);return R[a]=b,b}function k(b){for(var c=0;T>c&&b.check();)b.report(),c++;a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=c)}function l(a){for(var b in a)return!1;return!0}function m(a){return l(a.added)&&l(a.removed)&&l(a.changed)}function n(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function o(a,b){var c=b||(Array.isArray(a)?[]:{});for(var d in a)c[d]=a[d];return Array.isArray(a)&&(c.length=a.length),c}function p(a,b,c,d){if(this.closed=!1,this.object=a,this.callback=b,this.target=c,this.token=d,this.reporting=!0,F){var e=this;this.boundInternalCallback=function(a){e.internalCallback(a)}}q(this)}function q(a){V&&(U.push(a),p._allObserversCount++)}function r(a,b,c,d){p.call(this,a,b,c,d),this.connect(),this.sync(!0)}function s(a,b,c,d){if(!Array.isArray(a))throw Error("Provided object is not an Array");r.call(this,a,b,c,d)}function t(a){this.arr=[],this.callback=a,this.isObserved=!0}function u(a,b,c,d,e,g,h){var b=b instanceof i?b:j(b);return b&&b.length&&f(a)?(p.call(this,a,c,d,e),this.valueFn=g,this.setValueFn=h,this.path=b,this.connect(),this.sync(!0),void 0):(this.value_=b?b.getValueFrom(a):void 0,this.value=g?g(this.value_):this.value_,this.closed=!0,void 0)}function v(a,b,c,d){p.call(this,void 0,a,b,c),this.valueFn=d,this.observed=[],this.values=[],this.value=void 0,this.oldValue=void 0,this.oldValues=void 0,this.changeFlags=void 0,this.started=!1}function w(a,b){if("function"==typeof Object.observe){var c=Object.getNotifier(a);return function(d,e){var f={object:a,type:d,name:b};2===arguments.length&&(f.oldValue=e),c.notify(f)}}}function x(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];$[g.type]?(g.name in c||(c[g.name]=g.oldValue),"updated"!=g.type&&("new"!=g.type?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function y(a,b,c){return{index:a,removed:b,addedCount:c}}function z(){}function A(a,b,c,d,e,f){return db.calcSplices(a,b,c,d,e,f)}function B(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function C(a,b,c,d){for(var e=y(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=B(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function D(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case"splice":C(c,g.index,g.removed.slice(),g.addedCount);break;case"new":case"updated":case"deleted":if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;C(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function E(a,b){var c=[];return D(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?(b.removed[0]!==a[b.index]&&c.push(b),void 0):(c=c.concat(A(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)),void 0)}),c}var F=b(),G=c(),H=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},I="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},J="[$_a-zA-Z]",K="[$_a-zA-Z0-9]",L=J+"+"+K+"*",M="(?:[0-9]|[1-9]+[0-9]+)",N="(?:"+L+"|"+M+")",O="(?:"+N+")(?:\\s*\\.\\s*"+N+")*",P=new RegExp("^"+O+"$"),Q={},R={};i.get=j,i.prototype=I({__proto__:[],valid:!0,toString:function(){return this.join(".")},getValueFrom:function(a,b){for(var c=0;c<this.length;c++){if(null==a)return;b&&b.observe(a),a=a[this[c]]}return a},compiledGetValueFromFn:function(){var a=this.map(function(a){return d(a)?'["'+a+'"]':"."+a}),b="",c="obj";b+="if (obj != null";for(var e=0;e<this.length-1;e++)this[e],c+=a[e],b+=" &&\n "+c+" != null";return b+=")\n",c+=a[e],b+=" return "+c+";\nelse\n return undefined;",new Function("obj",b)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var S=new i("",Q);S.valid=!1,S.getValueFrom=S.setValueFrom=function(){};var T=1e3;p.prototype={internalCallback:function(a){this.closed||this.reporting&&this.check(a)&&(this.report(),this.testingResults&&(this.testingResults.anyChanged=!0))},close:function(){this.closed||(this.object&&"function"==typeof this.object.close&&this.object.close(),this.disconnect(),this.object=void 0,this.closed=!0)},deliver:function(a){this.closed||(F?(this.testingResults=a,Object.deliverChangeRecords(this.boundInternalCallback),this.testingResults=void 0):k(this))},report:function(){this.reporting&&(this.sync(!1),this.callback&&(this.reportArgs.push(this.token),this.invokeCallback(this.reportArgs)),this.reportArgs=void 0)},invokeCallback:function(a){try{this.callback.apply(this.target,a)}catch(b){p._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},reset:function(){this.closed||(F&&(this.reporting=!1,Object.deliverChangeRecords(this.boundInternalCallback),this.reporting=!0),this.sync(!0))}};var U,V=!F||a.forceCollectObservers;p._allObserversCount=0,V&&(U=[]);var W=!1,X="function"==typeof Object.deliverAllChangeRecords;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!W){if(X)return Object.deliverAllChangeRecords(),void 0;if(V){W=!0;var b=0,c={};do{b++;var d=U;U=[],c.anyChanged=!1;for(var e=0;e<d.length;e++){var f=d[e];f.closed||(F?f.deliver(c):f.check()&&(c.anyChanged=!0,f.report()),U.push(f))}}while(T>b&&c.anyChanged);a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=b),p._allObserversCount=U.length,W=!1}}},V&&(a.Platform.clearObservers=function(){U=[]}),r.prototype=I({__proto__:p.prototype,connect:function(){F&&Object.observe(this.object,this.boundInternalCallback)},sync:function(){F||(this.oldObject=o(this.object))},check:function(a){var b,c;if(F){if(!a)return!1;c={},b=x(this.object,a,c)}else c=this.oldObject,b=n(this.object,this.oldObject);return m(b)?!1:(this.reportArgs=[b.added||{},b.removed||{},b.changed||{}],this.reportArgs.push(function(a){return c[a]}),!0)},disconnect:function(){F?this.object&&Object.unobserve(this.object,this.boundInternalCallback):this.oldObject=void 0}}),s.prototype=I({__proto__:r.prototype,connect:function(){F&&Array.observe(this.object,this.boundInternalCallback)},sync:function(){F||(this.oldObject=this.object.slice())},check:function(a){var b;if(F){if(!a)return!1;b=E(this.object,a)}else b=A(this.object,0,this.object.length,this.oldObject,0,this.oldObject.length);return b&&b.length?(this.reportArgs=[b],!0):!1}}),s.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})};var Y=Object.getPrototypeOf({}),Z=Object.getPrototypeOf([]);t.prototype={reset:function(){this.isObserved=!this.isObserved},observe:function(a){if(f(a)&&a!==Y&&a!==Z){var b=this.arr.indexOf(a);b>=0&&this.arr[b+1]===this.isObserved||(0>b&&(b=this.arr.length,this.arr[b]=a,Object.observe(a,this.callback)),this.arr[b+1]=this.isObserved,this.observe(Object.getPrototypeOf(a)))}},cleanup:function(){for(var a=0,b=0,c=this.isObserved;b<this.arr.length;){var d=this.arr[b];this.arr[b+1]==c?(b>a&&(this.arr[a]=d,this.arr[a+1]=c),a+=2):Object.unobserve(d,this.callback),b+=2}this.arr.length=a}},u.prototype=I({__proto__:p.prototype,connect:function(){F&&(this.observedSet=new t(this.boundInternalCallback))},disconnect:function(){this.value=void 0,this.value_=void 0,this.observedSet&&(this.observedSet.reset(),this.observedSet.cleanup(),this.observedSet=void 0)},check:function(){return this.observedSet&&this.observedSet.reset(),this.value_=this.path.getValueFrom(this.object,this.observedSet),this.observedSet&&this.observedSet.cleanup(),g(this.value_,this.oldValue_)?!1:(this.value=this.valueFn?this.valueFn(this.value_):this.value_,this.reportArgs=[this.value,this.oldValue],!0)},sync:function(a){a&&(this.observedSet&&this.observedSet.reset(),this.value_=this.path.getValueFrom(this.object,this.observedSet),this.value=this.valueFn?this.valueFn(this.value_):this.value_,this.observedSet&&this.observedSet.cleanup()),this.oldValue_=this.value_,this.oldValue=this.value},setValue:function(a){this.path&&("function"==typeof this.setValueFn&&(a=this.setValueFn(a)),this.path.setValueFrom(this.object,a))}}),v.prototype=I({__proto__:u.prototype,addPath:function(a,b){if(this.started)throw Error("Cannot add more paths once started.");var b=b instanceof i?b:j(b),c=b?b.getValueFrom(a):void 0;this.observed.push(a,b),this.values.push(c)},start:function(){this.connect(),this.sync(!0)},getValues:function(){this.observedSet&&this.observedSet.reset();for(var a=!1,b=0;b<this.observed.length;b+=2){var c=this.observed[b+1];if(c){var d=this.observed[b],e=c.getValueFrom(d,this.observedSet),f=this.values[b/2];if(!g(e,f)){if(!a&&!this.valueFn){this.oldValues=this.oldValues||[],this.changeFlags=this.changeFlags||[];for(var h=0;h<this.values.length;h++)this.oldValues[h]=this.values[h],this.changeFlags[h]=!1}this.valueFn||(this.changeFlags[b/2]=!0),this.values[b/2]=e,a=!0}}}return this.observedSet&&this.observedSet.cleanup(),a},check:function(){if(this.getValues()){if(this.valueFn){if(this.value=this.valueFn(this.values),g(this.value,this.oldValue))return!1;this.reportArgs=[this.value,this.oldValue]}else this.reportArgs=[this.values,this.oldValues,this.changeFlags];return!0}},sync:function(a){a&&(this.getValues(),this.valueFn&&(this.value=this.valueFn(this.values))),this.valueFn&&(this.oldValue=this.value)},close:function(){if(this.observed){for(var a=0;a<this.observed.length;a+=2){var b=this.observed[a];b&&"function"==typeof b.close&&b.close()}this.observed=void 0,this.values=void 0}p.prototype.close.call(this)}});var $={"new":!0,updated:!0,deleted:!0};u.defineProperty=function(a,b,c){var d=c.object,e=j(c.path),f=w(a,b),g=new u(d,c.path,function(a,b){f&&f("updated",b)});return Object.defineProperty(a,b,{get:function(){return e.getValueFrom(d)},set:function(a){e.setValueFrom(d,a)},configurable:!0}),{close:function(){var c=e.getValueFrom(d);f&&g.deliver(),g.close(),Object.defineProperty(a,b,{value:c,writable:!0,configurable:!0})}}};var _=0,ab=1,bb=2,cb=3;z.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(_):(e.push(ab),d=g),b--,c--):f==h?(e.push(cb),b--,d=h):(e.push(bb),c--,d=i)}else e.push(cb),b--;else e.push(bb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,0==c-b&&0==f-e)return[];if(b==c){for(var j=y(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[y(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case _:j&&(l.push(j),j=void 0),m++,n++;break;case ab:j||(j=y(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case bb:j||(j=y(m,[],0)),j.addedCount++,m++;break;case cb:j||(j=y(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var db=new z;a.Observer=p,a.Observer.hasObjectObserve=F,a.ArrayObserver=s,a.ArrayObserver.calculateSplices=function(a,b){return db.calculateSplices(a,b)},a.ArraySplice=z,a.ObjectObserver=r,a.PathObserver=u,a.CompoundPathObserver=v,a.Path=i}("undefined"!=typeof global&&global?global:this),("undefined"==typeof WeakMap||navigator.userAgent.indexOf("Firefox/")>-1)&&!function(){var a=Object.defineProperty,b=Date.now()%1e9,c=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")};c.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]:void 0},"delete":function(a){this.set(a,void 0)}},window.WeakMap=c}();var ShadowDOMPolyfill={};!function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a,b){return Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))}),a}function d(a,b){return Object.getOwnPropertyNames(b).forEach(function(c){switch(c){case"arguments":case"caller":case"length":case"name":case"prototype":case"toString":return}Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))}),a}function e(a,b){for(var c=0;c<b.length;c++)if(b[c]in a)return b[c]}function f(a){var b=a.__proto__||Object.getPrototypeOf(a),c=C.get(b);if(c)return c;var d=f(b),e=r(d);return o(b,e,a),e}function g(a,b){m(a,b,!0)}function h(a,b){m(b,a,!1)}function i(a){return/^on[a-z]+$/.test(a)}function j(a){return F?new Function("return this.impl."+a):function(){return this.impl[a]}}function k(a){return F?new Function("v","this.impl."+a+" = v"):function(b){this.impl[a]=b}}function l(a){return F?new Function("return this.impl."+a+".apply(this.impl, arguments)"):function(){return this.impl[a].apply(this.impl,arguments)}}function m(b,c,d){Object.getOwnPropertyNames(b).forEach(function(e){if(!(e in c)){I&&b.__lookupGetter__(e);var f;try{f=Object.getOwnPropertyDescriptor(b,e)}catch(g){f=J}var h,m;if(d&&"function"==typeof f.value)return c[e]=l(e),void 0;var n=i(e);h=n?a.getEventHandlerGetter(e):j(e),(f.writable||f.set)&&(m=n?a.getEventHandlerSetter(e):k(e)),Object.defineProperty(c,e,{get:h,set:m,configurable:f.configurable,enumerable:f.enumerable})}})}function n(a,b,c){var e=a.prototype;o(e,b,c),d(b,a)}function o(a,c,d){var e=c.prototype;b(void 0===C.get(a)),C.set(a,c),D.set(e,a),g(a,e),d&&h(e,d)}function p(a,b){return C.get(b.prototype)===a}function q(a){var b=Object.getPrototypeOf(a),c=f(b),d=r(c);return o(b,d,a),d}function r(a){function b(b){a.call(this,b)}return b.prototype=Object.create(a.prototype),b.prototype.constructor=b,b}function s(a){return a instanceof E.EventTarget||a instanceof E.Event||a instanceof E.Range||a instanceof E.DOMImplementation}function t(a){return a instanceof M||a instanceof L||a instanceof N||a instanceof O||a instanceof K}function u(a){return null===a?null:(b(t(a)),a.polymerWrapper_||(a.polymerWrapper_=new(f(a))(a)))}function v(a){return null===a?null:(b(s(a)),a.impl)}function w(a){return a&&s(a)?v(a):a}function x(a){return a&&!s(a)?u(a):a}function y(a,c){null!==c&&(b(t(a)),b(void 0===c||s(c)),a.polymerWrapper_=c)}function z(a,b,c){Object.defineProperty(a.prototype,b,{get:c,configurable:!0,enumerable:!0})}function A(a,b){z(a,b,function(){return u(this.impl[b])})}function B(a,b){a.forEach(function(a){b.forEach(function(b){a.prototype[b]=function(){var a=x(this);return a[b].apply(a,arguments)}})})}var C=new WeakMap,D=new WeakMap,E=Object.create(null),F=!("securityPolicy"in document)||document.securityPolicy.allowsEval;if(F)try{var G=new Function("","return true;");F=G()}catch(H){}Object.getOwnPropertyNames(window);var I=/Firefox/.test(navigator.userAgent),J={get:function(){},set:function(){},configurable:!0,enumerable:!0},K=DOMImplementation,L=Event,M=Node,N=Window,O=Range;a.assert=b,a.constructorTable=C,a.defineGetter=z,a.defineWrapGetter=A,a.forwardMethodsToWrapper=B,a.isWrapperFor=p,a.mixin=c,a.nativePrototypeTable=D,a.oneOf=e,a.registerObject=q,a.registerWrapper=n,a.rewrap=y,a.unwrap=v,a.unwrapIfNeeded=w,a.wrap=u,a.wrapIfNeeded=x,a.wrappers=E}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a instanceof N.ShadowRoot}function c(a){var b=a.localName;return"content"===b||"shadow"===b}function d(a){return!!a.shadowRoot}function e(a){var b;return a.parentNode||(b=a.defaultView)&&M(b)||null}function f(f,g,h){if(h.length)return h.shift();if(b(f))return j(f)||a.getHostForShadowRoot(f);var i=a.eventParentsTable.get(f);if(i){for(var k=1;k<i.length;k++)h[k-1]=i[k];return i[0]}if(g&&c(f)){var l=f.parentNode;if(l&&d(l))for(var m=a.getShadowTrees(l),n=j(g),k=0;k<m.length;k++)if(m[k].contains(n))return n}return e(f)}function g(a){for(var d=[],e=a,g=[],i=[];e;){var j=null;if(c(e)){j=h(d);var k=d[d.length-1]||e;d.push(k)}else d.length||d.push(e);var l=d[d.length-1];g.push({target:l,currentTarget:e}),b(e)&&d.pop(),e=f(e,j,i)}return g}function h(a){for(var b=a.length-1;b>=0;b--)if(!c(a[b]))return a[b];return null}function i(d,e){for(var g=[];d;){for(var i=[],j=e,l=void 0;j;){var n=null;if(i.length){if(c(j)&&(n=h(i),k(l))){var o=i[i.length-1];i.push(o)}}else i.push(j);if(m(j,d))return i[i.length-1];b(j)&&i.pop(),l=j,j=f(j,n,g)}d=b(d)?a.getHostForShadowRoot(d):d.parentNode}}function j(b){return a.insertionParentTable.get(b)}function k(a){return j(a)}function l(a){for(var b;b=a.parentNode;)a=b;return a}function m(a,b){return l(a)===l(b)}function n(b,c){if(b===c)return!0;if(b instanceof N.ShadowRoot){var d=a.getHostForShadowRoot(b);return n(l(d),c)}return!1}function o(a){switch(a){case"DOMAttrModified":case"DOMAttributeNameChanged":case"DOMCharacterDataModified":case"DOMElementNameChanged":case"DOMNodeInserted":case"DOMNodeInsertedIntoDocument":case"DOMNodeRemoved":case"DOMNodeRemovedFromDocument":case"DOMSubtreeModified":return!0}return!1}function p(b){if(!P.get(b)){P.set(b,!0),o(b.type)||a.renderAllPending();var c=M(b.target),d=M(b);return q(d,c)}}function q(a,b){var c=g(b);return"load"===a.type&&2===c.length&&c[0].target instanceof N.Document&&c.shift(),X.set(a,c),r(a,c)&&s(a,c)&&t(a,c),T.set(a,w.NONE),R.set(a,null),a.defaultPrevented}function r(a,b){for(var c,d=b.length-1;d>0;d--){var e=b[d].target,f=b[d].currentTarget;if(e!==f&&(c=w.CAPTURING_PHASE,!u(b[d],a,c)))return!1}return!0}function s(a,b){var c=w.AT_TARGET;return u(b[0],a,c)}function t(a,b){for(var c,d=a.bubbles,e=1;e<b.length;e++){var f=b[e].target,g=b[e].currentTarget;if(f===g)c=w.AT_TARGET;else{if(!d||V.get(a))continue;c=w.BUBBLING_PHASE}if(!u(b[e],a,c))return}}function u(a,b,c){var d=a.target,e=a.currentTarget,f=O.get(e);if(!f)return!0;if("relatedTarget"in b){var g=L(b),h=M(g.relatedTarget),j=i(e,h);if(j===d)return!0;S.set(b,j)}T.set(b,c);var k=b.type,l=!1;Q.set(b,d),R.set(b,e);for(var m=0;m<f.length;m++){var n=f[m];if(n.removed)l=!0;else if(!(n.type!==k||!n.capture&&c===w.CAPTURING_PHASE||n.capture&&c===w.BUBBLING_PHASE))try{if("function"==typeof n.handler?n.handler.call(e,b):n.handler.handleEvent(b),V.get(b))return!1}catch(o){window.onerror?window.onerror(o.message):console.error(o)}}if(l){var p=f.slice();f.length=0;for(var m=0;m<p.length;m++)p[m].removed||f.push(p[m])}return!U.get(b)}function v(a,b,c){this.type=a,this.handler=b,this.capture=Boolean(c)}function w(a,b){return a instanceof Y?(this.impl=a,void 0):M(A(Y,"Event",a,b))}function x(a){return a&&a.relatedTarget?Object.create(a,{relatedTarget:{value:L(a.relatedTarget)}}):a}function y(a,b,c){var d=window[a],e=function(b,c){return b instanceof d?(this.impl=b,void 0):M(A(d,a,b,c))};return e.prototype=Object.create(b.prototype),c&&J(e.prototype,c),d&&(d.prototype["init"+a]?K(d,e,document.createEvent(a)):K(d,e,new d("temp"))),e}function z(a,b){return function(){arguments[b]=L(arguments[b]);var c=L(this);c[a].apply(c,arguments)}}function A(a,b,c,d){if(gb)return new a(c,x(d));var e=L(document.createEvent(b)),f=fb[b],g=[c];return Object.keys(f).forEach(function(a){var b=null!=d&&a in d?d[a]:f[a];"relatedTarget"===a&&(b=L(b)),g.push(b)}),e["init"+b].apply(e,g),e}function B(a){return"function"==typeof a?!0:a&&a.handleEvent}function C(a){this.impl=a}function D(b){return b instanceof N.ShadowRoot&&(b=a.getHostForShadowRoot(b)),L(b)}function E(a){I(a,jb)}function F(b,c,d,e){a.renderAllPending();for(var f=M(kb.call(c.impl,d,e)),h=g(f,this),i=0;i<h.length;i++){var j=h[i];if(j.currentTarget===b)return j.target}return null}function G(a){return function(){var b=W.get(this);return b&&b[a]&&b[a].value||null}}function H(a){var b=a.slice(2);return function(c){var d=W.get(this);d||(d=Object.create(null),W.set(this,d));var e=d[a];if(e&&this.removeEventListener(b,e.wrapped,!1),"function"==typeof c){var f=function(b){var d=c.call(this,b);d===!1?b.preventDefault():"onbeforeunload"===a&&"string"==typeof d&&(b.returnValue=d)};this.addEventListener(b,f,!1),d[a]={value:c,wrapped:f}}}}var I=a.forwardMethodsToWrapper,J=a.mixin,K=a.registerWrapper,L=a.unwrap,M=a.wrap,N=a.wrappers;new WeakMap;var O=new WeakMap,P=new WeakMap,Q=new WeakMap,R=new WeakMap,S=new WeakMap,T=new WeakMap,U=new WeakMap,V=new WeakMap,W=new WeakMap,X=new WeakMap;v.prototype={equals:function(a){return this.handler===a.handler&&this.type===a.type&&this.capture===a.capture},get removed(){return null===this.handler},remove:function(){this.handler=null}};var Y=window.Event;w.prototype={get target(){return Q.get(this)},get currentTarget(){return R.get(this)},get eventPhase(){return T.get(this)},get path(){var a=new N.NodeList,b=X.get(this);if(b){for(var c=0,d=b.length-1,e=l(R.get(this)),f=0;d>=f;f++){var g=b[f].currentTarget,h=l(g);n(e,h)&&(f!==d||g instanceof N.Node)&&(a[c++]=g)}a.length=c}return a},stopPropagation:function(){U.set(this,!0)},stopImmediatePropagation:function(){U.set(this,!0),V.set(this,!0)}},K(Y,w,document.createEvent("Event"));var Z=y("UIEvent",w),$=y("CustomEvent",w),_={get relatedTarget(){return S.get(this)||M(L(this).relatedTarget)}},ab=J({initMouseEvent:z("initMouseEvent",14)},_),bb=J({initFocusEvent:z("initFocusEvent",5)},_),cb=y("MouseEvent",Z,ab),db=y("FocusEvent",Z,bb),eb=y("MutationEvent",w,{initMutationEvent:z("initMutationEvent",3),get relatedNode(){return M(this.impl.relatedNode)}}),fb=Object.create(null),gb=function(){try{new window.MouseEvent("click")}catch(a){return!1}return!0}();if(!gb){var hb=function(a,b,c){if(c){var d=fb[c];b=J(J({},d),b)}fb[a]=b};hb("Event",{bubbles:!1,cancelable:!1}),hb("CustomEvent",{detail:null},"Event"),hb("UIEvent",{view:null,detail:0},"Event"),hb("MouseEvent",{screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:null},"UIEvent"),hb("FocusEvent",{relatedTarget:null},"UIEvent")}var ib=window.EventTarget,jb=["addEventListener","removeEventListener","dispatchEvent"];[Node,Window].forEach(function(a){var b=a.prototype;jb.forEach(function(a){Object.defineProperty(b,a+"_",{value:b[a]})})}),C.prototype={addEventListener:function(a,b,c){if(B(b)){var d=new v(a,b,c),e=O.get(this);if(e){for(var f=0;f<e.length;f++)if(d.equals(e[f]))return}else e=[],O.set(this,e);e.push(d);var g=D(this);g.addEventListener_(a,p,!0)}},removeEventListener:function(a,b,c){c=Boolean(c);var d=O.get(this);if(d){for(var e=0,f=!1,g=0;g<d.length;g++)d[g].type===a&&d[g].capture===c&&(e++,d[g].handler===b&&(f=!0,d[g].remove()));if(f&&1===e){var h=D(this);h.removeEventListener_(a,p,!0)}}},dispatchEvent:function(a){var b=D(this);return b.dispatchEvent_(L(a))}},ib&&K(ib,C);var kb=document.elementFromPoint;a.adjustRelatedTarget=i,a.elementFromPoint=F,a.getEventHandlerGetter=G,a.getEventHandlerSetter=H,a.wrapEventTargetMethods=E,a.wrappers.CustomEvent=$,a.wrappers.Event=w,a.wrappers.EventTarget=C,a.wrappers.FocusEvent=db,a.wrappers.MouseEvent=cb,a.wrappers.MutationEvent=eb,a.wrappers.UIEvent=Z}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a,b){Object.defineProperty(a,b,{enumerable:!1})}function c(){this.length=0,b(this,"length")}function d(a){if(null==a)return a;for(var b=new c,d=0,e=a.length;e>d;d++)b[d]=f(a[d]);return b.length=e,b}function e(a,b){a.prototype[b]=function(){return d(this.impl[b].apply(this.impl,arguments))}}var f=a.wrap;c.prototype={item:function(a){return this[a]}},b(c.prototype,"item"),a.wrappers.NodeList=c,a.addWrapNodeListMethod=e,a.wrapNodeList=d}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){o(a instanceof k)}function c(a,b,c,d){if(!(a instanceof DocumentFragment))return a.parentNode&&a.parentNode.removeChild(a),a.parentNode_=b,a.previousSibling_=c,a.nextSibling_=d,c&&(c.nextSibling_=a),d&&(d.previousSibling_=a),[a];for(var e,f=[];e=a.firstChild;)a.removeChild(e),f.push(e),e.parentNode_=b;for(var g=0;g<f.length;g++)f[g].previousSibling_=f[g-1]||c,f[g].nextSibling_=f[g+1]||d;return c&&(c.nextSibling_=f[0]),d&&(d.previousSibling_=f[f.length-1]),f}function d(a){if(a instanceof DocumentFragment){for(var b=[],c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b}return[a]}function e(a){for(var b=0;b<a.length;b++)a[b].nodeWasAdded_()}function f(a,b){var c=a.nodeType===k.DOCUMENT_NODE?a:a.ownerDocument;c!==b.ownerDocument&&c.adoptNode(b)}function g(b,c){if(c.length){var d=b.ownerDocument;if(d!==c[0].ownerDocument)for(var e=0;e<c.length;e++)a.adoptNodeNoRemove(c[e],d)}}function h(a,b){g(a,b);var c=b.length;if(1===c)return r(b[0]);for(var d=r(a.ownerDocument.createDocumentFragment()),e=0;c>e;e++)d.appendChild(r(b[e]));return d}function i(a){if(a.invalidateShadowRenderer()){for(var b=a.firstChild;b;){o(b.parentNode===a);var c=b.nextSibling,d=r(b),e=d.parentNode;e&&y.call(e,d),b.previousSibling_=b.nextSibling_=b.parentNode_=null,b=c}a.firstChild_=a.lastChild_=null}else for(var c,f=r(a),g=f.firstChild;g;)c=g.nextSibling,y.call(f,g),g=c}function j(a){var b=a.parentNode;return b&&b.invalidateShadowRenderer()}function k(a){o(a instanceof u),l.call(this,a),this.parentNode_=void 0,this.firstChild_=void 0,this.lastChild_=void 0,this.nextSibling_=void 0,this.previousSibling_=void 0}var l=a.wrappers.EventTarget,m=a.wrappers.NodeList,n=a.defineWrapGetter,o=a.assert,p=a.mixin,q=a.registerWrapper,r=a.unwrap,s=a.wrap,t=a.wrapIfNeeded,u=window.Node,v=u.prototype.appendChild,w=u.prototype.insertBefore,x=u.prototype.replaceChild,y=u.prototype.removeChild,z=u.prototype.compareDocumentPosition;k.prototype=Object.create(l.prototype),p(k.prototype,{appendChild:function(a){b(a);var g;if(this.invalidateShadowRenderer()||j(a)){var i=this.lastChild,k=null;g=c(a,this,i,k),this.lastChild_=g[g.length-1],i||(this.firstChild_=g[0]),v.call(this.impl,h(this,g))}else g=d(a),f(this,a),v.call(this.impl,r(a));return e(g),a},insertBefore:function(a,i){if(!i)return this.appendChild(a);b(a),b(i),o(i.parentNode===this);var k;if(this.invalidateShadowRenderer()||j(a)){var l=i.previousSibling,m=i;k=c(a,this,l,m),this.firstChild===i&&(this.firstChild_=k[0]);var n=r(i),p=n.parentNode;p?w.call(p,h(this,k),n):g(this,k)}else k=d(a),f(this,a),w.call(this.impl,r(a),r(i));return e(k),a},removeChild:function(a){if(b(a),a.parentNode!==this)throw new Error("NotFoundError");var c=r(a);if(this.invalidateShadowRenderer()){var d=this.firstChild,e=this.lastChild,f=a.nextSibling,g=a.previousSibling,h=c.parentNode;h&&y.call(h,c),d===a&&(this.firstChild_=f),e===a&&(this.lastChild_=g),g&&(g.nextSibling_=f),f&&(f.previousSibling_=g),a.previousSibling_=a.nextSibling_=a.parentNode_=void 0}else y.call(this.impl,c);return a},replaceChild:function(a,g){if(b(a),b(g),g.parentNode!==this)throw new Error("NotFoundError");var i,k=r(g);if(this.invalidateShadowRenderer()||j(a)){var l=g.previousSibling,m=g.nextSibling;m===a&&(m=a.nextSibling),i=c(a,this,l,m),this.firstChild===g&&(this.firstChild_=i[0]),this.lastChild===g&&(this.lastChild_=i[i.length-1]),g.previousSibling_=g.nextSibling_=g.parentNode_=void 0,k.parentNode&&x.call(k.parentNode,h(this,i),k)}else i=d(a),f(this,a),x.call(this.impl,r(a),k);return e(i),g},nodeWasAdded_:function(){for(var a=this.firstChild;a;a=a.nextSibling)a.nodeWasAdded_()},hasChildNodes:function(){return null===this.firstChild},get parentNode(){return void 0!==this.parentNode_?this.parentNode_:s(this.impl.parentNode)},get firstChild(){return void 0!==this.firstChild_?this.firstChild_:s(this.impl.firstChild)},get lastChild(){return void 0!==this.lastChild_?this.lastChild_:s(this.impl.lastChild)},get nextSibling(){return void 0!==this.nextSibling_?this.nextSibling_:s(this.impl.nextSibling)},get previousSibling(){return void 0!==this.previousSibling_?this.previousSibling_:s(this.impl.previousSibling)},get parentElement(){for(var a=this.parentNode;a&&a.nodeType!==k.ELEMENT_NODE;)a=a.parentNode;return a},get textContent(){for(var a="",b=this.firstChild;b;b=b.nextSibling)a+=b.textContent;return a},set textContent(a){if(this.invalidateShadowRenderer()){if(i(this),""!==a){var b=this.impl.ownerDocument.createTextNode(a);this.appendChild(b)}}else this.impl.textContent=a},get childNodes(){for(var a=new m,b=0,c=this.firstChild;c;c=c.nextSibling)a[b++]=c;return a.length=b,a},cloneNode:function(a){if(!this.invalidateShadowRenderer())return s(this.impl.cloneNode(a));var b=s(this.impl.cloneNode(!1));if(a)for(var c=this.firstChild;c;c=c.nextSibling)b.appendChild(c.cloneNode(!0));return b},contains:function(a){if(!a)return!1;if(a=t(a),a===this)return!0;var b=a.parentNode;return b?this.contains(b):!1},compareDocumentPosition:function(a){return z.call(this.impl,r(a))}}),n(k,"ownerDocument"),q(u,k,document.createDocumentFragment()),delete k.prototype.querySelector,delete k.prototype.querySelectorAll,k.prototype=p(Object.create(l.prototype),k.prototype),a.wrappers.Node=k}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a,c){for(var d,e=a.firstElementChild;e;){if(e.matches(c))return e;if(d=b(e,c))return d;e=e.nextElementSibling}return null}function c(a,b,d){for(var e=a.firstElementChild;e;)e.matches(b)&&(d[d.length++]=e),c(e,b,d),e=e.nextElementSibling;
+return d}var d={querySelector:function(a){return b(this,a)},querySelectorAll:function(a){return c(this,a,new NodeList)}},e={getElementsByTagName:function(a){return this.querySelectorAll(a)},getElementsByClassName:function(a){return this.querySelectorAll("."+a)},getElementsByTagNameNS:function(a,b){if("*"===a)return this.getElementsByTagName(b);for(var c=new NodeList,d=this.getElementsByTagName(b),e=0,f=0;e<d.length;e++)d[e].namespaceURI===a&&(c[f++]=d[e]);return c.length=f,c}};a.GetElementsByInterface=e,a.SelectorsInterface=d}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}function c(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}var d=a.wrappers.NodeList,e={get firstElementChild(){return b(this.firstChild)},get lastElementChild(){return c(this.lastChild)},get childElementCount(){for(var a=0,b=this.firstElementChild;b;b=b.nextElementSibling)a++;return a},get children(){for(var a=new d,b=0,c=this.firstElementChild;c;c=c.nextElementSibling)a[b++]=c;return a.length=b,a}},f={get nextElementSibling(){return b(this.nextSibling)},get previousElementSibling(){return c(this.previousSibling)}};a.ChildNodeInterface=f,a.ParentNodeInterface=e}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}var c=a.ChildNodeInterface,d=a.wrappers.Node,e=a.mixin,f=a.registerWrapper,g=window.CharacterData;b.prototype=Object.create(d.prototype),e(b.prototype,{get textContent(){return this.data},set textContent(a){this.data=a}}),e(b.prototype,c),f(g,b,document.createTextNode("")),a.wrappers.CharacterData=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(b,c){var d=b.parentNode;if(d&&d.shadowRoot){var e=a.getRendererForHost(d);e.dependsOnAttribute(c)&&e.invalidate()}}function c(a){g.call(this,a)}function d(a,c,d){var e=d||c;Object.defineProperty(a,c,{get:function(){return this.impl[c]},set:function(a){this.impl[c]=a,b(this,e)},configurable:!0,enumerable:!0})}var e=a.ChildNodeInterface,f=a.GetElementsByInterface,g=a.wrappers.Node,h=a.ParentNodeInterface,i=a.SelectorsInterface;a.addWrapNodeListMethod;var j=a.mixin,k=a.oneOf,l=a.registerWrapper,m=a.wrappers,n=window.Element,o=k(n.prototype,["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"]),p=n.prototype[o];c.prototype=Object.create(g.prototype),j(c.prototype,{createShadowRoot:function(){var b=new m.ShadowRoot(this);this.impl.polymerShadowRoot_=b;var c=a.getRendererForHost(this);return c.invalidate(),b},get shadowRoot(){return this.impl.polymerShadowRoot_||null},setAttribute:function(a,c){this.impl.setAttribute(a,c),b(this,a)},removeAttribute:function(a){this.impl.removeAttribute(a),b(this,a)},matches:function(a){return p.call(this.impl,a)}}),c.prototype[o]=function(a){return this.matches(a)},n.prototype.webkitCreateShadowRoot&&(c.prototype.webkitCreateShadowRoot=c.prototype.createShadowRoot),d(c.prototype,"id"),d(c.prototype,"className","class"),j(c.prototype,e),j(c.prototype,f),j(c.prototype,h),j(c.prototype,i),l(n,c),a.matchesName=o,a.wrappers.Element=c}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a){case"&":return"&";case"<":return"<";case'"':return"""}}function c(a){return a.replace(p,b)}function d(a){switch(a.nodeType){case Node.ELEMENT_NODE:for(var b,d=a.tagName.toLowerCase(),f="<"+d,g=a.attributes,h=0;b=g[h];h++)f+=" "+b.name+'="'+c(b.value)+'"';return f+=">",q[d]?f:f+e(a)+"</"+d+">";case Node.TEXT_NODE:return c(a.nodeValue);case Node.COMMENT_NODE:return"<!--"+c(a.nodeValue)+"-->";default:throw console.error(a),new Error("not implemented")}}function e(a){for(var b="",c=a.firstChild;c;c=c.nextSibling)b+=d(c);return b}function f(a,b,c){var d=c||"div";a.textContent="";var e=n(a.ownerDocument.createElement(d));e.innerHTML=b;for(var f;f=e.firstChild;)a.appendChild(o(f))}function g(a){j.call(this,a)}function h(b){k(g,b,function(){return a.renderAllPending(),this.impl[b]})}function i(b){Object.defineProperty(g.prototype,b,{value:function(){return a.renderAllPending(),this.impl[b].apply(this.impl,arguments)},configurable:!0,enumerable:!0})}var j=a.wrappers.Element,k=a.defineGetter,l=a.mixin,m=a.registerWrapper,n=a.unwrap,o=a.wrap,p=/&|<|"/g,q={area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},r=window.HTMLElement;g.prototype=Object.create(j.prototype),l(g.prototype,{get innerHTML(){return e(this)},set innerHTML(a){this.invalidateShadowRenderer()?f(this,a,this.tagName):this.impl.innerHTML=a},get outerHTML(){return d(this)},set outerHTML(a){var b=this.parentNode;b&&(b.invalidateShadowRenderer(),this.impl.outerHTML=a)}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollLeft","scrollTop","scrollWidth"].forEach(h),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(i),m(r,g,document.createElement("b")),a.wrappers.HTMLElement=g,a.getInnerHTML=e,a.setInnerHTML=f}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLContentElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get select(){return this.getAttribute("select")},set select(a){this.setAttribute("select",a)},setAttribute:function(a,b){c.prototype.setAttribute.call(this,a,b),"select"===String(a).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),f&&e(f,b),a.wrappers.HTMLContentElement=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLShadowElement;b.prototype=Object.create(c.prototype),d(b.prototype,{}),f&&e(f,b),a.wrappers.HTMLShadowElement=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){if(!a.defaultView)return a;var b=m.get(a);if(!b){for(b=a.implementation.createHTMLDocument("");b.lastChild;)b.removeChild(b.lastChild);m.set(a,b)}return b}function c(a){for(var c,d=b(a.ownerDocument),e=j(d.createDocumentFragment());c=a.firstChild;)e.appendChild(c);return e}function d(a){if(e.call(this,a),!n){var b=c(a);l.set(this,k(b))}}var e=a.wrappers.HTMLElement,f=a.getInnerHTML,g=a.mixin,h=a.registerWrapper,i=a.setInnerHTML,j=a.unwrap,k=a.wrap,l=new WeakMap,m=new WeakMap,n=window.HTMLTemplateElement;d.prototype=Object.create(e.prototype),g(d.prototype,{get content(){return n?k(this.impl.content):l.get(this)},get innerHTML(){return f(this.content)},set innerHTML(a){i(this.content,a)}}),n&&h(n,d),a.wrappers.HTMLTemplateElement=d}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a.localName){case"content":return new c(a);case"shadow":return new e(a);case"template":return new f(a)}d.call(this,a)}var c=a.wrappers.HTMLContentElement,d=a.wrappers.HTMLElement,e=a.wrappers.HTMLShadowElement,f=a.wrappers.HTMLTemplateElement;a.mixin;var g=a.registerWrapper,h=window.HTMLUnknownElement;b.prototype=Object.create(d.prototype),g(h,b),a.wrappers.HTMLUnknownElement=b}(this.ShadowDOMPolyfill),function(a){"use strict";var b=a.GetElementsByInterface,c=a.ParentNodeInterface,d=a.SelectorsInterface,e=a.mixin,f=a.registerObject,g=f(document.createDocumentFragment());e(g.prototype,c),e(g.prototype,d),e(g.prototype,b);var h=f(document.createTextNode("")),i=f(document.createComment(""));a.wrappers.Comment=i,a.wrappers.DocumentFragment=g,a.wrappers.Text=h}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=i(a.impl.ownerDocument.createDocumentFragment());c.call(this,b),g(b,this);var d=a.shadowRoot;k.set(this,d),j.set(this,a)}var c=a.wrappers.DocumentFragment,d=a.elementFromPoint,e=a.getInnerHTML,f=a.mixin,g=a.rewrap,h=a.setInnerHTML,i=a.unwrap,j=new WeakMap,k=new WeakMap;b.prototype=Object.create(c.prototype),f(b.prototype,{get innerHTML(){return e(this)},set innerHTML(a){h(this,a),this.invalidateShadowRenderer()},get olderShadowRoot(){return k.get(this)||null},invalidateShadowRenderer:function(){return j.get(this).invalidateShadowRenderer()},elementFromPoint:function(a,b){return d(this,this.ownerDocument,a,b)},getElementById:function(a){return this.querySelector("#"+a)}}),a.wrappers.ShadowRoot=b,a.getHostForShadowRoot=function(a){return j.get(a)}}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){a.previousSibling_=a.previousSibling,a.nextSibling_=a.nextSibling,a.parentNode_=a.parentNode}function c(a,c,e){var f=G(a),g=G(c),h=e?G(e):null;if(d(c),b(c),e)a.firstChild===e&&(a.firstChild_=e),e.previousSibling_=e.previousSibling;else{a.lastChild_=a.lastChild,a.lastChild===a.firstChild&&(a.firstChild_=a.firstChild);var i=H(f.lastChild);i&&(i.nextSibling_=i.nextSibling)}f.insertBefore(g,h)}function d(a){var c=G(a),d=c.parentNode;if(d){var e=H(d);b(a),a.previousSibling&&(a.previousSibling.nextSibling_=a),a.nextSibling&&(a.nextSibling.previousSibling_=a),e.lastChild===a&&(e.lastChild_=a),e.firstChild===a&&(e.firstChild_=a),d.removeChild(c)}}function e(a,b){g(b).push(a),x(a,b);var c=J.get(a);c||J.set(a,c=[]),c.push(b)}function f(a){I.set(a,[])}function g(a){return I.get(a)}function h(a){for(var b=[],c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b}function i(a,b,c){for(var d=a.firstChild;d;d=d.nextSibling)if(b(d)){if(c(d)===!1)return}else i(d,b,c)}function j(a,b){var c=b.getAttribute("select");if(!c)return!0;if(c=c.trim(),!c)return!0;if(!(a instanceof y))return!1;if(!M.test(c))return!1;if(":"===c[0]&&!N.test(c))return!1;try{return a.matches(c)}catch(d){return!1}}function k(){for(var a=0;a<P.length;a++)P[a].render();P=[]}function l(){E=null,k()}function m(a){var b=L.get(a);return b||(b=new q(a),L.set(a,b)),b}function n(a){for(;a;a=a.parentNode)if(a instanceof C)return a;return null}function o(a){return m(D(a))}function p(a){this.skip=!1,this.node=a,this.childNodes=[]}function q(a){this.host=a,this.dirty=!1,this.invalidateAttributes(),this.associateNode(a)}function r(a){return a instanceof z}function s(a){return a instanceof z}function t(a){return a instanceof A}function u(a){return a instanceof A}function v(a){return a.shadowRoot}function w(a){for(var b=[],c=a.shadowRoot;c;c=c.olderShadowRoot)b.push(c);return b}function x(a,b){K.set(a,b)}var y=a.wrappers.Element,z=a.wrappers.HTMLContentElement,A=a.wrappers.HTMLShadowElement,B=a.wrappers.Node,C=a.wrappers.ShadowRoot;a.assert;var D=a.getHostForShadowRoot;a.mixin;var E,F=a.oneOf,G=a.unwrap,H=a.wrap,I=new WeakMap,J=new WeakMap,K=new WeakMap,L=new WeakMap,M=/^[*.:#[a-zA-Z_|]/,N=new RegExp("^:("+["link","visited","target","enabled","disabled","checked","indeterminate","nth-child","nth-last-child","nth-of-type","nth-last-of-type","first-child","last-child","first-of-type","last-of-type","only-of-type"].join("|")+")"),O=F(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","setTimeout"]),P=[],Q=new ArraySplice;Q.equals=function(a,b){return G(a.node)===b},p.prototype={append:function(a){var b=new p(a);return this.childNodes.push(b),b},sync:function(a){if(!this.skip){for(var b=this.node,e=this.childNodes,f=h(G(b)),g=a||new WeakMap,i=Q.calculateSplices(e,f),j=0,k=0,l=0,m=0;m<i.length;m++){for(var n=i[m];l<n.index;l++)k++,e[j++].sync(g);for(var o=n.removed.length,p=0;o>p;p++){var q=H(f[k++]);g.get(q)||d(q)}for(var r=n.addedCount,s=f[k]&&H(f[k]),p=0;r>p;p++){var t=e[j++],u=t.node;c(b,u,s),g.set(u,!0),t.sync(g)}l+=r}for(var m=l;m<e.length;m++)e[m++].sync(g)}}},q.prototype={render:function(a){if(this.dirty){this.invalidateAttributes(),this.treeComposition();var b=this.host,c=b.shadowRoot;this.associateNode(b);for(var d=!e,e=a||new p(b),f=c.firstChild;f;f=f.nextSibling)this.renderNode(c,e,f,!1);d&&e.sync(),this.dirty=!1}},invalidate:function(){if(!this.dirty){if(this.dirty=!0,P.push(this),E)return;E=window[O](l,0)}},renderNode:function(a,b,c,d){if(v(c)){b=b.append(c);var e=m(c);e.dirty=!0,e.render(b)}else r(c)?this.renderInsertionPoint(a,b,c,d):t(c)?this.renderShadowInsertionPoint(a,b,c):this.renderAsAnyDomTree(a,b,c,d)},renderAsAnyDomTree:function(a,b,c,d){if(b=b.append(c),v(c)){var e=m(c);b.skip=!e.dirty,e.render(b)}else for(var f=c.firstChild;f;f=f.nextSibling)this.renderNode(a,b,f,d)},renderInsertionPoint:function(a,b,c,d){var e=g(c);if(e.length){this.associateNode(c);for(var f=0;f<e.length;f++){var h=e[f];r(h)&&d?this.renderInsertionPoint(a,b,h,d):this.renderAsAnyDomTree(a,b,h,d)}}else this.renderFallbackContent(a,b,c);this.associateNode(c.parentNode)},renderShadowInsertionPoint:function(a,b,c){var d=a.olderShadowRoot;if(d){x(d,c),this.associateNode(c.parentNode);for(var e=d.firstChild;e;e=e.nextSibling)this.renderNode(d,b,e,!0)}else this.renderFallbackContent(a,b,c)},renderFallbackContent:function(a,b,c){this.associateNode(c),this.associateNode(c.parentNode);for(var d=c.firstChild;d;d=d.nextSibling)this.renderAsAnyDomTree(a,b,d,!1)},invalidateAttributes:function(){this.attributes=Object.create(null)},updateDependentAttributes:function(a){if(a){var b=this.attributes;/\.\w+/.test(a)&&(b["class"]=!0),/#\w+/.test(a)&&(b.id=!0),a.replace(/\[\s*([^\s=\|~\]]+)/g,function(a,c){b[c]=!0})}},dependsOnAttribute:function(a){return this.attributes[a]},distribute:function(a,b){var c=this;i(a,s,function(a){f(a),c.updateDependentAttributes(a.getAttribute("select"));for(var d=0;d<b.length;d++){var g=b[d];void 0!==g&&j(g,a)&&(e(g,a),b[d]=void 0)}})},treeComposition:function(){for(var a=this.host,b=a.shadowRoot,c=[],d=a.firstChild;d;d=d.nextSibling)if(r(d)){var e=g(d);e&&e.length||(e=h(d)),c.push.apply(c,e)}else c.push(d);for(var f,j;b;){if(f=void 0,i(b,u,function(a){return f=a,!1}),j=f,this.distribute(b,c),j){var k=b.olderShadowRoot;if(k){b=k,x(b,j);continue}break}break}},associateNode:function(a){a.impl.polymerShadowRenderer_=this}},B.prototype.invalidateShadowRenderer=function(){var a=this.impl.polymerShadowRenderer_;return a?(a.invalidate(),!0):!1},z.prototype.getDistributedNodes=function(){return k(),g(this)},A.prototype.nodeWasAdded_=z.prototype.nodeWasAdded_=function(){this.invalidateShadowRenderer();var a,b=n(this);b&&(a=o(b)),this.impl.polymerShadowRenderer_=a,a&&a.invalidate()},a.eventParentsTable=J,a.getRendererForHost=m,a.getShadowTrees=w,a.insertionParentTable=K,a.renderAllPending=k,a.visual={insertBefore:c,remove:d}}(this.ShadowDOMPolyfill),function(a){"use strict";function b(b){if(window[b]){d(!a.wrappers[b]);var i=function(a){c.call(this,a)};i.prototype=Object.create(c.prototype),e(i.prototype,{get form(){return h(g(this).form)}}),f(window[b],i,document.createElement(b.slice(4,-7))),a.wrappers[b]=i}}var c=a.wrappers.HTMLElement,d=a.assert,e=a.mixin,f=a.registerWrapper,g=a.unwrap,h=a.wrap,i=["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLKeygenElement","HTMLLabelElement","HTMLLegendElement","HTMLObjectElement","HTMLOptionElement","HTMLOutputElement","HTMLSelectElement","HTMLTextAreaElement"];i.forEach(b)}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){k.call(this,a)}function c(a){var c=document[a];b.prototype[a]=function(){return v(c.apply(this.impl,arguments))}}function d(a,b){y.call(b.impl,u(a)),e(a,b)}function e(a,b){a.shadowRoot&&b.adoptNode(a.shadowRoot),a instanceof n&&f(a,b);for(var c=a.firstChild;c;c=c.nextSibling)e(c,b)}function f(a,b){var c=a.olderShadowRoot;c&&b.adoptNode(c)}function g(a){this.impl=a}function h(a,b){var c=document.implementation[b];a.prototype[b]=function(){return v(c.apply(this.impl,arguments))}}function i(a,b){var c=document.implementation[b];a.prototype[b]=function(){return c.apply(this.impl,arguments)}}var j=a.GetElementsByInterface,k=a.wrappers.Node,l=a.ParentNodeInterface,m=a.SelectorsInterface,n=a.wrappers.ShadowRoot,o=a.defineWrapGetter,p=a.elementFromPoint,q=a.forwardMethodsToWrapper,r=a.matchesName,s=a.mixin,t=a.registerWrapper,u=a.unwrap,v=a.wrap,w=a.wrapEventTargetMethods;a.wrapNodeList;var x=new WeakMap;b.prototype=Object.create(k.prototype),o(b,"documentElement"),o(b,"body"),o(b,"head"),["createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","getElementById"].forEach(c);var y=document.adoptNode;if(s(b.prototype,{adoptNode:function(a){return a.parentNode&&a.parentNode.removeChild(a),d(a,this),a},elementFromPoint:function(a,b){return p(this,this,a,b)}}),document.register){var z=document.register;b.prototype.register=function(b,c){function d(a){return a?(this.impl=a,void 0):document.createElement(b)}var e=c.prototype;if(a.nativePrototypeTable.get(e))throw new Error("NotSupportedError");for(var f,g=Object.getPrototypeOf(e),h=[];g&&!(f=a.nativePrototypeTable.get(g));)h.push(g),g=Object.getPrototypeOf(g);if(!f)throw new Error("NotSupportedError");for(var i=Object.create(f),j=h.length-1;j>=0;j--)i=Object.create(i);return["createdCallback","enteredDocumentCallback","leftDocumentCallback","attributeChangedCallback"].forEach(function(a){var b=e[a];b&&(i[a]=function(){b.apply(v(this),arguments)})}),z.call(u(this),b,{prototype:i}),d.prototype=e,d.prototype.constructor=d,a.constructorTable.set(i,d),a.nativePrototypeTable.set(e,i),d},q([window.HTMLDocument||window.Document],["register"])}q([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild",r]),q([window.HTMLDocument||window.Document],["adoptNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById"]),s(b.prototype,j),s(b.prototype,l),s(b.prototype,m),s(b.prototype,{get implementation(){var a=x.get(this);return a?a:(a=new g(u(this).implementation),x.set(this,a),a)}}),t(window.Document,b,document.implementation.createHTMLDocument("")),window.HTMLDocument&&t(window.HTMLDocument,b),w([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),h(g,"createDocumentType"),h(g,"createDocument"),h(g,"createHTMLDocument"),i(g,"hasFeature"),t(window.DOMImplementation,g),q([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),a.adoptNodeNoRemove=d,a.wrappers.DOMImplementation=g,a.wrappers.Document=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.EventTarget,d=a.mixin,e=a.registerWrapper,f=a.unwrap,g=a.unwrapIfNeeded,h=a.wrap,i=a.renderAllPending,j=window.Window;b.prototype=Object.create(c.prototype);var k=window.getComputedStyle;j.prototype.getComputedStyle=function(a,b){return i(),k.call(this||window,g(a),b)},["addEventListener","removeEventListener","dispatchEvent"].forEach(function(a){j.prototype[a]=function(){var b=h(this||window);return b[a].apply(b,arguments)}}),d(b.prototype,{getComputedStyle:function(a,b){return k.call(f(this),g(a),b)}}),e(j,b),a.wrappers.Window=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}function c(a){return new b(a)}function d(a){return a.map(c)}function e(a){var b=this;this.impl=new k(function(c){a.call(b,d(c),b)})}var f=a.defineGetter,g=a.defineWrapGetter,h=a.registerWrapper,i=a.unwrapIfNeeded,j=a.wrapNodeList;a.wrappers;var k=window.MutationObserver||window.WebKitMutationObserver;if(k){var l=window.MutationRecord;b.prototype={get addedNodes(){return j(this.impl.addedNodes)},get removedNodes(){return j(this.impl.removedNodes)}},["target","previousSibling","nextSibling"].forEach(function(a){g(b,a)}),["type","attributeName","attributeNamespace","oldValue"].forEach(function(a){f(b,a,function(){return this.impl[a]})}),l&&h(l,b),window.Node,e.prototype={observe:function(a,b){this.impl.observe(i(a),b)},disconnect:function(){this.impl.disconnect()},takeRecords:function(){return d(this.impl.takeRecords())}},a.wrappers.MutationObserver=e,a.wrappers.MutationRecord=b}}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.registerWrapper,d=a.unwrap,e=a.unwrapIfNeeded,f=a.wrap,g=window.Range;b.prototype={get startContainer(){return f(this.impl.startContainer)},get endContainer(){return f(this.impl.endContainer)},get commonAncestorContainer(){return f(this.impl.commonAncestorContainer)},setStart:function(a,b){this.impl.setStart(e(a),b)},setEnd:function(a,b){this.impl.setEnd(e(a),b)},setStartBefore:function(a){this.impl.setStartBefore(e(a))},setStartAfter:function(a){this.impl.setStartAfter(e(a))},setEndBefore:function(a){this.impl.setEndBefore(e(a))},setEndAfter:function(a){this.impl.setEndAfter(e(a))},selectNode:function(a){this.impl.selectNode(e(a))},selectNodeContents:function(a){this.impl.selectNodeContents(e(a))},compareBoundaryPoints:function(a,b){return this.impl.compareBoundaryPoints(a,d(b))},extractContents:function(){return f(this.impl.extractContents())},cloneContents:function(){return f(this.impl.cloneContents())},insertNode:function(a){this.impl.insertNode(e(a))},surroundContents:function(a){this.impl.surroundContents(e(a))},cloneRange:function(){return f(this.impl.cloneRange())},isPointInRange:function(a,b){return this.impl.isPointInRange(e(a),b)},comparePoint:function(a,b){return this.impl.comparePoint(e(a),b)},intersectsNode:function(a){return this.impl.intersectsNode(e(a))}},g.prototype.createContextualFragment&&(b.prototype.createContextualFragment=function(a){return f(this.impl.createContextualFragment(a))}),c(window.Range,b),a.wrappers.Range=b}(this.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=c[a],d=window[b];if(d){var e=document.createElement(a),f=e.constructor;window[b]=f}}a.isWrapperFor;var c={a:"HTMLAnchorElement",applet:"HTMLAppletElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",br:"HTMLBRElement",base:"HTMLBaseElement",body:"HTMLBodyElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",dl:"HTMLDListElement",datalist:"HTMLDataListElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",hr:"HTMLHRElement",head:"HTMLHeadElement",h1:"HTMLHeadingElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",input:"HTMLInputElement",li:"HTMLLIElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",link:"HTMLLinkElement",map:"HTMLMapElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",del:"HTMLModElement",ol:"HTMLOListElement",object:"HTMLObjectElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",table:"HTMLTableElement",tr:"HTMLTableRowElement",thead:"HTMLTableSectionElement",tbody:"HTMLTableSectionElement",textarea:"HTMLTextAreaElement",title:"HTMLTitleElement",ul:"HTMLUListElement",video:"HTMLVideoElement"};Object.keys(c).forEach(b),Object.getOwnPropertyNames(a.wrappers).forEach(function(b){window[b]=a.wrappers[b]}),a.knownElements=c}(this.ShadowDOMPolyfill),function(){var a=window.ShadowDOMPolyfill;a.wrap,Object.defineProperties(HTMLElement.prototype,{webkitShadowRoot:{get:function(){return this.shadowRoot}}}),HTMLElement.prototype.webkitCreateShadowRoot=HTMLElement.prototype.createShadowRoot,window.dartExperimentalFixupGetTag=function(b){function c(a){if(a instanceof d)return"NodeList";if(a instanceof e)return"ShadowRoot";if(window.MutationRecord&&a instanceof MutationRecord)return"MutationRecord";if(window.MutationObserver&&a instanceof MutationObserver)return"MutationObserver";var c=f(a);if(a!==c){var g=a.constructor;if(g===c.constructor){var h=g._ShadowDOMPolyfill$cacheTag_;return h||(h=Object.prototype.toString.call(c),h=h.substring(8,h.length-1),g._ShadowDOMPolyfill$cacheTag_=h),h}a=c}return b(a)}var d=a.wrappers.NodeList,e=a.wrappers.ShadowRoot,f=a.unwrapIfNeeded;return c}}();var Platform={};!function(a){function b(a,b){var c="";return Array.prototype.forEach.call(a,function(a){c+=a.textContent+"\n\n"}),b||(c=c.replace(m,"")),c}function c(a){var b=document.createElement("style");b.textContent=a,document.head.appendChild(b);var c=b.sheet.cssRules;return b.parentNode.removeChild(b),c}function d(a){for(var b=0,c=[];b<a.length;b++)c.push(a[b].cssText);return c.join("\n\n")}function e(a){a&&f().appendChild(document.createTextNode(a))}function f(){return g||(g=document.createElement("style"),g.setAttribute("ShadowCSSShim","")),g}var g,h={strictStyling:!1,registry:{},shimStyling:function(a,b,c){if(a){var d=this.registerDefinition(a,b,c);this.strictStyling&&this.applyScopeToContent(a,b),this.shimPolyfillDirectives(d.rootStyles,b),this.applyShimming(d.scopeStyles,b)}},shimShadowDOMStyling:function(a,b){this.shimPolyfillDirectives(a,b),this.applyShimming(a,b)},registerDefinition:function(a,b,c){var d=this.registry[b]={root:a,name:b,extendsName:c},e=a.querySelectorAll("style");e=e?Array.prototype.slice.call(e,0):[],d.rootStyles=e,d.scopeStyles=d.rootStyles;var f=this.registry[d.extendsName];return f&&(d.scopeStyles=d.scopeStyles.concat(f.scopeStyles)),d},applyScopeToContent:function(a,b){a&&(Array.prototype.forEach.call(a.querySelectorAll("*"),function(a){a.setAttribute(b,"")}),Array.prototype.forEach.call(a.querySelectorAll("template"),function(a){this.applyScopeToContent(a.content,b)},this))},shimPolyfillDirectives:function(a,b){a&&Array.prototype.forEach.call(a,function(a){a.textContent=this.convertPolyfillDirectives(a.textContent,b)},this)},convertPolyfillDirectives:function(a,b){for(var c,d,e="",f=0;c=n.exec(a);)e+=a.substring(f,c.index),d=c[1].slice(0,-2).replace(q,b),e+=this.scopeSelector(d,b)+"{",f=n.lastIndex;return e+=a.substring(f,a.length)},applyShimming:function(a,b){var c=this.shimAtHost(a,b);c+=this.shimScoping(a,b),e(c)},shimAtHost:function(a,b){return a?this.convertAtHostStyles(a,b):void 0},convertAtHostStyles:function(a,e){for(var f,g=b(a),h="",j=0;f=i.exec(g);)h+=g.substring(j,f.index),h+=this.scopeHostCss(f[1],e),j=i.lastIndex;h+=g.substring(j,g.length);var k=new RegExp("^"+e+p,"m"),g=d(this.findAtHostRules(c(h),k));return g},scopeHostCss:function(a,b){for(var c,d="";c=j.exec(a);)d+=this.scopeHostSelector(c[1],b)+" "+c[2]+"\n ";return d},scopeHostSelector:function(a,b){var c=[],d=a.split(","),e="[is="+b+"]";return d.forEach(function(a){a=a.trim(),a.match(k)?a=a.replace(k,b+"$1$3, "+e+"$1$3"):a.match(l)&&(a=b+a+", "+e+a),c.push(a)},this),c.join(", ")},findAtHostRules:function(a,b){return Array.prototype.filter.call(a,this.isHostRule.bind(this,b))},isHostRule:function(a,b){return b.selectorText&&b.selectorText.match(a)||b.cssRules&&this.findAtHostRules(b.cssRules,a).length||b.type==CSSRule.WEBKIT_KEYFRAMES_RULE},shimScoping:function(a,b){return a?this.convertScopedStyles(a,b):void 0},convertScopedStyles:function(a,d){Array.prototype.forEach.call(a,function(a){a.parentNode&&a.parentNode.removeChild(a)});var e=b(a).replace(i,"");e=this.convertPseudos(e);var f=c(e);return e=this.scopeRules(f,d)},convertPseudos:function(a){return a.replace(o," [pseudo=$1]")},scopeRules:function(a,b){var c="";return Array.prototype.forEach.call(a,function(a){a.selectorText&&a.style&&a.style.cssText?(c+=this.scopeSelector(a.selectorText,b,this.strictStyling)+" {\n ",c+=this.propertiesFromRule(a)+"\n}\n\n"):a.media?(c+="@media "+a.media.mediaText+" {\n",c+=this.scopeRules(a.cssRules,b),c+="\n}\n\n"):a.cssText&&(c+=a.cssText+"\n\n")},this),c},scopeSelector:function(a,b,c){var d=[],e=a.split(",");return e.forEach(function(a){a=a.trim(),this.selectorNeedsScoping(a,b)&&(a=c?this.applyStrictSelectorScope(a,b):this.applySimpleSelectorScope(a,b)),d.push(a)},this),d.join(", ")},selectorNeedsScoping:function(a,b){var c="("+b+"|\\[is="+b+"\\])",d=new RegExp("^"+c+p,"m");return!a.match(d)},applySimpleSelectorScope:function(a,b){return b+" "+a+", "+"[is="+b+"] "+a},applyStrictSelectorScope:function(a,b){var c=[" ",">","+","~"],d=a,e="["+b+"]";return c.forEach(function(a){var b=d.split(a);d=b.map(function(a){var b=a.trim();return b&&c.indexOf(b)<0&&b.indexOf(e)<0&&(a=b.replace(/([^:]*)(:*)(.*)/,"$1"+e+"$2$3")),a}).join(a)}),d},propertiesFromRule:function(a){var b=a.style.cssText;return a.style.content&&!a.style.content.match(/['"]+/)&&(b="content: '"+a.style.content+"';\n"+a.style.cssText.replace(/content:[^;]*;/g,"")),b}},i=/@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,j=/([^{]*)({[\s\S]*?})/gim,k=/(.*)((?:\*)|(?:\:scope))(.*)/,l=/^[.\[:]/,m=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,n=/\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,o=/::(x-[^\s{,(]*)/gim,p="([>\\s~+[.,{:][\\s\\S]*)?$",q=/@host/gim;if(window.ShadowDOMPolyfill){e("style { display: none !important; }\n");var r=document.querySelector("head");r.insertBefore(f(),r.childNodes[0])}a.ShadowCSS=h}(window.Platform),function(a){function b(a,b){if(window.ShadowDOMPolyfill){for(var h,i=this.convertPolyfillDirectives(a,b),j="",k=0;h=e.exec(i);)j+=i.substring(k,h.index),j+=this.scopeHostCss(h[1],b),k=e.lastIndex;j+=i.substring(k,i.length);var l=new RegExp("^"+b+g,"m"),m=d(this.findAtHostRules(c(j),l));i=i.replace(f,""),i=this.convertPseudos(i);var n=c(i),o=this.scopeRules(n,b);return m+o}}function c(a){var b=document.createElement("style");b.textContent=a,document.head.appendChild(b);var c=b.sheet.cssRules;return b.parentNode.removeChild(b),c}function d(a){for(var b=0,c=[];b<a.length;b++)c.push(a[b].cssText);return c.join("\n\n")}var e=/@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,f=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,g="([>\\s~+[.,{:][\\s\\S]*)?$";a.ShadowCSS.shimShadowDOMStyling2=b}(window.Platform)}
\ No newline at end of file
diff --git a/pkg/shadow_dom/lib/src/platform/patches-shadowdom-polyfill.js b/pkg/shadow_dom/lib/src/platform/patches-shadowdom-polyfill.js
index 57c8c59..1b0014c 100644
--- a/pkg/shadow_dom/lib/src/platform/patches-shadowdom-polyfill.js
+++ b/pkg/shadow_dom/lib/src/platform/patches-shadowdom-polyfill.js
@@ -30,8 +30,10 @@
// TODO(jmesserly): do we still need these?
if (obj instanceof NodeList) return 'NodeList';
if (obj instanceof ShadowRoot) return 'ShadowRoot';
- if (obj instanceof MutationRecord) return 'MutationRecord';
- if (obj instanceof MutationObserver) return 'MutationObserver';
+ if (window.MutationRecord && (obj instanceof MutationRecord))
+ return 'MutationRecord';
+ if (window.MutationObserver && (obj instanceof MutationObserver))
+ return 'MutationObserver';
var unwrapped = unwrapIfNeeded(obj);
if (obj !== unwrapped) {
diff --git a/pkg/shadow_dom/tool/build/if-poly.js b/pkg/shadow_dom/tool/build/if-poly.js
index 7503d65..95d4d6b 100644
--- a/pkg/shadow_dom/tool/build/if-poly.js
+++ b/pkg/shadow_dom/tool/build/if-poly.js
@@ -1,3 +1,2 @@
-if ((!HTMLElement.prototype.createShadowRoot &&
- !HTMLElement.prototype.webkitCreateShadowRoot) ||
- window.__forceShadowDomPolyfill) {
+if (!HTMLElement.prototype.createShadowRoot
+ || window.__forceShadowDomPolyfill) {
diff --git a/pkg/stack_trace/lib/src/frame.dart b/pkg/stack_trace/lib/src/frame.dart
index b222737..797bef1 100644
--- a/pkg/stack_trace/lib/src/frame.dart
+++ b/pkg/stack_trace/lib/src/frame.dart
@@ -11,12 +11,13 @@
// #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21)
final _vmFrame = new RegExp(
- r'^#\d+\s+([^\s].*) \((.+):(\d+):(\d+)\)$');
+ r'^#\d+\s+([^\s].*) \((.+?):(\d+)(?::(\d+))?\)$');
// at VW.call$0 (http://pub.dartlang.org/stuff.dart.js:560:28)
// at http://pub.dartlang.org/stuff.dart.js:560:28
final _v8Frame = new RegExp(
- r'^\s*at (?:([^\s].*) \((.+):(\d+):(\d+)\)|(.+):(\d+):(\d+))$');
+ r'^\s*at (?:([^\s].*?)(?: \[as [^\]]+\])? '
+ r'\((.+):(\d+):(\d+)\)|(.+):(\d+):(\d+))$');
// .VW.call$0@http://pub.dartlang.org/stuff.dart.js:560
// .VW.call$0("arg")@http://pub.dartlang.org/stuff.dart.js:560
@@ -108,9 +109,17 @@
throw new FormatException("Couldn't parse VM stack trace line '$frame'.");
}
- var uri = Uri.parse(match[2]);
+ // Get the pieces out of the regexp match. Function, URI and line should
+ // always be found. The column is optional.
var member = match[1].replaceAll("<anonymous closure>", "<fn>");
- return new Frame(uri, int.parse(match[3]), int.parse(match[4]), member);
+ var uri = Uri.parse(match[2]);
+ var line = int.parse(match[3]);
+ var column = null;
+ var columnMatch = match[4];
+ if (columnMatch != null) {
+ column = int.parse(columnMatch);
+ }
+ return new Frame(uri, line, column, member);
}
/// Parses a string representation of a Chrome/V8 stack frame.
diff --git a/pkg/stack_trace/test/frame_test.dart b/pkg/stack_trace/test/frame_test.dart
index 0be717d..62cfd2e 100644
--- a/pkg/stack_trace/test/frame_test.dart
+++ b/pkg/stack_trace/test/frame_test.dart
@@ -10,7 +10,7 @@
void main() {
group('.parseVM', () {
- test('parses a stack frame correctly', () {
+ test('parses a stack frame with column correctly', () {
var frame = new Frame.parseVM("#1 Foo._bar "
"(file:///home/nweiz/code/stuff.dart:42:21)");
expect(frame.uri,
@@ -20,6 +20,16 @@
expect(frame.member, equals('Foo._bar'));
});
+ test('parses a stack frame without column correctly', () {
+ var frame = new Frame.parseVM("#1 Foo._bar "
+ "(file:///home/nweiz/code/stuff.dart:24)");
+ expect(frame.uri,
+ equals(Uri.parse("file:///home/nweiz/code/stuff.dart")));
+ expect(frame.line, equals(24));
+ expect(frame.column, null);
+ expect(frame.member, equals('Foo._bar'));
+ });
+
test('converts "<anonymous closure>" to "<fn>"', () {
String parsedMember(String member) =>
new Frame.parseVM('#0 $member (foo:0:0)').member;
@@ -44,8 +54,6 @@
expect(() => new Frame.parseVM('#1 Foo'), throwsFormatException);
expect(() => new Frame.parseVM('#1 Foo (dart:async/future.dart)'),
throwsFormatException);
- expect(() => new Frame.parseVM('#1 Foo (dart:async/future.dart:10)'),
- throwsFormatException);
expect(() => new Frame.parseVM('#1 (dart:async/future.dart:10:15)'),
throwsFormatException);
expect(() => new Frame.parseVM('Foo (dart:async/future.dart:10:15)'),
@@ -74,6 +82,18 @@
expect(frame.member, equals('<fn>'));
});
+ test('parses a stack frame with [as ...] correctly', () {
+ // Ignore "[as ...]", since other stack trace formats don't support a
+ // similar construct.
+ var frame = new Frame.parseV8(" at VW.call\$0 [as call\$4] "
+ "(http://pub.dartlang.org/stuff.dart.js:560:28)");
+ expect(frame.uri,
+ equals(Uri.parse("http://pub.dartlang.org/stuff.dart.js")));
+ expect(frame.line, equals(560));
+ expect(frame.column, equals(28));
+ expect(frame.member, equals('VW.call\$0'));
+ });
+
test('converts "<anonymous>" to "<fn>"', () {
String parsedMember(String member) =>
new Frame.parseV8(' at $member (foo:0:0)').member;
diff --git a/pkg/yaml/lib/src/yaml_map.dart b/pkg/yaml/lib/src/yaml_map.dart
index aa8397c..50ae2d9 100644
--- a/pkg/yaml/lib/src/yaml_map.dart
+++ b/pkg/yaml/lib/src/yaml_map.dart
@@ -23,6 +23,12 @@
YamlMap._wrap(this._map);
+ void addAll(Map other) {
+ other.forEach((key, value) {
+ this[key] = value;
+ });
+ }
+
bool containsValue(value) => _map.containsValue(value);
bool containsKey(key) => _map.containsKey(_wrapKey(key));
operator [](key) => _map[_wrapKey(key)];
diff --git a/runtime/PRESUBMIT.py b/runtime/PRESUBMIT.py
index 7c76202..ccaa35d 100644
--- a/runtime/PRESUBMIT.py
+++ b/runtime/PRESUBMIT.py
@@ -4,6 +4,7 @@
import os
import cpplint
+import re
class PathHackException(Exception):
@@ -54,6 +55,7 @@
def RunLint(input_api, output_api):
result = []
cpplint._cpplint_state.ResetErrorCounts()
+ memcpy_match_count = 0
# Find all .cc and .h files in the change list.
for svn_file in input_api.AffectedTextFiles():
filename = svn_file.AbsoluteLocalPath()
@@ -71,8 +73,23 @@
cpplint.ProcessFile(filename, 1)
if cleanup is not None:
cleanup()
+ # memcpy does not handle overlapping memory regions. Even though this
+ # is well documented it seems to be used in error quite often. To avoid
+ # problems we disallow the direct use of memcpy. The exceptions are in
+ # third-party code and in platform/globals.h which uses it to implement
+ # bit_cast and bit_copy.
+ if not filename.endswith(os.path.join('platform', 'globals.h')) and \
+ filename.find('third_party') == -1:
+ fh = open(filename, 'r')
+ content = fh.read()
+ match = re.search('\\bmemcpy\\b', content)
+ if match:
+ line_number = content[0:match.start()].count('\n') + 1
+ print "%s:%d: use of memcpy is forbidden" % (filename, line_number)
+ memcpy_match_count += 1
+
# Report a presubmit error if any of the files had an error.
- if cpplint._cpplint_state.error_count > 0:
+ if cpplint._cpplint_state.error_count > 0 or memcpy_match_count > 0:
result = [output_api.PresubmitError('Failed cpplint check.')]
return result
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 2cc50c3..91702ab 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -27,6 +27,14 @@
}
+// Corelib 'Uri.base' implementation.
+Uri _uriBase() {
+ return new Uri.file(Directory.current.path + "/");
+}
+
+_getUriBaseClosure() => _uriBase;
+
+
var _httpRequestResponseCode = 0;
var _httpRequestStatusString;
var _httpRequestResponse;
diff --git a/runtime/bin/builtin_impl_sources.gypi b/runtime/bin/builtin_impl_sources.gypi
index d62c091..241aed0 100644
--- a/runtime/bin/builtin_impl_sources.gypi
+++ b/runtime/bin/builtin_impl_sources.gypi
@@ -53,8 +53,6 @@
'fdutils_macos.cc',
'hashmap_test.cc',
'isolate_data.h',
- 'native_service.h',
- 'native_service.cc',
'thread.h',
'utils.h',
'utils_android.cc',
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index e6f705b..07cc545 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -30,7 +30,6 @@
V(Directory_Delete, 2) \
V(Directory_Rename, 2) \
V(Directory_List, 3) \
- V(Directory_NewServicePort, 0) \
V(File_Open, 2) \
V(File_Exists, 1) \
V(File_Close, 1) \
@@ -59,7 +58,6 @@
V(File_GetStdioHandleType, 1) \
V(File_GetType, 2) \
V(File_AreIdentical, 2) \
- V(File_NewServicePort, 0) \
V(FileSystemWatcher_IsSupported, 0) \
V(FileSystemWatcher_ReadEvents, 1) \
V(FileSystemWatcher_UnwatchPath, 1) \
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 4239279..eabd4f3 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -659,13 +659,16 @@
Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root,
Dart_Handle builtin_lib) {
+ Dart_Handle corelib = Dart_LookupLibrary(NewString("dart:core"));
+ DART_CHECK_VALID(corelib);
+
// Setup the corelib 'print' function.
Dart_Handle print = Dart_Invoke(
builtin_lib, NewString("_getPrintClosure"), 0, NULL);
- Dart_Handle corelib = Dart_LookupLibrary(NewString("dart:core"));
Dart_Handle result = Dart_SetField(corelib,
NewString("_printClosure"),
print);
+ DART_CHECK_VALID(result);
// Setup the 'timer' factory.
Dart_Handle url = NewString(kAsyncLibURL);
@@ -680,6 +683,14 @@
DART_CHECK_VALID(Dart_Invoke(
async_lib, NewString("_setTimerFactoryClosure"), 1, args));
+ // Setup the corelib 'Uri.base' getter.
+ Dart_Handle uri_base = Dart_Invoke(
+ builtin_lib, NewString("_getUriBaseClosure"), 0, NULL);
+ DART_CHECK_VALID(uri_base);
+ result = Dart_SetField(corelib,
+ NewString("_uriBaseClosure"),
+ uri_base);
+ DART_CHECK_VALID(result);
if (IsWindowsHost()) {
// Set running on Windows flag.
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index c7b499a..323b4a9 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -13,14 +13,6 @@
namespace dart {
namespace bin {
-// Forward declaration.
-static void DirectoryService(Dart_Port, Dart_Port, Dart_CObject*);
-
-NativeService Directory::directory_service_("DirectoryService",
- DirectoryService,
- 16);
-
-
void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) {
char* current = Directory::Current();
if (current != NULL) {
@@ -148,9 +140,9 @@
}
-static CObject* DirectoryCreateRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString path(request[1]);
+CObject* Directory::CreateRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString path(request[0]);
if (Directory::Create(path.CString())) {
return CObject::True();
} else {
@@ -161,10 +153,10 @@
}
-static CObject* DirectoryDeleteRequest(const CObjectArray& request) {
- if (request.Length() == 3 && request[1]->IsString() && request[2]->IsBool()) {
- CObjectString path(request[1]);
- CObjectBool recursive(request[2]);
+CObject* Directory::DeleteRequest(const CObjectArray& request) {
+ if (request.Length() == 2 && request[0]->IsString() && request[1]->IsBool()) {
+ CObjectString path(request[0]);
+ CObjectBool recursive(request[1]);
if (Directory::Delete(path.CString(), recursive.Value())) {
return CObject::True();
} else {
@@ -175,11 +167,11 @@
}
-static CObject* DirectoryExistsRequest(const CObjectArray& request) {
+CObject* Directory::ExistsRequest(const CObjectArray& request) {
static const int kExists = 1;
static const int kDoesNotExist = 0;
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString path(request[1]);
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString path(request[0]);
Directory::ExistsResult result = Directory::Exists(path.CString());
if (result == Directory::EXISTS) {
return new CObjectInt32(CObject::NewInt32(kExists));
@@ -193,9 +185,9 @@
}
-static CObject* DirectoryCreateTempRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString path(request[1]);
+CObject* Directory::CreateTempRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString path(request[0]);
char* result = Directory::CreateTemp(path.CString());
if (result != NULL) {
CObject* temp_dir = new CObjectString(CObject::NewString(result));
@@ -218,14 +210,14 @@
return error;
}
-static CObject* DirectoryListStartRequest(const CObjectArray& request) {
- if (request.Length() == 4 &&
- request[1]->IsString() &&
- request[2]->IsBool() &&
- request[3]->IsBool()) {
- CObjectString path(request[1]);
- CObjectBool recursive(request[2]);
- CObjectBool follow_links(request[3]);
+CObject* Directory::ListStartRequest(const CObjectArray& request) {
+ if (request.Length() == 3 &&
+ request[0]->IsString() &&
+ request[1]->IsBool() &&
+ request[2]->IsBool()) {
+ CObjectString path(request[0]);
+ CObjectBool recursive(request[1]);
+ CObjectBool follow_links(request[2]);
AsyncDirectoryListing* dir_listing =
new AsyncDirectoryListing(path.CString(),
recursive.Value(),
@@ -237,7 +229,7 @@
CObjectArray* error = new CObjectArray(CObject::NewArray(3));
error->SetAt(0, new CObjectInt32(
CObject::NewInt32(AsyncDirectoryListing::kListError)));
- error->SetAt(1, request[1]);
+ error->SetAt(1, request[0]);
error->SetAt(2, err);
return error;
}
@@ -249,10 +241,10 @@
}
-static CObject* DirectoryListNextRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
- request[1]->IsIntptr()) {
- CObjectIntptr ptr(request[1]);
+CObject* Directory::ListNextRequest(const CObjectArray& request) {
+ if (request.Length() == 1 &&
+ request[0]->IsIntptr()) {
+ CObjectIntptr ptr(request[0]);
AsyncDirectoryListing* dir_listing =
reinterpret_cast<AsyncDirectoryListing*>(ptr.Value());
const int kArraySize = 128;
@@ -268,9 +260,9 @@
}
-static CObject* DirectoryListStopRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsIntptr()) {
- CObjectIntptr ptr(request[1]);
+CObject* Directory::ListStopRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsIntptr()) {
+ CObjectIntptr ptr(request[0]);
AsyncDirectoryListing* dir_listing =
reinterpret_cast<AsyncDirectoryListing*>(ptr.Value());
delete dir_listing;
@@ -280,13 +272,12 @@
}
-static CObject* DirectoryRenameRequest(const CObjectArray& request,
- Dart_Port response_port) {
- if (request.Length() == 3 &&
- request[1]->IsString() &&
- request[2]->IsString()) {
- CObjectString path(request[1]);
- CObjectString new_path(request[2]);
+CObject* Directory::RenameRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsString() &&
+ request[1]->IsString()) {
+ CObjectString path(request[0]);
+ CObjectString new_path(request[1]);
bool completed = Directory::Rename(path.CString(), new_path.CString());
if (completed) return CObject::True();
return CObject::NewOSError();
@@ -295,65 +286,6 @@
}
-static void DirectoryService(Dart_Port dest_port_id,
- Dart_Port reply_port_id,
- Dart_CObject* message) {
- CObject* response = CObject::IllegalArgumentError();
- CObjectArray request(message);
- if (message->type == Dart_CObject_kArray) {
- if (request.Length() > 1 && request[0]->IsInt32()) {
- CObjectInt32 requestType(request[0]);
- switch (requestType.Value()) {
- case Directory::kCreateRequest:
- response = DirectoryCreateRequest(request);
- break;
- case Directory::kDeleteRequest:
- response = DirectoryDeleteRequest(request);
- break;
- case Directory::kExistsRequest:
- response = DirectoryExistsRequest(request);
- break;
- case Directory::kCreateTempRequest:
- response = DirectoryCreateTempRequest(request);
- break;
- case Directory::kListStartRequest:
- response = DirectoryListStartRequest(request);
- break;
- case Directory::kListNextRequest:
- response = DirectoryListNextRequest(request);
- break;
- case Directory::kListStopRequest:
- response = DirectoryListStopRequest(request);
- break;
- case Directory::kRenameRequest:
- response = DirectoryRenameRequest(request, reply_port_id);
- break;
- default:
- UNREACHABLE();
- }
- }
- }
-
- Dart_PostCObject(reply_port_id, response->AsApiCObject());
-}
-
-
-Dart_Port Directory::GetServicePort() {
- return directory_service_.GetServicePort();
-}
-
-
-void FUNCTION_NAME(Directory_NewServicePort)(Dart_NativeArguments args) {
- Dart_SetReturnValue(args, Dart_Null());
- Dart_Port service_port = Directory::GetServicePort();
- if (service_port != ILLEGAL_PORT) {
- // Return a send port for the service port.
- Dart_Handle send_port = Dart_NewSendPort(service_port);
- Dart_SetReturnValue(args, send_port);
- }
-}
-
-
bool AsyncDirectoryListing::AddFileSystemEntityToResponse(Response type,
char* arg) {
array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type)));
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index a8786bf..210739e 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -7,7 +7,6 @@
#include "bin/builtin.h"
#include "bin/dartutils.h"
-#include "bin/native_service.h"
#include "platform/globals.h"
#include "platform/thread.h"
@@ -274,11 +273,17 @@
static char* CreateTemp(const char* const_template);
static bool Delete(const char* path, bool recursive);
static bool Rename(const char* path, const char* new_path);
- static Dart_Port GetServicePort();
+
+ static CObject* CreateRequest(const CObjectArray& request);
+ static CObject* DeleteRequest(const CObjectArray& request);
+ static CObject* ExistsRequest(const CObjectArray& request);
+ static CObject* CreateTempRequest(const CObjectArray& request);
+ static CObject* ListStartRequest(const CObjectArray& request);
+ static CObject* ListNextRequest(const CObjectArray& request);
+ static CObject* ListStopRequest(const CObjectArray& request);
+ static CObject* RenameRequest(const CObjectArray& request);
private:
- static NativeService directory_service_;
-
DISALLOW_ALLOCATION();
DISALLOW_IMPLICIT_CONSTRUCTORS(Directory);
};
diff --git a/runtime/bin/directory_patch.dart b/runtime/bin/directory_patch.dart
index 314298d..da4e014 100644
--- a/runtime/bin/directory_patch.dart
+++ b/runtime/bin/directory_patch.dart
@@ -14,6 +14,4 @@
native "Directory_Rename";
/* patch */ static List _list(String path, bool recursive, bool followLinks)
native "Directory_List";
- /* patch */ static SendPort _newServicePort()
- native "Directory_NewServicePort";
}
diff --git a/runtime/bin/eventhandler.cc b/runtime/bin/eventhandler.cc
index c25a2fa..8de036e 100644
--- a/runtime/bin/eventhandler.cc
+++ b/runtime/bin/eventhandler.cc
@@ -74,6 +74,12 @@
}
+EventHandlerImplementation* EventHandler::delegate() {
+ if (event_handler == NULL) return NULL;
+ return &event_handler->delegate_;
+}
+
+
/*
* Send data to the EventHandler thread to register for a given instance
* args[0] a ReceivePort args[1] with a notification event args[2].
diff --git a/runtime/bin/eventhandler.h b/runtime/bin/eventhandler.h
index a9b0bcd..64f9306 100644
--- a/runtime/bin/eventhandler.h
+++ b/runtime/bin/eventhandler.h
@@ -119,6 +119,8 @@
*/
static void Stop();
+ static EventHandlerImplementation* delegate();
+
private:
friend class EventHandlerImplementation;
EventHandlerImplementation delegate_;
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 170c493..59b2207 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -77,7 +77,7 @@
if (num_bytes > GetRemainingLength()) {
num_bytes = GetRemainingLength();
}
- memcpy(buffer, GetBufferStart() + index_, num_bytes);
+ memmove(buffer, GetBufferStart() + index_, num_bytes);
index_ += num_bytes;
return num_bytes;
}
@@ -85,7 +85,7 @@
int OverlappedBuffer::Write(const void* buffer, int num_bytes) {
ASSERT(num_bytes == buflen_);
- memcpy(GetBufferStart(), buffer, num_bytes);
+ memmove(GetBufferStart(), buffer, num_bytes);
data_length_ = num_bytes;
return num_bytes;
}
@@ -107,6 +107,7 @@
pending_read_(NULL),
pending_write_(NULL),
last_error_(NOERROR),
+ thread_wrote_(0),
flags_(0) {
InitializeCriticalSection(&cs_);
}
@@ -122,6 +123,7 @@
pending_read_(NULL),
pending_write_(NULL),
last_error_(NOERROR),
+ thread_wrote_(0),
flags_(0) {
InitializeCriticalSection(&cs_);
}
@@ -332,7 +334,7 @@
void FileHandle::DoClose() {
- if (GetStdHandle(STD_OUTPUT_HANDLE) == handle_) {
+ if (handle_ == GetStdHandle(STD_OUTPUT_HANDLE)) {
int fd = _open("NUL", _O_WRONLY);
ASSERT(fd >= 0);
_dup2(fd, _fileno(stdout));
@@ -358,10 +360,6 @@
}
-void DirectoryWatchHandle::DoClose() {
- Handle::DoClose();
-}
-
bool DirectoryWatchHandle::IssueRead() {
ScopedLock lock(this);
OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize);
@@ -562,30 +560,72 @@
}
+static unsigned int __stdcall WriteFileThread(void* args) {
+ Handle* handle = reinterpret_cast<Handle*>(args);
+ handle->WriteSyncCompleteAsync();
+ return 0;
+}
+
+
+void Handle::WriteSyncCompleteAsync() {
+ ASSERT(pending_write_ != NULL);
+
+ DWORD bytes_written = -1;
+ BOOL ok = WriteFile(handle_,
+ pending_write_->GetBufferStart(),
+ pending_write_->GetBufferSize(),
+ &bytes_written,
+ NULL);
+ if (!ok) {
+ if (GetLastError() != ERROR_BROKEN_PIPE) {
+ Log::PrintErr("WriteFile failed %d\n", GetLastError());
+ }
+ bytes_written = 0;
+ }
+ thread_wrote_ += bytes_written;
+ OVERLAPPED* overlapped = pending_write_->GetCleanOverlapped();
+ ok = PostQueuedCompletionStatus(event_handler_->completion_port(),
+ bytes_written,
+ reinterpret_cast<ULONG_PTR>(this),
+ overlapped);
+ if (!ok) {
+ FATAL("PostQueuedCompletionStatus failed");
+ }
+}
+
+
int Handle::Write(const void* buffer, int num_bytes) {
ScopedLock lock(this);
+ if (pending_write_ != NULL) return 0;
+ if (num_bytes > kBufferSize) num_bytes = kBufferSize;
if (SupportsOverlappedIO()) {
- if (pending_write_ != NULL) return 0;
if (completion_port_ == INVALID_HANDLE_VALUE) return 0;
- if (num_bytes > kBufferSize) num_bytes = kBufferSize;
pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
pending_write_->Write(buffer, num_bytes);
if (!IssueWrite()) return -1;
return num_bytes;
} else {
- DWORD bytes_written = -1;
- BOOL ok = WriteFile(handle_,
- buffer,
- num_bytes,
- &bytes_written,
- NULL);
- if (!ok) {
- if (GetLastError() != ERROR_BROKEN_PIPE) {
- Log::PrintErr("WriteFile failed: %d\n", GetLastError());
- }
- event_handler_->HandleClosed(this);
+ // In the case of stdout and stderr, OverlappedIO is not supported.
+ // Here we'll instead spawn a new thread for each write, to make it async.
+ // This code is actually never exposed to the user, as stdout and stderr is
+ // not available as a RawSocket, but only wrapped in a Socket.
+ // Note that we return '0', unless a thread have already completed a write.
+ // TODO(ajohnsen): Don't spawn a new thread per write. Issue 13541.
+ if (thread_wrote_ > 0) {
+ if (num_bytes > thread_wrote_) num_bytes = thread_wrote_;
+ thread_wrote_ -= num_bytes;
+ return num_bytes;
}
- return bytes_written;
+ pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
+ pending_write_->Write(buffer, num_bytes);
+ // Completing asynchronously through thread.
+ uint32_t tid;
+ uintptr_t thread_handle =
+ _beginthreadex(NULL, 32 * 1024, WriteFileThread, this, 0, &tid);
+ if (thread_handle == -1) {
+ FATAL("Failed to start write file thread");
+ }
+ return 0;
}
}
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 3adaf57..945277b 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -211,6 +211,7 @@
}
void ReadSyncCompleteAsync();
+ void WriteSyncCompleteAsync();
DWORD last_error() { return last_error_; }
void set_last_error(DWORD last_error) { last_error_ = last_error; }
@@ -241,6 +242,7 @@
OverlappedBuffer* pending_write_; // Buffer for pending write
DWORD last_error_;
+ DWORD thread_wrote_;
private:
int flags_;
@@ -272,7 +274,6 @@
virtual void EnsureInitialized(EventHandlerImplementation* event_handler);
virtual bool IsClosed();
- virtual void DoClose();
virtual bool IssueRead();
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 0ae6aad..71e5325 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -17,11 +17,6 @@
static const int kMSPerSecond = 1000;
-// Forward declaration.
-static void FileService(Dart_Port, Dart_Port, Dart_CObject*);
-
-NativeService File::file_service_("FileService", FileService, 16);
-
// The file pointer has been passed into Dart as an intptr_t and it is safe
// to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and
@@ -638,9 +633,9 @@
}
-static CObject* FileExistsRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString filename(request[1]);
+CObject* File::ExistsRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString filename(request[0]);
bool result = File::Exists(filename.CString());
return CObject::Bool(result);
}
@@ -648,9 +643,9 @@
}
-static CObject* FileCreateRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString filename(request[1]);
+CObject* File::CreateRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString filename(request[0]);
bool result = File::Create(filename.CString());
if (result) {
return CObject::True();
@@ -661,13 +656,13 @@
return CObject::IllegalArgumentError();
}
-static CObject* FileOpenRequest(const CObjectArray& request) {
+CObject* File::OpenRequest(const CObjectArray& request) {
File* file = NULL;
- if (request.Length() == 3 &&
- request[1]->IsString() &&
- request[2]->IsInt32()) {
- CObjectString filename(request[1]);
- CObjectInt32 mode(request[2]);
+ if (request.Length() == 2 &&
+ request[0]->IsString() &&
+ request[1]->IsInt32()) {
+ CObjectString filename(request[0]);
+ CObjectInt32 mode(request[1]);
File::DartFileOpenMode dart_file_mode =
static_cast<File::DartFileOpenMode>(mode.Value());
File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
@@ -683,9 +678,9 @@
}
-static CObject* FileDeleteRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString filename(request[1]);
+CObject* File::DeleteRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString filename(request[0]);
bool result = File::Delete(filename.CString());
if (result) {
return CObject::True();
@@ -697,12 +692,12 @@
}
-static CObject* FileRenameRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsString() &&
- request[2]->IsString()) {
- CObjectString old_path(request[1]);
- CObjectString new_path(request[2]);
+CObject* File::RenameRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsString() &&
+ request[1]->IsString()) {
+ CObjectString old_path(request[0]);
+ CObjectString new_path(request[1]);
bool completed = File::Rename(old_path.CString(), new_path.CString());
if (completed) return CObject::True();
return CObject::NewOSError();
@@ -711,9 +706,9 @@
}
-static CObject* FileResolveSymbolicLinksRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString filename(request[1]);
+CObject* File::ResolveSymbolicLinksRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString filename(request[0]);
char* result = File::GetCanonicalPath(filename.CString());
if (result != NULL) {
CObject* path = new CObjectString(CObject::NewString(result));
@@ -727,10 +722,10 @@
}
-static CObject* FileCloseRequest(const CObjectArray& request) {
+CObject* File::CloseRequest(const CObjectArray& request) {
intptr_t return_value = -1;
- if (request.Length() == 2 && request[1]->IsIntptr()) {
- File* file = CObjectToFilePointer(request[1]);
+ if (request.Length() == 1 && request[0]->IsIntptr()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
delete file;
return_value = 0;
@@ -739,9 +734,9 @@
}
-static CObject* FilePositionRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsIntptr()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::PositionRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsIntptr()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
intptr_t return_value = file->Position();
@@ -758,14 +753,14 @@
}
-static CObject* FileSetPositionRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsIntptr() &&
- request[2]->IsInt32OrInt64()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::SetPositionRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsIntptr() &&
+ request[1]->IsInt32OrInt64()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
- int64_t position = CObjectInt32OrInt64ToInt64(request[2]);
+ int64_t position = CObjectInt32OrInt64ToInt64(request[1]);
if (file->SetPosition(position)) {
return CObject::True();
} else {
@@ -779,14 +774,14 @@
}
-static CObject* FileTruncateRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsIntptr() &&
- request[2]->IsInt32OrInt64()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::TruncateRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsIntptr() &&
+ request[1]->IsInt32OrInt64()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
- int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
+ int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
if (file->Truncate(length)) {
return CObject::True();
} else {
@@ -800,14 +795,14 @@
}
-static CObject* FileLengthRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsIntptr()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::LengthRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsIntptr()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
- intptr_t return_value = file->Length();
+ off_t return_value = file->Length();
if (return_value >= 0) {
- return new CObjectIntptr(CObject::NewIntptr(return_value));
+ return new CObjectInt64(CObject::NewInt64(return_value));
} else {
return CObject::NewOSError();
}
@@ -819,12 +814,12 @@
}
-static CObject* FileLengthFromPathRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString filepath(request[1]);
- intptr_t return_value = File::LengthFromPath(filepath.CString());
+CObject* File::LengthFromPathRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString filepath(request[0]);
+ off_t return_value = File::LengthFromPath(filepath.CString());
if (return_value >= 0) {
- return new CObjectIntptr(CObject::NewIntptr(return_value));
+ return new CObjectInt64(CObject::NewInt64(return_value));
} else {
return CObject::NewOSError();
}
@@ -833,9 +828,9 @@
}
-static CObject* FileLastModifiedRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString filepath(request[1]);
+CObject* File::LastModifiedRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString filepath(request[0]);
int64_t return_value = File::LastModified(filepath.CString());
if (return_value >= 0) {
return new CObjectIntptr(CObject::NewInt64(return_value * kMSPerSecond));
@@ -847,9 +842,9 @@
}
-static CObject* FileFlushRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsIntptr()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::FlushRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsIntptr()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
if (file->Flush()) {
@@ -865,9 +860,9 @@
}
-static CObject* FileReadByteRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsIntptr()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::ReadByteRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsIntptr()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
uint8_t buffer;
@@ -887,14 +882,14 @@
}
-static CObject* FileWriteByteRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsIntptr() &&
- request[2]->IsInt32OrInt64()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::WriteByteRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsIntptr() &&
+ request[1]->IsInt32OrInt64()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
- int64_t byte = CObjectInt32OrInt64ToInt64(request[2]);
+ int64_t byte = CObjectInt32OrInt64ToInt64(request[1]);
uint8_t buffer = static_cast<uint8_t>(byte & 0xff);
int64_t bytes_written = file->Write(reinterpret_cast<void*>(&buffer), 1);
if (bytes_written > 0) {
@@ -910,14 +905,14 @@
}
-static CObject* FileReadRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsIntptr() &&
- request[2]->IsInt32OrInt64()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::ReadRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsIntptr() &&
+ request[1]->IsInt32OrInt64()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
- int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
+ int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
ASSERT(io_buffer != NULL);
uint8_t* data = io_buffer->value.as_external_typed_data.data;
@@ -942,14 +937,14 @@
}
-static CObject* FileReadIntoRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsIntptr() &&
- request[2]->IsInt32OrInt64()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::ReadIntoRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsIntptr() &&
+ request[1]->IsInt32OrInt64()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
- int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
+ int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
ASSERT(io_buffer != NULL);
uint8_t* data = io_buffer->value.as_external_typed_data.data;
@@ -1000,26 +995,26 @@
}
-static CObject* FileWriteFromRequest(const CObjectArray& request) {
- if (request.Length() == 5 &&
- request[1]->IsIntptr() &&
- (request[2]->IsTypedData() || request[2]->IsArray()) &&
- request[3]->IsInt32OrInt64() &&
- request[4]->IsInt32OrInt64()) {
- File* file = CObjectToFilePointer(request[1]);
+CObject* File::WriteFromRequest(const CObjectArray& request) {
+ if (request.Length() == 4 &&
+ request[0]->IsIntptr() &&
+ (request[1]->IsTypedData() || request[1]->IsArray()) &&
+ request[2]->IsInt32OrInt64() &&
+ request[3]->IsInt32OrInt64()) {
+ File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
- int64_t start = CObjectInt32OrInt64ToInt64(request[3]);
- int64_t end = CObjectInt32OrInt64ToInt64(request[4]);
+ int64_t start = CObjectInt32OrInt64ToInt64(request[2]);
+ int64_t end = CObjectInt32OrInt64ToInt64(request[3]);
int64_t length = end - start;
uint8_t* buffer_start;
- if (request[2]->IsTypedData()) {
- CObjectTypedData typed_data(request[2]);
+ if (request[1]->IsTypedData()) {
+ CObjectTypedData typed_data(request[1]);
start = start * SizeInBytes(typed_data.Type());
length = length * SizeInBytes(typed_data.Type());
buffer_start = typed_data.Buffer() + start;
} else {
- CObjectArray array(request[2]);
+ CObjectArray array(request[1]);
buffer_start = new uint8_t[length];
for (int i = 0; i < length; i++) {
if (array[i + start]->IsInt32OrInt64()) {
@@ -1035,7 +1030,7 @@
}
int64_t bytes_written =
file->Write(reinterpret_cast<void*>(buffer_start), length);
- if (!request[2]->IsTypedData()) {
+ if (!request[1]->IsTypedData()) {
delete[] buffer_start;
}
if (bytes_written >= 0) {
@@ -1051,14 +1046,14 @@
}
-static CObject* FileCreateLinkRequest(const CObjectArray& request) {
- if (request.Length() != 3 ||
- !request[1]->IsString() ||
- !request[2]->IsString()) {
+CObject* File::CreateLinkRequest(const CObjectArray& request) {
+ if (request.Length() != 2 ||
+ !request[0]->IsString() ||
+ !request[1]->IsString()) {
return CObject::IllegalArgumentError();
}
- CObjectString link_name(request[1]);
- CObjectString target_name(request[2]);
+ CObjectString link_name(request[0]);
+ CObjectString target_name(request[1]);
if (File::CreateLink(link_name.CString(), target_name.CString())) {
return CObject::True();
} else {
@@ -1067,9 +1062,9 @@
}
-static CObject* FileDeleteLinkRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString link_path(request[1]);
+CObject* File::DeleteLinkRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString link_path(request[0]);
bool result = File::DeleteLink(link_path.CString());
if (result) {
return CObject::True();
@@ -1081,12 +1076,12 @@
}
-static CObject* FileRenameLinkRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsString() &&
- request[2]->IsString()) {
- CObjectString old_path(request[1]);
- CObjectString new_path(request[2]);
+CObject* File::RenameLinkRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsString() &&
+ request[1]->IsString()) {
+ CObjectString old_path(request[0]);
+ CObjectString new_path(request[1]);
bool completed = File::RenameLink(old_path.CString(), new_path.CString());
if (completed) return CObject::True();
return CObject::NewOSError();
@@ -1095,9 +1090,9 @@
}
-static CObject* FileLinkTargetRequest(const CObjectArray& request) {
- if (request.Length() == 2 && request[1]->IsString()) {
- CObjectString link_path(request[1]);
+CObject* File::LinkTargetRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString link_path(request[0]);
char* target = File::LinkTarget(link_path.CString());
if (target != NULL) {
CObject* result = new CObjectString(CObject::NewString(target));
@@ -1111,12 +1106,12 @@
}
-static CObject* FileTypeRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsString() &&
- request[2]->IsBool()) {
- CObjectString path(request[1]);
- CObjectBool follow_links(request[2]);
+CObject* File::TypeRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsString() &&
+ request[1]->IsBool()) {
+ CObjectString path(request[0]);
+ CObjectBool follow_links(request[1]);
File::Type type = File::GetType(path.CString(), follow_links.Value());
return new CObjectInt32(CObject::NewInt32(type));
}
@@ -1124,12 +1119,12 @@
}
-static CObject* FileIdenticalRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsString() &&
- request[2]->IsString()) {
- CObjectString path1(request[1]);
- CObjectString path2(request[2]);
+CObject* File::IdenticalRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsString() &&
+ request[1]->IsString()) {
+ CObjectString path1(request[0]);
+ CObjectString path2(request[1]);
File::Identical result = File::AreIdentical(path1.CString(),
path2.CString());
if (result == File::kError) {
@@ -1144,11 +1139,11 @@
}
-static CObject* FileStatRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
- request[1]->IsString()) {
+CObject* File::StatRequest(const CObjectArray& request) {
+ if (request.Length() == 1 &&
+ request[0]->IsString()) {
int64_t data[File::kStatSize];
- CObjectString path(request[1]);
+ CObjectString path(request[0]);
File::Stat(path.CString(), data);
if (data[File::kType] == File::kDoesNotExist) {
return CObject::NewOSError();
@@ -1166,118 +1161,5 @@
return CObject::IllegalArgumentError();
}
-
-static void FileService(Dart_Port dest_port_id,
- Dart_Port reply_port_id,
- Dart_CObject* message) {
- CObject* response = CObject::IllegalArgumentError();
- CObjectArray request(message);
- if (message->type == Dart_CObject_kArray) {
- if (request.Length() > 1 && request[0]->IsInt32()) {
- CObjectInt32 requestType(request[0]);
- switch (requestType.Value()) {
- case File::kExistsRequest:
- response = FileExistsRequest(request);
- break;
- case File::kCreateRequest:
- response = FileCreateRequest(request);
- break;
- case File::kOpenRequest:
- response = FileOpenRequest(request);
- break;
- case File::kDeleteRequest:
- response = FileDeleteRequest(request);
- break;
- case File::kRenameRequest:
- response = FileRenameRequest(request);
- break;
- case File::kResolveSymbolicLinksRequest:
- response = FileResolveSymbolicLinksRequest(request);
- break;
- case File::kCloseRequest:
- response = FileCloseRequest(request);
- break;
- case File::kPositionRequest:
- response = FilePositionRequest(request);
- break;
- case File::kSetPositionRequest:
- response = FileSetPositionRequest(request);
- break;
- case File::kTruncateRequest:
- response = FileTruncateRequest(request);
- break;
- case File::kLengthRequest:
- response = FileLengthRequest(request);
- break;
- case File::kLengthFromPathRequest:
- response = FileLengthFromPathRequest(request);
- break;
- case File::kLastModifiedRequest:
- response = FileLastModifiedRequest(request);
- break;
- case File::kFlushRequest:
- response = FileFlushRequest(request);
- break;
- case File::kReadByteRequest:
- response = FileReadByteRequest(request);
- break;
- case File::kWriteByteRequest:
- response = FileWriteByteRequest(request);
- break;
- case File::kReadRequest:
- response = FileReadRequest(request);
- break;
- case File::kReadIntoRequest:
- response = FileReadIntoRequest(request);
- break;
- case File::kWriteFromRequest:
- response = FileWriteFromRequest(request);
- break;
- case File::kDeleteLinkRequest:
- response = FileDeleteLinkRequest(request);
- break;
- case File::kRenameLinkRequest:
- response = FileRenameLinkRequest(request);
- break;
- case File::kCreateLinkRequest:
- response = FileCreateLinkRequest(request);
- break;
- case File::kLinkTargetRequest:
- response = FileLinkTargetRequest(request);
- break;
- case File::kTypeRequest:
- response = FileTypeRequest(request);
- break;
- case File::kIdenticalRequest:
- response = FileIdenticalRequest(request);
- break;
- case File::kStatRequest:
- response = FileStatRequest(request);
- break;
- default:
- UNREACHABLE();
- }
- }
- }
-
- Dart_PostCObject(reply_port_id, response->AsApiCObject());
-}
-
-
-Dart_Port File::GetServicePort() {
- return file_service_.GetServicePort();
-}
-
-
-void FUNCTION_NAME(File_NewServicePort)(Dart_NativeArguments args) {
- Dart_SetReturnValue(args, Dart_Null());
- Dart_Port service_port = File::GetServicePort();
- if (service_port != ILLEGAL_PORT) {
- // Return a send port for the service port.
- Dart_Handle send_port = Dart_NewSendPort(service_port);
- Dart_SetReturnValue(args, send_port);
- }
-}
-
} // namespace bin
} // namespace dart
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index a6eccce..6eec87a 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -12,7 +12,6 @@
#include "bin/builtin.h"
#include "bin/dartutils.h"
-#include "bin/native_service.h"
#include "platform/globals.h"
#include "platform/thread.h"
@@ -170,7 +169,32 @@
static FileOpenMode DartModeToFileMode(DartFileOpenMode mode);
- static Dart_Port GetServicePort();
+ static CObject* ExistsRequest(const CObjectArray& request);
+ static CObject* CreateRequest(const CObjectArray& request);
+ static CObject* DeleteRequest(const CObjectArray& request);
+ static CObject* RenameRequest(const CObjectArray& request);
+ static CObject* OpenRequest(const CObjectArray& request);
+ static CObject* ResolveSymbolicLinksRequest(const CObjectArray& request);
+ static CObject* CloseRequest(const CObjectArray& request);
+ static CObject* PositionRequest(const CObjectArray& request);
+ static CObject* SetPositionRequest(const CObjectArray& request);
+ static CObject* TruncateRequest(const CObjectArray& request);
+ static CObject* LengthRequest(const CObjectArray& request);
+ static CObject* LengthFromPathRequest(const CObjectArray& request);
+ static CObject* LastModifiedRequest(const CObjectArray& request);
+ static CObject* FlushRequest(const CObjectArray& request);
+ static CObject* ReadByteRequest(const CObjectArray& request);
+ static CObject* WriteByteRequest(const CObjectArray& request);
+ static CObject* ReadRequest(const CObjectArray& request);
+ static CObject* ReadIntoRequest(const CObjectArray& request);
+ static CObject* WriteFromRequest(const CObjectArray& request);
+ static CObject* CreateLinkRequest(const CObjectArray& request);
+ static CObject* DeleteLinkRequest(const CObjectArray& request);
+ static CObject* RenameLinkRequest(const CObjectArray& request);
+ static CObject* LinkTargetRequest(const CObjectArray& request);
+ static CObject* TypeRequest(const CObjectArray& request);
+ static CObject* IdenticalRequest(const CObjectArray& request);
+ static CObject* StatRequest(const CObjectArray& request);
private:
explicit File(FileHandle* handle) : handle_(handle) { }
@@ -181,8 +205,6 @@
// FileHandle is an OS specific class which stores data about the file.
FileHandle* handle_; // OS specific handle for the file.
- static NativeService file_service_;
-
DISALLOW_COPY_AND_ASSIGN(File);
};
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index ea121f2..93367f4 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -2,10 +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.
-patch class _FileUtils {
- /* patch */ static SendPort _newServicePort() native "File_NewServicePort";
-}
-
patch class _File {
/* patch */ static _exists(String path) native "File_Exists";
/* patch */ static _create(String path) native "File_Create";
diff --git a/runtime/bin/file_system_watcher.cc b/runtime/bin/file_system_watcher.cc
index f5efb69..7893ffb 100644
--- a/runtime/bin/file_system_watcher.cc
+++ b/runtime/bin/file_system_watcher.cc
@@ -35,7 +35,7 @@
bool recursive = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3));
intptr_t id = FileSystemWatcher::WatchPath(path, events, recursive);
if (id == -1) {
- Dart_PropagateError(DartUtils::NewDartOSError());
+ Dart_ThrowException(DartUtils::NewDartOSError());
} else {
SetWatcherIdNativeField(watcher, id);
}
diff --git a/runtime/bin/io_impl_sources.gypi b/runtime/bin/io_impl_sources.gypi
index 2ace0ad..8887d10 100644
--- a/runtime/bin/io_impl_sources.gypi
+++ b/runtime/bin/io_impl_sources.gypi
@@ -23,6 +23,9 @@
'filter.cc',
'filter.h',
'filter_unsupported.cc',
+ 'io_service.cc',
+ 'io_service.h',
+ 'io_service_unsupported.cc',
'net/nss_memio.cc',
'net/nss_memio.h',
'platform.cc',
@@ -58,11 +61,14 @@
'sources!' : [
'filter_unsupported.cc',
'secure_socket_unsupported.cc',
+ 'io_service_unsupported.cc',
],
},{ # else dart_io_support == 0
'sources!' : [
'filter.cc',
'filter.h',
+ 'io_service.cc',
+ 'io_service.h',
'net/nss_memio.cc',
'net/nss_memio.h',
'secure_socket.cc',
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 9d74167..ff77b1d 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -28,6 +28,7 @@
V(Filter_Process, 4) \
V(Filter_Processed, 3) \
V(InternetAddress_Fixed, 1) \
+ V(IOService_NewServicePort, 0) \
V(Platform_NumberOfProcessors, 0) \
V(Platform_OperatingSystem, 0) \
V(Platform_PathSeparator, 0) \
@@ -53,7 +54,6 @@
V(SecureSocket_RegisterHandshakeCompleteCallback, 2) \
V(SecureSocket_Renegotiate, 4) \
V(SecureSocket_InitializeLibrary, 3) \
- V(SecureSocket_NewServicePort, 0) \
V(SecureSocket_FilterPointer, 1) \
V(ServerSocket_CreateBindListen, 5) \
V(ServerSocket_Accept, 2) \
@@ -65,7 +65,6 @@
V(Socket_GetRemotePeer, 1) \
V(Socket_GetError, 1) \
V(Socket_GetStdioHandle, 2) \
- V(Socket_NewServicePort, 0) \
V(Socket_GetType, 1) \
V(Socket_SetOption, 3) \
V(Socket_SetSocketId, 2) \
diff --git a/runtime/bin/io_service.cc b/runtime/bin/io_service.cc
new file mode 100644
index 0000000..922b98c
--- /dev/null
+++ b/runtime/bin/io_service.cc
@@ -0,0 +1,78 @@
+// 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.
+
+#include "bin/dartutils.h"
+#include "bin/directory.h"
+#include "bin/file.h"
+#include "bin/io_buffer.h"
+#include "bin/io_service.h"
+#include "bin/secure_socket.h"
+#include "bin/socket.h"
+#include "bin/thread.h"
+#include "bin/utils.h"
+
+#include "platform/globals.h"
+#include "platform/thread.h"
+#include "platform/utils.h"
+
+#include "include/dart_api.h"
+
+
+namespace dart {
+namespace bin {
+
+#define CASE_REQUEST(type, method, id) \
+ case IOService::k##type##method##Request: \
+ response = type::method##Request(data); \
+ break;
+
+void IOServiceCallback(Dart_Port dest_port_id,
+ Dart_Port reply_port_id,
+ Dart_CObject* message) {
+ CObject* response = CObject::IllegalArgumentError();
+ CObjectArray request(message);
+ if (message->type == Dart_CObject_kArray &&
+ request.Length() == 3 &&
+ request[0]->IsInt32() &&
+ request[1]->IsInt32() &&
+ request[2]->IsArray()) {
+ CObjectInt32 message_id(request[0]);
+ CObjectInt32 request_id(request[1]);
+ CObjectArray data(request[2]);
+ switch (request_id.Value()) {
+ IO_SERVICE_REQUEST_LIST(CASE_REQUEST);
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ CObjectArray result(CObject::NewArray(2));
+ result.SetAt(0, request[0]);
+ result.SetAt(1, response);
+ Dart_PostCObject(reply_port_id, result.AsApiCObject());
+}
+
+
+Dart_Port IOService::GetServicePort() {
+ Dart_Port result = Dart_NewNativePort("IOService",
+ IOServiceCallback,
+ true);
+ return result;
+}
+
+
+void FUNCTION_NAME(IOService_NewServicePort)(Dart_NativeArguments args) {
+ Dart_SetReturnValue(args, Dart_Null());
+ Dart_Port service_port = IOService::GetServicePort();
+ if (service_port != ILLEGAL_PORT) {
+ // Return a send port for the service port.
+ Dart_Handle send_port = Dart_NewSendPort(service_port);
+ Dart_SetReturnValue(args, send_port);
+ }
+}
+
+
+} // namespace bin
+} // namespace dart
+
diff --git a/runtime/bin/io_service.h b/runtime/bin/io_service.h
new file mode 100644
index 0000000..0559039
--- /dev/null
+++ b/runtime/bin/io_service.h
@@ -0,0 +1,71 @@
+// 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.
+
+#ifndef BIN_IO_SERVICE_H_
+#define BIN_IO_SERVICE_H_
+
+#include "bin/builtin.h"
+#include "bin/utils.h"
+
+
+namespace dart {
+namespace bin {
+
+#define IO_SERVICE_REQUEST_LIST(V) \
+ V(File, Exists, 0) \
+ V(File, Create, 1) \
+ V(File, Delete, 2) \
+ V(File, Rename, 3) \
+ V(File, Open, 4) \
+ V(File, ResolveSymbolicLinks, 5) \
+ V(File, Close, 6) \
+ V(File, Position, 7) \
+ V(File, SetPosition, 8) \
+ V(File, Truncate, 9) \
+ V(File, Length, 10) \
+ V(File, LengthFromPath, 11) \
+ V(File, LastModified, 12) \
+ V(File, Flush, 13) \
+ V(File, ReadByte, 14) \
+ V(File, WriteByte, 15) \
+ V(File, Read, 16) \
+ V(File, ReadInto, 17) \
+ V(File, WriteFrom, 18) \
+ V(File, CreateLink, 19) \
+ V(File, DeleteLink, 20) \
+ V(File, RenameLink, 21) \
+ V(File, LinkTarget, 22) \
+ V(File, Type, 23) \
+ V(File, Identical, 24) \
+ V(File, Stat, 25) \
+ V(Socket, Lookup, 26) \
+ V(Socket, ListInterfaces, 27) \
+ V(Socket, ReverseLookup, 28) \
+ V(Directory, Create, 29) \
+ V(Directory, Delete, 30) \
+ V(Directory, Exists, 31) \
+ V(Directory, CreateTemp, 32) \
+ V(Directory, ListStart, 33) \
+ V(Directory, ListNext, 34) \
+ V(Directory, ListStop, 35) \
+ V(Directory, Rename, 36) \
+ V(SSLFilter, ProcessFilter, 37)
+
+#define DECLARE_REQUEST(type, method, id) \
+ k##type##method##Request = id,
+
+class IOService {
+ public:
+ enum {
+IO_SERVICE_REQUEST_LIST(DECLARE_REQUEST)
+ };
+
+ static Dart_Port GetServicePort();
+};
+
+} // namespace bin
+} // namespace dart
+
+#endif // BIN_IO_SERVICE_H_
+
diff --git a/runtime/bin/io_service_patch.dart b/runtime/bin/io_service_patch.dart
new file mode 100644
index 0000000..c6a7035
--- /dev/null
+++ b/runtime/bin/io_service_patch.dart
@@ -0,0 +1,52 @@
+// 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.
+
+patch class _IOService {
+ // Lazy initialize service ports, 32 per isolate.
+ static const int _SERVICE_PORT_COUNT = 32;
+ static List<SendPort> _servicePort = new List(_SERVICE_PORT_COUNT);
+ static ReceivePort _receivePort;
+ static SendPort _replyToPort;
+ static Map<int, Completer> _messageMap = {};
+ static int _id = 0;
+
+ /* patch */ static Future dispatch(int request, List data) {
+ int id;
+ do {
+ id = _getNextId();
+ } while (_messageMap.containsKey(id));
+ int index = id % _SERVICE_PORT_COUNT;
+ _initialize(index);
+ var completer = new Completer();
+ _messageMap[id] = completer;
+ _servicePort[index].send([id, request, data], _replyToPort);
+ return completer.future;
+ }
+
+ static void _initialize(int index) {
+ if (_servicePort[index] == null) {
+ _servicePort[index] = _newServicePort();
+ }
+ if (_receivePort == null) {
+ _receivePort = new ReceivePort();
+ _replyToPort = _receivePort.toSendPort();
+ _receivePort.receive((data, _) {
+ assert(data is List && data.length == 2);
+ _messageMap.remove(data[0]).complete(data[1]);
+ if (_messageMap.length == 0) {
+ _id = 0;
+ _receivePort.close();
+ _receivePort = null;
+ }
+ });
+ }
+ }
+
+ static int _getNextId() {
+ if (_id == 0x7FFFFFFF) _id = 0;
+ return _id++;
+ }
+
+ static SendPort _newServicePort() native "IOService_NewServicePort";
+}
diff --git a/runtime/bin/io_service_unsupported.cc b/runtime/bin/io_service_unsupported.cc
new file mode 100644
index 0000000..9e51ca1
--- /dev/null
+++ b/runtime/bin/io_service_unsupported.cc
@@ -0,0 +1,21 @@
+// 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.
+
+#include "bin/builtin.h"
+#include "bin/dartutils.h"
+
+#include "include/dart_api.h"
+
+
+namespace dart {
+namespace bin {
+
+void FUNCTION_NAME(IOService_NewServicePort)(Dart_NativeArguments args) {
+ Dart_ThrowException(DartUtils::NewDartArgumentError(
+ "IOService is unsupported on this platform"));
+}
+
+} // namespace bin
+} // namespace dart
+
diff --git a/runtime/bin/io_sources.gypi b/runtime/bin/io_sources.gypi
index 67294c9..e5bdbe3 100644
--- a/runtime/bin/io_sources.gypi
+++ b/runtime/bin/io_sources.gypi
@@ -11,6 +11,7 @@
'file_patch.dart',
'file_system_entity_patch.dart',
'filter_patch.dart',
+ 'io_service_patch.dart',
'platform_patch.dart',
'process_patch.dart',
'socket_patch.dart',
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index b854e3d..92e08ac 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -407,6 +407,7 @@
#define CHECK_RESULT(result) \
if (Dart_IsError(result)) { \
*error = strdup(Dart_GetError(result)); \
+ *is_compile_error = Dart_IsCompilationError(result); \
Dart_ExitScope(); \
Dart_ShutdownIsolate(); \
return NULL; \
@@ -417,7 +418,8 @@
static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
const char* main,
void* data,
- char** error) {
+ char** error,
+ bool* is_compile_error) {
Dart_Isolate isolate =
Dart_CreateIsolate(script_uri, main, snapshot_buffer, data, error);
if (isolate == NULL) {
@@ -503,10 +505,12 @@
static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
const char* main,
void* data, char** error) {
+ bool is_compile_error = false;
return CreateIsolateAndSetupHelper(script_uri,
main,
new IsolateData(),
- error);
+ error,
+ &is_compile_error);
}
@@ -765,16 +769,18 @@
// Call CreateIsolateAndSetup which creates an isolate and loads up
// the specified application script.
char* error = NULL;
+ bool is_compile_error = false;
char* isolate_name = BuildIsolateName(script_name, "main");
Dart_Isolate isolate = CreateIsolateAndSetupHelper(script_name,
"main",
new IsolateData(),
- &error);
+ &error,
+ &is_compile_error);
if (isolate == NULL) {
Log::PrintErr("%s\n", error);
free(error);
delete [] isolate_name;
- return kErrorExitCode; // Indicates we encountered an error.
+ return is_compile_error ? kCompilationErrorExitCode : kErrorExitCode;
}
delete [] isolate_name;
@@ -795,7 +801,7 @@
Log::PrintErr("%s\n", Dart_GetError(result));
Dart_ExitScope();
Dart_ShutdownIsolate();
- return kErrorExitCode; // Indicates we encountered an error.
+ return DartErrorExit(result);
}
// Write the magic number to indicate file is a script snapshot.
diff --git a/runtime/bin/native_service.cc b/runtime/bin/native_service.cc
deleted file mode 100644
index 37506aa..0000000
--- a/runtime/bin/native_service.cc
+++ /dev/null
@@ -1,46 +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.
-
-#include "bin/native_service.h"
-
-#include "platform/globals.h"
-#include "bin/thread.h"
-
-
-namespace dart {
-namespace bin {
-
-NativeService::NativeService(const char* name,
- Dart_NativeMessageHandler handler,
- int number_of_ports)
- : name_(name),
- handler_(handler),
- service_ports_size_(number_of_ports),
- service_ports_index_(0) {
- service_ports_ = new Dart_Port[service_ports_size_];
- for (int i = 0; i < service_ports_size_; i++) {
- service_ports_[i] = ILLEGAL_PORT;
- }
-}
-
-
-NativeService::~NativeService() {
- delete[] service_ports_;
-}
-
-
-Dart_Port NativeService::GetServicePort() {
- MutexLocker lock(&mutex_);
- Dart_Port result = service_ports_[service_ports_index_];
- if (result == ILLEGAL_PORT) {
- result = Dart_NewNativePort(name_, handler_, true);
- ASSERT(result != ILLEGAL_PORT);
- service_ports_[service_ports_index_] = result;
- }
- service_ports_index_ = (service_ports_index_ + 1) % service_ports_size_;
- return result;
-}
-
-} // namespace bin
-} // namespace dart
diff --git a/runtime/bin/native_service.h b/runtime/bin/native_service.h
deleted file mode 100644
index c001750..0000000
--- a/runtime/bin/native_service.h
+++ /dev/null
@@ -1,53 +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.
-
-#ifndef BIN_NATIVE_SERVICE_H_
-#define BIN_NATIVE_SERVICE_H_
-
-#include "include/dart_api.h"
-#include "include/dart_native_api.h"
-#include "platform/globals.h"
-#include "platform/thread.h"
-
-
-namespace dart {
-namespace bin {
-
-// Utility class to set up a native service and allocate Dart native
-// ports to interact with it from Dart code. The number of native ports
-// allocated for each service is limited.
-class NativeService {
- public:
- // Create a native service with the given name and handler. Allow
- // the creation of [number_of_ports] native ports for the service.
- // If GetServicePort is called more than [number_of_ports] times
- // one of the already allocated native ports will be reused.
- NativeService(const char* name,
- Dart_NativeMessageHandler handler,
- int number_of_ports);
-
- ~NativeService();
-
- // Get a Dart native port for this native service.
- Dart_Port GetServicePort();
-
- private:
- // Name and handler for the native service.
- const char* name_;
- Dart_NativeMessageHandler handler_;
-
- // Allocated native ports for the service. Mutex protected since
- // the service can be used from multiple isolates.
- dart::Mutex mutex_;
- int service_ports_size_;
- Dart_Port* service_ports_;
- int service_ports_index_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(NativeService);
-};
-
-} // namespace bin
-} // namespace dart
-
-#endif // BIN_NATIVE_SERVICE_H_
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index c83afab..00514c7 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -814,7 +814,7 @@
// Calculate the exit code.
ASSERT(oh[2].GetDataSize() == 8);
uint32_t exit[2];
- memcpy(&exit, oh[2].GetFirstDataBuffer(), sizeof(exit));
+ memmove(&exit, oh[2].GetFirstDataBuffer(), sizeof(exit));
oh[2].FreeDataBuffer();
intptr_t exit_code = exit[0];
intptr_t negative = exit[1];
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index 5038266..0a2547c 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -42,13 +42,6 @@
// be null if only secure client sockets are used.
const char* SSLFilter::password_ = NULL;
-// Forward declaration.
-static void ProcessFilter(Dart_Port dest_port_id,
- Dart_Port reply_port_id,
- Dart_CObject* message);
-
-NativeService SSLFilter::filter_service_("FilterService", ProcessFilter, 16);
-
static const int kSSLFilterNativeFieldIndex = 0;
@@ -295,33 +288,32 @@
* the updated pointers from Dart and C++, to make the new valid state of
* the circular buffer.
*/
-static void ProcessFilter(Dart_Port dest_port_id,
- Dart_Port reply_port_id,
- Dart_CObject* message) {
- CObjectArray args(message);
- CObjectIntptr filter_object(args[0]);
+CObject* SSLFilter::ProcessFilterRequest(const CObjectArray& request) {
+ CObjectIntptr filter_object(request[0]);
SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value());
- bool in_handshake = CObjectBool(args[1]).Value();
+ bool in_handshake = CObjectBool(request[1]).Value();
int starts[SSLFilter::kNumBuffers];
int ends[SSLFilter::kNumBuffers];
for (int i = 0; i < SSLFilter::kNumBuffers; ++i) {
- starts[i] = CObjectInt32(args[2 * i + 2]).Value();
- ends[i] = CObjectInt32(args[2 * i + 3]).Value();
+ starts[i] = CObjectInt32(request[2 * i + 2]).Value();
+ ends[i] = CObjectInt32(request[2 * i + 3]).Value();
}
if (filter->ProcessAllBuffers(starts, ends, in_handshake)) {
+ CObjectArray* result = new CObjectArray(
+ CObject::NewArray(SSLFilter::kNumBuffers * 2));
for (int i = 0; i < SSLFilter::kNumBuffers; ++i) {
- args[2 * i + 2]->AsApiCObject()->value.as_int32 = starts[i];
- args[2 * i + 3]->AsApiCObject()->value.as_int32 = ends[i];
+ result->SetAt(2 * i, new CObjectInt32(CObject::NewInt32(starts[i])));
+ result->SetAt(2 * i + 1, new CObjectInt32(CObject::NewInt32(ends[i])));
}
- Dart_PostCObject(reply_port_id, args.AsApiCObject());
+ return result;
} else {
PRErrorCode error_code = PR_GetError();
const char* error_message = PR_ErrorToString(error_code, PR_LANGUAGE_EN);
CObjectArray* result = new CObjectArray(CObject::NewArray(2));
result->SetAt(0, new CObjectInt32(CObject::NewInt32(error_code)));
result->SetAt(1, new CObjectString(CObject::NewString(error_message)));
- Dart_PostCObject(reply_port_id, result->AsApiCObject());
+ return result;
}
}
@@ -738,19 +730,8 @@
}
} else { // Client.
if (SSL_SetURL(filter_, host_name) == -1) {
- ThrowPRException("TlsException",
- "Failed SetURL call");
+ ThrowPRException("TlsException", "Failed SetURL call");
}
-
- // This disables the SSL session cache for client connections.
- // This resolves issue 7208, but degrades performance.
- // TODO(7230): Reenable session cache, without breaking client connections.
- status = SSL_OptionSet(filter_, SSL_NO_CACHE, PR_TRUE);
- if (status != SECSuccess) {
- ThrowPRException("TlsException",
- "Failed SSL_OptionSet(NO_CACHE) call");
- }
-
if (send_client_certificate) {
SSL_SetPKCS11PinArg(filter_, const_cast<char*>(password_));
status = SSL_GetClientAuthDataHook(
@@ -964,22 +945,5 @@
return bytes_processed;
}
-
-Dart_Port SSLFilter::GetServicePort() {
- return filter_service_.GetServicePort();
-}
-
-
-void FUNCTION_NAME(SecureSocket_NewServicePort)(Dart_NativeArguments args) {
- Dart_SetReturnValue(args, Dart_Null());
- Dart_Port service_port = SSLFilter::GetServicePort();
- if (service_port != ILLEGAL_PORT) {
- // Return a send port for the service port.
- Dart_Handle send_port = Dart_NewSendPort(service_port);
- Dart_SetReturnValue(args, send_port);
- }
-}
-
-
} // namespace bin
} // namespace dart
diff --git a/runtime/bin/secure_socket.h b/runtime/bin/secure_socket.h
index 304ccd5..70c6c62 100644
--- a/runtime/bin/secure_socket.h
+++ b/runtime/bin/secure_socket.h
@@ -22,7 +22,6 @@
#include "bin/dartutils.h"
#include "bin/socket.h"
#include "bin/utils.h"
-#include "bin/native_service.h"
namespace dart {
namespace bin {
@@ -88,15 +87,15 @@
const char* password,
bool use_builtin_root_certificates,
bool report_duplicate_initialization = true);
- static Dart_Port GetServicePort();
Dart_Handle callback_error;
+ static CObject* ProcessFilterRequest(const CObjectArray& request);
+
private:
static const int kMemioBufferSize = 20 * KB;
static bool library_initialized_;
static const char* password_;
static dart::Mutex* mutex_; // To protect library initialization.
- static NativeService filter_service_;
uint8_t* buffers_[kNumBuffers];
int buffer_size_;
diff --git a/runtime/bin/secure_socket_patch.dart b/runtime/bin/secure_socket_patch.dart
index 104f562..450738a 100644
--- a/runtime/bin/secure_socket_patch.dart
+++ b/runtime/bin/secure_socket_patch.dart
@@ -15,9 +15,6 @@
patch class _SecureFilter {
/* patch */ factory _SecureFilter() => new _SecureFilterImpl();
-
- /* patch */ static SendPort _newServicePort()
- native "SecureSocket_NewServicePort";
}
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 672e333..4dfbe50 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -55,7 +55,7 @@
}
case SocketAddress::ADDRESS_LOOPBACK_IP_V6: {
raw.in6.sin6_family = AF_INET6;
- raw.in6.sin6_addr = in6addr_any;
+ raw.in6.sin6_addr = in6addr_loopback;
break;
}
case SocketAddress::ADDRESS_ANY_IP_V4: {
@@ -65,7 +65,7 @@
}
case SocketAddress::ADDRESS_ANY_IP_V6: {
raw.in6.sin6_family = AF_INET6;
- raw.in6.sin6_addr = in6addr_loopback;
+ raw.in6.sin6_addr = in6addr_any;
break;
}
default:
@@ -353,12 +353,12 @@
}
-static CObject* LookupRequest(const CObjectArray& request) {
- if (request.Length() == 3 &&
- request[1]->IsString() &&
- request[2]->IsInt32()) {
- CObjectString host(request[1]);
- CObjectInt32 type(request[2]);
+CObject* Socket::LookupRequest(const CObjectArray& request) {
+ if (request.Length() == 2 &&
+ request[0]->IsString() &&
+ request[1]->IsInt32()) {
+ CObjectString host(request[0]);
+ CObjectInt32 type(request[1]);
CObject* result = NULL;
OSError* os_error = NULL;
AddressList<SocketAddress>* addresses =
@@ -401,10 +401,10 @@
}
-static CObject* ReverseLookupRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
- request[1]->IsTypedData()) {
- CObjectUint8Array addr_object(request[1]);
+CObject* Socket::ReverseLookupRequest(const CObjectArray& request) {
+ if (request.Length() == 1 &&
+ request[0]->IsTypedData()) {
+ CObjectUint8Array addr_object(request[0]);
RawAddr addr;
memmove(reinterpret_cast<void *>(&addr),
addr_object.Buffer(),
@@ -425,10 +425,10 @@
-static CObject* ListInterfacesRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
- request[1]->IsInt32()) {
- CObjectInt32 type(request[1]);
+CObject* Socket::ListInterfacesRequest(const CObjectArray& request) {
+ if (request.Length() == 1 &&
+ request[0]->IsInt32()) {
+ CObjectInt32 type(request[0]);
CObject* result = NULL;
OSError* os_error = NULL;
AddressList<InterfaceSocketAddress>* addresses = Socket::ListInterfaces(
@@ -476,70 +476,6 @@
}
-void SocketService(Dart_Port dest_port_id,
- Dart_Port reply_port_id,
- Dart_CObject* message) {
- CObject* response = CObject::IllegalArgumentError();
- CObjectArray request(message);
- if (message->type == Dart_CObject_kArray) {
- if (request.Length() > 1 && request[0]->IsInt32()) {
- CObjectInt32 request_type(request[0]);
- switch (request_type.Value()) {
- case Socket::kLookupRequest:
- response = LookupRequest(request);
- break;
- case Socket::kListInterfacesRequest:
- response = ListInterfacesRequest(request);
- break;
- case Socket::kReverseLookupRequest:
- response = ReverseLookupRequest(request);
- break;
- default:
- UNREACHABLE();
- }
- }
- }
-
- Dart_PostCObject(reply_port_id, response->AsApiCObject());
-}
-
-
-Dart_Port Socket::GetServicePort() {
- MutexLocker lock(mutex_);
- if (service_ports_size_ == 0) {
- ASSERT(service_ports_ == NULL);
- service_ports_size_ = 16;
- service_ports_ = new Dart_Port[service_ports_size_];
- service_ports_index_ = 0;
- for (int i = 0; i < service_ports_size_; i++) {
- service_ports_[i] = ILLEGAL_PORT;
- }
- }
-
- Dart_Port result = service_ports_[service_ports_index_];
- if (result == ILLEGAL_PORT) {
- result = Dart_NewNativePort("SocketService",
- SocketService,
- true);
- ASSERT(result != ILLEGAL_PORT);
- service_ports_[service_ports_index_] = result;
- }
- service_ports_index_ = (service_ports_index_ + 1) % service_ports_size_;
- return result;
-}
-
-
-void FUNCTION_NAME(Socket_NewServicePort)(Dart_NativeArguments args) {
- Dart_SetReturnValue(args, Dart_Null());
- Dart_Port service_port = Socket::GetServicePort();
- if (service_port != ILLEGAL_PORT) {
- // Return a send port for the service port.
- Dart_Handle send_port = Dart_NewSendPort(service_port);
- Dart_SetReturnValue(args, send_port);
- }
-}
-
-
void FUNCTION_NAME(Socket_SetOption)(Dart_NativeArguments args) {
Dart_Handle socket_obj = Dart_GetNativeArgument(args, 0);
intptr_t socket = 0;
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index db76f58..d6f9b0d 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -7,6 +7,7 @@
#include "bin/builtin.h"
#include "bin/utils.h"
+#include "bin/dartutils.h"
#include "platform/globals.h"
#include "platform/thread.h"
@@ -185,6 +186,10 @@
int type,
OSError** os_error);
+ static CObject* LookupRequest(const CObjectArray& request);
+ static CObject* ListInterfacesRequest(const CObjectArray& request);
+ static CObject* ReverseLookupRequest(const CObjectArray& request);
+
static Dart_Port GetServicePort();
static Dart_Handle SetSocketIdNativeField(Dart_Handle socket, intptr_t id);
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index 39b142b..18b2bd8 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -25,10 +25,19 @@
SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
- const char* result = inet_ntop(sockaddr->sa_family,
- &raw->in.sin_addr,
- as_string_,
- INET6_ADDRSTRLEN);
+ const char* result;
+ if (sockaddr->sa_family == AF_INET) {
+ result = inet_ntop(sockaddr->sa_family,
+ &raw->in.sin_addr,
+ as_string_,
+ INET_ADDRSTRLEN);
+ } else {
+ ASSERT(sockaddr->sa_family == AF_INET6);
+ result = inet_ntop(sockaddr->sa_family,
+ &raw->in6.sin6_addr,
+ as_string_,
+ INET6_ADDRSTRLEN);
+ }
if (result == NULL) as_string_[0] = 0;
memmove(reinterpret_cast<void *>(&addr_),
sockaddr,
@@ -193,6 +202,7 @@
intptr_t Socket::GetStdioHandle(intptr_t num) {
+ Socket::SetNonBlocking(num);
return num;
}
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 63fd9c3..24e688d 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -26,10 +26,19 @@
SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
- const char* result = inet_ntop(sockaddr->sa_family,
- &raw->in.sin_addr,
- as_string_,
- INET6_ADDRSTRLEN);
+ const char* result;
+ if (sockaddr->sa_family == AF_INET) {
+ result = inet_ntop(sockaddr->sa_family,
+ &raw->in.sin_addr,
+ as_string_,
+ INET_ADDRSTRLEN);
+ } else {
+ ASSERT(sockaddr->sa_family == AF_INET6);
+ result = inet_ntop(sockaddr->sa_family,
+ &raw->in6.sin6_addr,
+ as_string_,
+ INET6_ADDRSTRLEN);
+ }
if (result == NULL) as_string_[0] = 0;
memmove(reinterpret_cast<void *>(&addr_),
sockaddr,
@@ -193,6 +202,7 @@
intptr_t Socket::GetStdioHandle(intptr_t num) {
+ Socket::SetNonBlocking(num);
return num;
}
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 3b52c09..2b6138f 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -26,10 +26,19 @@
SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
- const char* result = inet_ntop(sockaddr->sa_family,
- &raw->in.sin_addr,
- as_string_,
- INET6_ADDRSTRLEN);
+ const char* result;
+ if (sockaddr->sa_family == AF_INET) {
+ result = inet_ntop(sockaddr->sa_family,
+ &raw->in.sin_addr,
+ as_string_,
+ INET_ADDRSTRLEN);
+ } else {
+ ASSERT(sockaddr->sa_family == AF_INET6);
+ result = inet_ntop(sockaddr->sa_family,
+ &raw->in6.sin6_addr,
+ as_string_,
+ INET6_ADDRSTRLEN);
+ }
if (result == NULL) as_string_[0] = 0;
memmove(reinterpret_cast<void *>(&addr_),
sockaddr,
@@ -193,6 +202,7 @@
intptr_t Socket::GetStdioHandle(intptr_t num) {
+ Socket::SetNonBlocking(num);
return num;
}
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index f4f07af..0042aed 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -220,13 +220,9 @@
// Holds the address used to connect or bind the socket.
InternetAddress address;
- // Native port for socket services.
- static SendPort socketService;
-
static Future<List<InternetAddress>> lookup(
String host, {InternetAddressType type: InternetAddressType.ANY}) {
- ensureSocketService();
- return socketService.call([HOST_NAME_LOOKUP, host, type._value])
+ return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value])
.then((response) {
if (isErrorResponse(response)) {
throw createError(response, "Failed host lookup: '$host'");
@@ -240,8 +236,7 @@
}
static Future<InternetAddress> reverseLookup(InternetAddress addr) {
- ensureSocketService();
- return socketService.call([REVERSE_LOOKUP, addr._sockaddr_storage])
+ return _IOService.dispatch(_SOCKET_REVERSE_LOOKUP, [addr._sockaddr_storage])
.then((response) {
if (isErrorResponse(response)) {
throw createError(response, "Failed reverse host lookup", addr);
@@ -255,8 +250,7 @@
bool includeLoopback: false,
bool includeLinkLocal: false,
InternetAddressType type: InternetAddressType.ANY}) {
- ensureSocketService();
- return socketService.call([LIST_INTERFACES, type._value])
+ return _IOService.dispatch(_SOCKET_LIST_INTERFACES, [type._value])
.then((response) {
if (isErrorResponse(response)) {
throw createError(response, "Failed listing interfaces");
@@ -295,7 +289,6 @@
});
})
.then((address) {
- ensureSocketService();
var socket = new _NativeSocket.normal();
socket.address = address;
var result = socket.nativeCreateConnect(
@@ -605,12 +598,6 @@
}
}
- static void ensureSocketService() {
- if (socketService == null) {
- socketService = _NativeSocket.newServicePort();
- }
- }
-
// Check whether this is an error response from a native port call.
static bool isErrorResponse(response) {
return response is List && response[0] != _SUCCESS_RESPONSE;
@@ -673,8 +660,6 @@
List nativeGetRemotePeer() native "Socket_GetRemotePeer";
OSError nativeGetError() native "Socket_GetError";
bool nativeSetOption(int option, bool enabled) native "Socket_SetOption";
-
- static SendPort newServicePort() native "Socket_NewServicePort";
}
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 696f8cc..87a0b30 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -201,6 +201,7 @@
FileHandle* file_handle = new FileHandle(handle);
if (file_handle == NULL) return -1;
file_handle->MarkDoesNotSupportOverlappedIO();
+ file_handle->EnsureInitialized(EventHandler::delegate());
return reinterpret_cast<intptr_t>(file_handle);
}
diff --git a/runtime/bin/stdin_android.cc b/runtime/bin/stdin_android.cc
index 9082deb..816023a 100644
--- a/runtime/bin/stdin_android.cc
+++ b/runtime/bin/stdin_android.cc
@@ -8,16 +8,19 @@
#include <termios.h> // NOLINT
#include "bin/stdin.h"
+#include "bin/fdutils.h"
namespace dart {
namespace bin {
int Stdin::ReadByte() {
+ FDUtils::SetBlocking(fileno(stdin));
int c = getchar();
if (c == EOF) {
c = -1;
}
+ FDUtils::SetNonBlocking(fileno(stdin));
return c;
}
diff --git a/runtime/bin/stdin_linux.cc b/runtime/bin/stdin_linux.cc
index 43e9e78..4f95198 100644
--- a/runtime/bin/stdin_linux.cc
+++ b/runtime/bin/stdin_linux.cc
@@ -8,16 +8,19 @@
#include <termios.h> // NOLINT
#include "bin/stdin.h"
+#include "bin/fdutils.h"
namespace dart {
namespace bin {
int Stdin::ReadByte() {
+ FDUtils::SetBlocking(fileno(stdin));
int c = getchar();
if (c == EOF) {
c = -1;
}
+ FDUtils::SetNonBlocking(fileno(stdin));
return c;
}
diff --git a/runtime/bin/stdin_macos.cc b/runtime/bin/stdin_macos.cc
index cb37a8b..0bea869 100644
--- a/runtime/bin/stdin_macos.cc
+++ b/runtime/bin/stdin_macos.cc
@@ -8,16 +8,19 @@
#include <termios.h> // NOLINT
#include "bin/stdin.h"
+#include "bin/fdutils.h"
namespace dart {
namespace bin {
int Stdin::ReadByte() {
+ FDUtils::SetBlocking(fileno(stdin));
int c = getchar();
if (c == EOF) {
c = -1;
}
+ FDUtils::SetNonBlocking(fileno(stdin));
return c;
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 80fc69b..a09f212 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -365,7 +365,9 @@
/**
* Checks to see if two handles refer to identically equal objects.
*
- * This is equivalent to using the triple-equals (===) operator.
+ * If both handles refer to instances, this is equivalent to using the top-level
+ * function identical() from dart:core. Otherwise, returns whether the two
+ * argument handles refer to the same object.
*
* \param obj1 An object to be compared.
* \param obj2 An object to be compared.
@@ -1143,7 +1145,6 @@
DART_EXPORT bool Dart_IsList(Dart_Handle object);
DART_EXPORT bool Dart_IsLibrary(Dart_Handle object);
DART_EXPORT bool Dart_IsType(Dart_Handle handle);
-DART_EXPORT bool Dart_IsClass(Dart_Handle handle);
DART_EXPORT bool Dart_IsFunction(Dart_Handle handle);
DART_EXPORT bool Dart_IsVariable(Dart_Handle handle);
DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle);
@@ -1174,18 +1175,6 @@
*/
DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance);
-/**
- * TODO(asiva): Deprecate this method once all use cases have switched
- * to using Dart_InstanceGetType
- * Gets the class for some Dart language object.
- *
- * \param instance Some Dart object.
- *
- * \return If no error occurs, the class is returned. Otherwise an
- * error handle is returned.
- */
-DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance);
-
/*
* =============================
@@ -1968,6 +1957,11 @@
typedef struct _Dart_NativeArguments* Dart_NativeArguments;
/**
+ * Extracts current isolate data from the native arguments structure.
+ */
+DART_EXPORT void* Dart_GetNativeIsolateData(Dart_NativeArguments args);
+
+/**
* Gets the native argument at some index.
*/
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args,
diff --git a/runtime/include/dart_debugger_api.h b/runtime/include/dart_debugger_api.h
index 605176a..12433b9 100755
--- a/runtime/include/dart_debugger_api.h
+++ b/runtime/include/dart_debugger_api.h
@@ -517,16 +517,6 @@
/**
- * Returns the superclass of the given class \cls.
- *
- * Requires there to be a current isolate.
- *
- * \return A handle to the class object.
- */
-DART_EXPORT Dart_Handle Dart_GetSuperclass(Dart_Handle cls);
-
-
-/**
* Returns the supertype of the given instantiated type \cls.
*
* Requires there to be a current isolate.
diff --git a/runtime/include/dart_mirrors_api.h b/runtime/include/dart_mirrors_api.h
index 23ec4e9..3a4c9ce 100644
--- a/runtime/include/dart_mirrors_api.h
+++ b/runtime/include/dart_mirrors_api.h
@@ -11,14 +11,14 @@
/**
- * Returns the class name for the provided class.
+ * Returns the simple name for the provided type.
*/
-DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle type);
+DART_EXPORT Dart_Handle Dart_TypeName(Dart_Handle type);
/**
- * Returns the qualified class name for the provided class.
+ * Returns the qualified name for the provided type.
*/
-DART_EXPORT Dart_Handle Dart_QualifiedClassName(Dart_Handle type);
+DART_EXPORT Dart_Handle Dart_QualifiedTypeName(Dart_Handle type);
/**
* Returns a list of the names of all functions or methods declared in
diff --git a/runtime/lib/bool_patch.dart b/runtime/lib/bool_patch.dart
index 60b5596..e6463fe 100644
--- a/runtime/lib/bool_patch.dart
+++ b/runtime/lib/bool_patch.dart
@@ -6,7 +6,7 @@
patch class bool {
- int get hashCode {
+ int get _identityHashCode {
return this ? 1231 : 1237;
}
}
diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
index 61cf8d6..9f0c74f 100644
--- a/runtime/lib/collection_patch.dart
+++ b/runtime/lib/collection_patch.dart
@@ -11,12 +11,15 @@
if (equals == null) {
return new _HashMap<K, V>();
}
- if (identical(identical, equals)) {
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
return new _IdentityHashMap<K, V>();
}
- hashCode = _defaultHashCode;
- } else if (equals == null) {
- equals = _defaultEquals;
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
} else {
if (hashCode == null) {
@@ -28,14 +31,16 @@
}
return new _CustomHashMap<K, V>(equals, hashCode, isValidKey);
}
+
+ /* patch */ factory HashMap.identity() = _IdentityHashMap<K, V>;
}
+
const int _MODIFICATION_COUNT_MASK = 0x3fffffff;
class _HashMap<K, V> implements HashMap<K, V> {
static const int _INITIAL_CAPACITY = 8;
- Type get runtimeType => HashMap;
int _elementCount = 0;
List<_HashMapEntry> _buckets = new List(_INITIAL_CAPACITY);
@@ -226,7 +231,6 @@
_CustomHashMap(this._equals, this._hashCode, validKey)
: _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test;
- Type get runtimeType => HashMap;
bool containsKey(Object key) {
if (!_validKey(key)) return false;
@@ -320,10 +324,9 @@
}
class _IdentityHashMap<K, V> extends _HashMap<K, V> {
- Type get runtimeType => HashMap;
bool containsKey(Object key) {
- int hashCode = key.hashCode;
+ int hashCode = identityHashCode(key);
List buckets = _buckets;
int index = hashCode & (buckets.length - 1);
_HashMapEntry entry = buckets[index];
@@ -335,7 +338,7 @@
}
V operator[](Object key) {
- int hashCode = key.hashCode;
+ int hashCode = identityHashCode(key);
List buckets = _buckets;
int index = hashCode & (buckets.length - 1);
_HashMapEntry entry = buckets[index];
@@ -349,7 +352,7 @@
}
void operator []=(K key, V value) {
- int hashCode = key.hashCode;
+ int hashCode = identityHashCode(key);
List buckets = _buckets;
int length = buckets.length;
int index = hashCode & (length - 1);
@@ -365,7 +368,7 @@
}
V putIfAbsent(K key, V ifAbsent()) {
- int hashCode = key.hashCode;
+ int hashCode = identityHashCode(key);
List buckets = _buckets;
int length = buckets.length;
int index = hashCode & (length - 1);
@@ -387,7 +390,7 @@
}
V remove(Object key) {
- int hashCode = key.hashCode;
+ int hashCode = identityHashCode(key);
List buckets = _buckets;
int index = hashCode & (buckets.length - 1);
_HashMapEntry entry = buckets[index];
@@ -512,20 +515,28 @@
if (equals == null) {
return new _HashSet<E>();
}
- if (identical(identical, equals)) {
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
return new _IdentityHashSet<E>();
}
- _hashCode = _defaultHashCode;
- } else if (equals == null) {
- _equals = _defaultEquals;
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
- isValidKey = new _TypeTest<E>().test;
} else {
- if (hashCode == null) hashCode = _defaultHashCode;
- if (equals == null) equals = _defaultEquals;
+ if (hashCode == null) {
+ hashCode = _defaultHashCode;
+ }
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
return new _CustomHashSet<E>(equals, hashCode, isValidKey);
}
+
+ /* patch */ factory HashSet.identity() = _IdentityHashSet<E>;
}
class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> {
@@ -691,6 +702,7 @@
}
class _IdentityHashSet<E> extends _HashSet<E> {
+ int _hashCode(e) => identityHashCode(e);
bool _equals(e1, e2) => identical(e1, e2);
HashSet<E> _newSet() => new _IdentityHashSet<E>();
}
@@ -699,7 +711,8 @@
final _Equality<E> _equality;
final _Hasher<E> _hasher;
final _Predicate _validKey;
- _CustomHashSet(this._equality, this._hasher, this._validKey);
+ _CustomHashSet(this._equality, this._hasher, bool validKey(Object o))
+ : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
bool remove(Object element) {
if (!_validKey(element)) return false;
@@ -880,12 +893,15 @@
if (equals == null) {
return new _LinkedHashMap<K, V>();
}
- if (identical(identical, equals)) {
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
return new _LinkedIdentityHashMap<K, V>();
}
- hashCode = _defaultHashCode;
- } else if (equals == null) {
- equals = _defaultEquals;
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
} else {
if (hashCode == null) {
@@ -897,6 +913,8 @@
}
return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
}
+
+ /* patch */ factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>;
}
// Methods that are exactly the same in all three linked hash map variants.
@@ -904,7 +922,6 @@
var _nextEntry;
var _previousEntry;
- Type get runtimeType => LinkedHashMap;
bool containsValue(Object value) {
int modificationCount = _modificationCount;
@@ -1008,20 +1025,28 @@
if (equals == null) {
return new _LinkedHashSet<E>();
}
- if (identical(identical, equals)) {
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
return new _LinkedIdentityHashSet<E>();
}
- _hashCode = _defaultHashCode;
- } else if (equals == null) {
- _equals = _defaultEquals;
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
- isValidKey = new _TypeTest<E>().test;
} else {
- if (hashCode == null) hashCode = _defaultHashCode;
- if (equals == null) equals = _defaultEquals;
+ if (hashCode == null) {
+ hashCode = _defaultHashCode;
+ }
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
return new _LinkedCustomHashSet<E>(equals, hashCode, isValidKey);
}
+
+ /* patch */ factory LinkedHashSet.identity() = _LinkedIdentityHashSet<E>;
}
class _LinkedHashSetEntry extends _HashSetEntry {
@@ -1133,6 +1158,7 @@
}
class _LinkedIdentityHashSet<E> extends _LinkedHashSet<E> {
+ int _hashCode(e) => identityHashCode(e);
bool _equals(e1, e2) => identical(e1, e2);
HashSet<E> _newSet() => new _LinkedIdentityHashSet<E>();
}
@@ -1142,7 +1168,7 @@
final _Hasher<E> _hasher;
final _Predicate _validKey;
- _LinkedCustomHashSet(this._equality, this._hasher, bool validKey(object))
+ _LinkedCustomHashSet(this._equality, this._hasher, bool validKey(Object o))
: _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
bool _equals(e1, e2) => _equality(e1, e2);
diff --git a/runtime/lib/double.dart b/runtime/lib/double.dart
index 166d731..4aefae8 100644
--- a/runtime/lib/double.dart
+++ b/runtime/lib/double.dart
@@ -5,7 +5,7 @@
class _Double implements double {
factory _Double.fromInteger(int value)
native "Double_doubleFromInteger";
- int get hashCode {
+ int get _identityHashCode {
if (isNaN || isInfinite) return 0;
return toInt();
}
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index a1818db..1f3ee3e 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -229,7 +229,7 @@
break;
}
case _InvocationMirror._CONSTRUCTOR: {
- msg = "No constructor '$memberName' declared in class '$_receiver'.";
+ msg = "No constructor '$memberName'$args_message declared in class '$_receiver'.";
break;
}
case _InvocationMirror._TOP_LEVEL: {
diff --git a/runtime/lib/expando_patch.dart b/runtime/lib/expando_patch.dart
index 7608861..0c9427c 100644
--- a/runtime/lib/expando_patch.dart
+++ b/runtime/lib/expando_patch.dart
@@ -14,7 +14,7 @@
_checkType(object);
var mask = _size - 1;
- var idx = object.hashCode & mask;
+ var idx = object._identityHashCode & mask;
var wp = _data[idx];
while (wp != null) {
@@ -35,7 +35,7 @@
_checkType(object);
var mask = _size - 1;
- var idx = object.hashCode & mask;
+ var idx = object._identityHashCode & mask;
var empty_idx = -1;
var wp = _data[idx];
@@ -64,7 +64,7 @@
if (value == null) {
// Not entering a null value. We just needed to make sure to clear an
- // existing value if it existed.
+ // existing value if it existed.
return;
}
diff --git a/runtime/lib/identical.cc b/runtime/lib/identical.cc
index 7508f03..dac63b5 100644
--- a/runtime/lib/identical.cc
+++ b/runtime/lib/identical.cc
@@ -11,21 +11,7 @@
DEFINE_NATIVE_ENTRY(Identical_comparison, 2) {
GET_NATIVE_ARGUMENT(Instance, a, arguments->NativeArgAt(0));
GET_NATIVE_ARGUMENT(Instance, b, arguments->NativeArgAt(1));
- if (a.raw() == b.raw()) return Bool::True().raw();
- if (a.IsInteger() && b.IsInteger()) {
- return Bool::Get(a.Equals(b)).raw();
- }
- if (a.IsDouble() && b.IsDouble()) {
- if (a.Equals(b)) return Bool::True().raw();
- // Check for NaN.
- const Double& a_double = Double::Cast(a);
- const Double& b_double = Double::Cast(b);
- if (isnan(a_double.value()) && isnan(b_double.value())) {
- return Bool::True().raw();
- }
- }
- return Bool::False().raw();
+ return Bool::Get(a.IsIdenticalTo(b)).raw();
}
-
} // namespace dart
diff --git a/runtime/lib/identical_patch.dart b/runtime/lib/identical_patch.dart
index b7f8f18..172478f 100644
--- a/runtime/lib/identical_patch.dart
+++ b/runtime/lib/identical_patch.dart
@@ -3,3 +3,5 @@
// BSD-style license that can be found in the LICENSE file.
patch bool identical(Object a, Object b) native "Identical_comparison";
+
+patch int identityHashCode(Object object) => object._identityHashCode;
diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart
index 77127e5..65db0c9 100644
--- a/runtime/lib/immutable_map.dart
+++ b/runtime/lib/immutable_map.dart
@@ -4,36 +4,36 @@
// Immutable map class for compiler generated map literals.
class ImmutableMap<K, V> implements Map<K, V> {
- final _ImmutableArray kvPairs_;
+ final _ImmutableArray _kvPairs;
const ImmutableMap._create(_ImmutableArray keyValuePairs)
- : kvPairs_ = keyValuePairs;
+ : _kvPairs = keyValuePairs;
V operator [](Object key) {
// TODO(hausner): Since the keys are sorted, we could do a binary
// search. But is it worth it?
- for (int i = 0; i < kvPairs_.length - 1; i += 2) {
- if (key == kvPairs_[i]) {
- return kvPairs_[i+1];
+ for (int i = 0; i < _kvPairs.length - 1; i += 2) {
+ if (key == _kvPairs[i]) {
+ return _kvPairs[i+1];
}
}
return null;
}
bool get isEmpty {
- return kvPairs_.length == 0;
+ return _kvPairs.length == 0;
}
bool get isNotEmpty => !isEmpty;
int get length {
- return kvPairs_.length ~/ 2;
+ return _kvPairs.length ~/ 2;
}
void forEach(void f(K key, V value)) {
- for (int i = 0; i < kvPairs_.length; i += 2) {
- f(kvPairs_[i], kvPairs_[i+1]);
+ for (int i = 0; i < _kvPairs.length; i += 2) {
+ f(_kvPairs[i], _kvPairs[i+1]);
}
}
@@ -46,8 +46,8 @@
}
bool containsKey(Object key) {
- for (int i = 0; i < kvPairs_.length; i += 2) {
- if (key == kvPairs_[i]) {
+ for (int i = 0; i < _kvPairs.length; i += 2) {
+ if (key == _kvPairs[i]) {
return true;
}
}
@@ -55,8 +55,8 @@
}
bool containsValue(Object value) {
- for (int i = 1; i < kvPairs_.length; i += 2) {
- if (value == kvPairs_[i]) {
+ for (int i = 1; i < _kvPairs.length; i += 2) {
+ if (value == _kvPairs[i]) {
return true;
}
}
@@ -113,7 +113,7 @@
int newIndex = _index + 1;
if (newIndex < _map.length) {
_index = newIndex;
- _current = _map.kvPairs_[newIndex * 2];
+ _current = _map._kvPairs[newIndex * 2];
return true;
}
_current = null;
@@ -135,7 +135,7 @@
int newIndex = _index + 1;
if (newIndex < _map.length) {
_index = newIndex;
- _current = _map.kvPairs_[newIndex * 2 + 1];
+ _current = _map._kvPairs[newIndex * 2 + 1];
return true;
}
_current = null;
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index 7c242ef..cec9518 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -222,7 +222,7 @@
throw new UnsupportedError(
"_Smi can only be allocated by the VM");
}
- int get hashCode {
+ int get _identityHashCode {
return this;
}
int operator ~() native "Smi_bitNegate";
@@ -233,38 +233,45 @@
String toString() {
if (this == 0) return "0";
- var reversed = new List();
- var val = this < 0 ? -this : this;
+ var reversed = _toStringBuffer;
+ var negative = false;
+ var val = this;
+ int index = 0;
+
+ if (this < 0) {
+ negative = true;
+ // Handle the first digit as negative to avoid negating the minimum
+ // smi, for which the negation is not a smi.
+ int digit = -(val.remainder(10));
+ reversed[index++] = digit + 0x30;
+ val = -(val ~/ 10);
+ }
+
while (val > 0) {
- reversed.add((val % 10) + 0x30);
+ int digit = val % 10;
+ reversed[index++] = (digit + 0x30);
val = val ~/ 10;
}
- final int numDigits = reversed.length;
- List digits;
- int i;
- if (this < 0) {
- digits = new List(numDigits + 1);
- digits[0] = 0x2D; // '-'.
- i = 1;
- } else {
- digits = new List(numDigits);
- i = 0;
+ if (negative) reversed[index++] = 0x2D; // '-'.
+
+ _OneByteString string = _OneByteString._allocate(index);
+ for (int i = 0, j = index; i < index; i++) {
+ string._setAt(i, reversed[--j]);
}
- int ri = reversed.length - 1;
- for (; i < digits.length; i++, ri--) {
- digits[i] = reversed[ri];
- }
- return _StringBase.createFromCharCodes(digits);
+ return string;
}
}
+// Reusable buffer used by smi.toString.
+List _toStringBuffer = new Uint8List(20);
+
// Represents integers that cannot be represented by Smi but fit into 64bits.
class _Mint extends _IntegerImplementation implements int {
factory _Mint._uninstantiable() {
throw new UnsupportedError(
"_Mint can only be allocated by the VM");
}
- int get hashCode {
+ int get _identityHashCode {
return this;
}
int operator ~() native "Mint_bitNegate";
@@ -288,7 +295,7 @@
throw new UnsupportedError(
"_Bigint can only be allocated by the VM");
}
- int get hashCode {
+ int get _identityHashCode {
return this;
}
int operator ~() native "Bigint_bitNegate";
diff --git a/runtime/lib/mirror_reference.dart b/runtime/lib/mirror_reference.dart
index b0f7726..89bc446 100644
--- a/runtime/lib/mirror_reference.dart
+++ b/runtime/lib/mirror_reference.dart
@@ -4,8 +4,7 @@
class _MirrorReference {
factory _MirrorReference._uninstantiable() {
- throw new UnsupportedError(
- "class _MirrorReference cannot be instantiated");
+ throw new UnsupportedError("class _MirrorReference cannot be instantiated");
}
bool operator ==(other) native "MirrorReference_equals";
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 9ae7d17..8e71843 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -10,6 +10,7 @@
#include "vm/object_store.h"
#include "vm/parser.h"
#include "vm/port.h"
+#include "vm/resolver.h"
#include "vm/symbols.h"
namespace dart {
@@ -53,7 +54,7 @@
// Conventions:
// * For throwing a NSM in a class klass we use its runtime type as receiver,
-// i.e., RawTypeOfClass(klass).
+// i.e., klass.RareType().
// * For throwing a NSM in a library, we just pass the null instance as
// receiver.
static void ThrowNoSuchMethod(const Instance& receiver,
@@ -398,6 +399,339 @@
}
+static RawInstance* ReturnResult(const Object& result) {
+ if (result.IsError()) {
+ ThrowInvokeError(Error::Cast(result));
+ UNREACHABLE();
+ }
+ if (result.IsInstance()) {
+ return Instance::Cast(result).raw();
+ }
+ ASSERT(result.IsNull());
+ return Instance::null();
+}
+
+
+// Invoke the function, or noSuchMethod if it is null. Propagate any unhandled
+// exceptions. Wrap and propagate any compilation errors.
+static RawInstance* InvokeDynamicFunction(
+ const Instance& receiver,
+ const Function& function,
+ const String& target_name,
+ const Array& args,
+ const Array& args_descriptor_array) {
+ // Note "args" is already the internal arguments with the receiver as the
+ // first element.
+ Object& result = Object::Handle();
+ ArgumentsDescriptor args_descriptor(args_descriptor_array);
+ if (function.IsNull() ||
+ !function.is_visible() ||
+ !function.AreValidArguments(args_descriptor, NULL)) {
+ result = DartEntry::InvokeNoSuchMethod(receiver,
+ target_name,
+ args,
+ args_descriptor_array);
+ } else {
+ result = DartEntry::InvokeFunction(function,
+ args,
+ args_descriptor_array);
+ }
+ return ReturnResult(result);
+}
+
+
+static RawInstance* InvokeLibraryGetter(const Library& library,
+ const String& getter_name,
+ const bool throw_nsm_if_absent) {
+ // To access a top-level we may need to use the Field or the getter Function.
+ // The getter function may either be in the library or in the field's owner
+ // class, depending on whether it was an actual getter, or an uninitialized
+ // field.
+ const Field& field = Field::Handle(
+ library.LookupFieldAllowPrivate(getter_name));
+ Function& getter = Function::Handle();
+ if (field.IsNull()) {
+ // No field found. Check for a getter in the lib.
+ const String& internal_getter_name =
+ String::Handle(Field::GetterName(getter_name));
+ getter = library.LookupFunctionAllowPrivate(internal_getter_name);
+ if (getter.IsNull()) {
+ getter = library.LookupFunctionAllowPrivate(getter_name);
+ if (!getter.IsNull()) {
+ // Looking for a getter but found a regular method: closurize it.
+ const Function& closure_function =
+ Function::Handle(getter.ImplicitClosureFunction());
+ return closure_function.ImplicitStaticClosure();
+ }
+ }
+ } else {
+ if (!field.IsUninitialized()) {
+ return field.value();
+ }
+ // An uninitialized field was found. Check for a getter in the field's
+ // owner classs.
+ const Class& klass = Class::Handle(field.owner());
+ const String& internal_getter_name =
+ String::Handle(Field::GetterName(getter_name));
+ getter = klass.LookupStaticFunctionAllowPrivate(internal_getter_name);
+ }
+
+ if (!getter.IsNull() && getter.is_visible()) {
+ // Invoke the getter and return the result.
+ const Object& result = Object::Handle(
+ DartEntry::InvokeFunction(getter, Object::empty_array()));
+ return ReturnResult(result);
+ }
+
+ if (throw_nsm_if_absent) {
+ ThrowNoSuchMethod(Instance::null_instance(),
+ getter_name,
+ getter,
+ InvocationMirror::kTopLevel,
+ InvocationMirror::kGetter);
+ UNREACHABLE();
+ }
+
+ // Fall through case: Indicate that we didn't find any function or field using
+ // a special null instance. This is different from a field being null. Callers
+ // make sure that this null does not leak into Dartland.
+ return Object::sentinel().raw();
+}
+
+
+static RawInstance* InvokeClassGetter(const Class& klass,
+ const String& getter_name,
+ const bool throw_nsm_if_absent) {
+ // Note static fields do not have implicit getters.
+ const Field& field = Field::Handle(klass.LookupStaticField(getter_name));
+ if (field.IsNull() || field.IsUninitialized()) {
+ const String& internal_getter_name = String::Handle(
+ Field::GetterName(getter_name));
+ Function& getter = Function::Handle(
+ klass.LookupStaticFunctionAllowPrivate(internal_getter_name));
+
+ if (getter.IsNull() || !getter.is_visible()) {
+ if (getter.IsNull()) {
+ getter = klass.LookupStaticFunctionAllowPrivate(getter_name);
+ if (!getter.IsNull()) {
+ // Looking for a getter but found a regular method: closurize it.
+ const Function& closure_function =
+ Function::Handle(getter.ImplicitClosureFunction());
+ return closure_function.ImplicitStaticClosure();
+ }
+ }
+ if (throw_nsm_if_absent) {
+ ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
+ getter_name,
+ getter,
+ InvocationMirror::kStatic,
+ InvocationMirror::kGetter);
+ UNREACHABLE();
+ }
+ // Fall through case: Indicate that we didn't find any function or field
+ // using a special null instance. This is different from a field being
+ // null. Callers make sure that this null does not leak into Dartland.
+ return Object::sentinel().raw();
+ }
+
+ // Invoke the getter and return the result.
+ const Object& result = Object::Handle(
+ DartEntry::InvokeFunction(getter, Object::empty_array()));
+ return ReturnResult(result);
+ }
+ return field.value();
+}
+
+
+
+
+static RawInstance* InvokeInstanceGetter(const Class& klass,
+ const Instance& reflectee,
+ const String& getter_name,
+ const bool throw_nsm_if_absent) {
+ const String& internal_getter_name = String::Handle(
+ Field::GetterName(getter_name));
+ Function& function = Function::Handle(
+ Resolver::ResolveDynamicAnyArgsAllowPrivate(klass, internal_getter_name));
+
+ if (!function.IsNull() || throw_nsm_if_absent) {
+ const int kNumArgs = 1;
+ const Array& args = Array::Handle(Array::New(kNumArgs));
+ args.SetAt(0, reflectee);
+ const Array& args_descriptor =
+ Array::Handle(ArgumentsDescriptor::New(args.Length()));
+
+ // InvokeDynamic invokes NoSuchMethod if the provided function is null.
+ return InvokeDynamicFunction(reflectee,
+ function,
+ internal_getter_name,
+ args,
+ args_descriptor);
+ }
+
+ // Fall through case: Indicate that we didn't find any function or field using
+ // a special null instance. This is different from a field being null. Callers
+ // make sure that this null does not leak into Dartland.
+ return Object::sentinel().raw();
+}
+
+
+static RawInstance* LookupFunctionOrFieldInLibraryPrefix(
+ const LibraryPrefix& prefix,
+ const String& lookup_name) {
+ const Object& entry = Object::Handle(prefix.LookupObject(lookup_name));
+ if (!entry.IsNull()) {
+ if (entry.IsField()) {
+ const Field& field = Field::Cast(entry);
+ const Class& field_owner = Class::Handle(field.owner());
+ const Library& field_library = Library::Handle(field_owner.library());
+ const Instance& result = Instance::Handle(
+ InvokeLibraryGetter(field_library, lookup_name, false));
+ if (result.raw() != Object::sentinel().raw()) {
+ return result.raw();
+ }
+ } else if (entry.IsFunction()) {
+ const Function& func = Function::Cast(entry);
+ const Function& closure_function = Function::Handle(
+ func.ImplicitClosureFunction());
+ return closure_function.ImplicitStaticClosure();
+ }
+ }
+
+ // Fall through case: Indicate that we didn't find any function or field using
+ // a special null instance. This is different from a field being null. Callers
+ // make sure that this null does not leak into Dartland.
+ return Object::sentinel().raw();
+}
+
+
+static RawInstance* LookupStaticFunctionOrFieldInClass(
+ const Class& klass,
+ const String& lookup_name) {
+ Instance& result = Instance::Handle(
+ InvokeClassGetter(klass, lookup_name, false));
+ if (result.raw() != Object::sentinel().raw()) {
+ return result.raw();
+ }
+
+ Function& func = Function::Handle();
+ Class& lookup_class = Class::Handle(klass.raw());
+ while (func.IsNull() && !lookup_class.IsNull()) {
+ func ^= lookup_class.LookupStaticFunctionAllowPrivate(lookup_name);
+ lookup_class = lookup_class.SuperClass();
+ }
+ if (!func.IsNull()) {
+ const Function& closure_function = Function::Handle(
+ func.ImplicitClosureFunction());
+ ASSERT(!closure_function.IsNull());
+ return closure_function.ImplicitStaticClosure();
+ }
+
+ // Fall through case: Indicate that we didn't find any function or field using
+ // a special null instance. This is different from a field being null. Callers
+ // make sure that this null does not leak into Dartland.
+ return Object::sentinel().raw();
+}
+
+
+static RawInstance* LookupFunctionOrFieldInFunctionContext(
+ const Function& func,
+ const Context& ctx,
+ const String& lookup_name) {
+ const ContextScope& ctx_scope = ContextScope::Handle(func.context_scope());
+ intptr_t this_index = -1;
+
+ // Search local context.
+ String& name = String::Handle();
+ for (intptr_t i = 0; i < ctx_scope.num_variables(); i++) {
+ name ^= ctx_scope.NameAt(i);
+ if (name.Equals(lookup_name)) {
+ return ctx.At(i);
+ } else if (name.Equals(Symbols::This())) {
+ // Record instance index to search for the field in the instance
+ // afterwards.
+ this_index = i;
+ }
+ }
+
+ // Search the instance this function is attached to.
+ if (this_index >= 0) {
+ // Since we want the closurized version of a function, we can access, both,
+ // functions and fields through their implicit getter name. If the implicit
+ // getter does not exist for the function, a method extractor will be
+ // created.
+ const Class& owner = Class::Handle(func.Owner());
+ const Instance& receiver = Instance::Handle(ctx.At(this_index));
+ return InvokeInstanceGetter(owner, receiver, lookup_name, false);
+ }
+
+ // Fall through case: Indicate that we didn't find any function or field using
+ // a special null instance. This is different from a field being null. Callers
+ // make sure that this null does not leak into Dartland.
+ return Object::sentinel().raw();
+}
+
+
+static RawInstance* LookupFunctionOrFieldInLibraryHelper(
+ const Library& library,
+ const String& class_name,
+ const String& lookup_name) {
+ if (class_name.IsNull()) {
+ const Instance& result = Instance::Handle(
+ InvokeLibraryGetter(library, lookup_name, false));
+ if (result.raw() != Object::sentinel().raw()) {
+ return result.raw();
+ }
+ const Function& func = Function::Handle(
+ library.LookupFunctionAllowPrivate(lookup_name));
+ if (!func.IsNull()) {
+ const Function& closure_function = Function::Handle(
+ func.ImplicitClosureFunction());
+ return closure_function.ImplicitStaticClosure();
+ }
+ } else {
+ const Class& cls = Class::Handle(
+ library.LookupClassAllowPrivate(class_name));
+ if (!cls.IsNull()) {
+ return LookupStaticFunctionOrFieldInClass(cls, lookup_name);
+ }
+ }
+
+ // Fall through case: Indicate that we didn't find any function or field using
+ // a special null instance. This is different from a field being null. Callers
+ // make sure that this null does not leak into Dartland.
+ return Object::sentinel().raw();
+}
+
+
+static RawInstance* LookupFunctionOrFieldInLibrary(const Library& library,
+ const String& class_name,
+ const String& lookup_name) {
+ Instance& result = Instance::Handle();
+ // Check current library.
+ result ^= LookupFunctionOrFieldInLibraryHelper(
+ library, class_name, lookup_name);
+ if (result.raw() != Object::sentinel().raw()) {
+ return result.raw();
+ }
+ // Check all imports.
+ Library& lib_it = Library::Handle();
+ for (intptr_t i = 0; i < library.num_imports(); i++) {
+ lib_it ^= library.ImportLibraryAt(i);
+ result ^= LookupFunctionOrFieldInLibraryHelper(
+ lib_it, class_name, lookup_name);
+ if (result.raw() != Object::sentinel().raw()) {
+ return result.raw();
+ }
+ }
+
+ // Fall through case: Indicate that we didn't find any function or field using
+ // a special null instance. This is different from a field being null. Callers
+ // make sure that this null does not leak into Dartland.
+ return Object::sentinel().raw();
+}
+
+
DEFINE_NATIVE_ENTRY(Mirrors_makeLocalMirrorSystem, 0) {
return CreateMirrorSystem();
}
@@ -505,18 +839,6 @@
}
-static bool FieldIsUninitialized(const Field& field) {
- ASSERT(!field.IsNull());
-
- // Return getter method for uninitialized fields, rather than the
- // field object, since the value in the field object will not be
- // initialized until the first time the getter is invoked.
- const Instance& value = Instance::Handle(field.value());
- ASSERT(value.raw() != Object::transition_sentinel().raw());
- return value.raw() == Object::sentinel().raw();
-}
-
-
DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
const Class& klass = Class::Handle(ref.GetClassReferent());
@@ -756,39 +1078,6 @@
}
-// Invoke the function, or noSuchMethod if it is null. Propagate any unhandled
-// exceptions. Wrap and propagate any compilation errors.
-static RawObject* ReflectivelyInvokeDynamicFunction(
- const Instance& receiver,
- const Function& function,
- const String& target_name,
- const Array& args,
- const Array& args_descriptor_array) {
- // Note "args" is already the internal arguments with the receiver as the
- // first element.
- Object& result = Object::Handle();
-
- ArgumentsDescriptor args_descriptor(args_descriptor_array);
- if (function.IsNull() ||
- !function.is_visible() ||
- !function.AreValidArguments(args_descriptor, NULL)) {
- result = DartEntry::InvokeNoSuchMethod(receiver,
- target_name,
- args,
- args_descriptor_array);
- } else {
- result = DartEntry::InvokeFunction(function,
- args,
- args_descriptor_array);
- }
-
- if (result.IsError()) {
- ThrowInvokeError(Error::Cast(result));
- UNREACHABLE();
- }
- return result.raw();
-}
-
DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) {
// Argument 0 is the mirror, which is unused by the native. It exists
// because this native is an instance method in order to be polymorphic
@@ -799,24 +1088,18 @@
GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3));
GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
+ Class& klass = Class::Handle(reflectee.clazz());
+ Function& function = Function::Handle(
+ Resolver::ResolveDynamicAnyArgsAllowPrivate(klass, function_name));
+
const Array& args_descriptor =
Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names));
- Class& klass = Class::Handle(reflectee.clazz());
- Function& function = Function::Handle();
- while (!klass.IsNull()) {
- function = klass.LookupDynamicFunctionAllowPrivate(function_name);
- if (!function.IsNull()) {
- break;
- }
- klass = klass.SuperClass();
- }
-
- return ReflectivelyInvokeDynamicFunction(reflectee,
- function,
- function_name,
- args,
- args_descriptor);
+ return InvokeDynamicFunction(reflectee,
+ function,
+ function_name,
+ args,
+ args_descriptor);
}
@@ -826,34 +1109,8 @@
// with its cousins.
GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2));
-
- // Every instance field has a getter Function. Try to find the
- // getter in any superclass and use that function to access the
- // field.
- // NB: We do not use Resolver::ResolveDynamic because we want to find private
- // members.
Class& klass = Class::Handle(reflectee.clazz());
- String& internal_getter_name = String::Handle(Field::GetterName(getter_name));
- Function& getter = Function::Handle();
- while (!klass.IsNull()) {
- getter = klass.LookupDynamicFunctionAllowPrivate(internal_getter_name);
- if (!getter.IsNull()) {
- break;
- }
- klass = klass.SuperClass();
- }
-
- const int kNumArgs = 1;
- const Array& args = Array::Handle(Array::New(kNumArgs));
- args.SetAt(0, reflectee);
- const Array& args_descriptor =
- Array::Handle(ArgumentsDescriptor::New(args.Length()));
-
- return ReflectivelyInvokeDynamicFunction(reflectee,
- getter,
- internal_getter_name,
- args,
- args_descriptor);
+ return InvokeInstanceGetter(klass, reflectee, getter_name, true);
}
@@ -897,11 +1154,11 @@
const Array& args_descriptor =
Array::Handle(ArgumentsDescriptor::New(args.Length()));
- return ReflectivelyInvokeDynamicFunction(reflectee,
- setter,
- internal_setter_name,
- args,
- args_descriptor);
+ return InvokeDynamicFunction(reflectee,
+ setter,
+ internal_setter_name,
+ args,
+ args_descriptor);
}
@@ -924,6 +1181,80 @@
}
+DEFINE_NATIVE_ENTRY(ClosureMirror_find_in_context, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Array, lookup_parts, arguments->NativeArgAt(1));
+ ASSERT(lookup_parts.Length() >= 1 && lookup_parts.Length() <= 3);
+
+ Function& function = Function::Handle();
+ const bool callable = closure.IsCallable(&function, NULL);
+ ASSERT(callable);
+
+ const int parts_len = lookup_parts.Length();
+ // Lookup name is always the last part.
+ const String& lookup_name = String::Handle(String::RawCast(
+ lookup_parts.At(parts_len - 1)));
+
+ String& part_name = String::Handle();
+ Class& owner = Class::Handle(function.Owner());
+ LibraryPrefix& prefix = LibraryPrefix::Handle();
+ Library& this_library = Library::Handle(owner.library());
+ Instance& result = Instance::Handle(Object::sentinel().raw());
+ if (parts_len == 1) {
+ // Could be either a field in context, an instance or static field of the
+ // enclosing class, or a field in the current library or any imported
+ // library.
+ result ^= LookupFunctionOrFieldInFunctionContext(
+ function, Context::Handle(Closure::context(closure)), lookup_name);
+ if (result.raw() == Object::sentinel().raw()) {
+ result ^= LookupStaticFunctionOrFieldInClass(owner, lookup_name);
+ }
+ if (result.raw() == Object::sentinel().raw()) {
+ result ^= LookupFunctionOrFieldInLibrary(this_library,
+ part_name,
+ lookup_name);
+ }
+ } else if (parts_len == 2) {
+ // Could be either library.field or class.staticfield.
+ part_name ^= lookup_parts.At(0);
+ prefix ^= this_library.LookupLocalLibraryPrefix(part_name);
+ if (prefix.IsNull()) {
+ result ^= LookupFunctionOrFieldInLibrary(this_library,
+ part_name,
+ lookup_name);
+ } else {
+ result ^= LookupFunctionOrFieldInLibraryPrefix(prefix, lookup_name);
+ }
+ } else {
+ ASSERT(parts_len == 3);
+ // Can only be library.class.staticfield.
+ part_name ^= lookup_parts.At(0);
+ prefix ^= this_library.LookupLocalLibraryPrefix(part_name);
+ if (!prefix.IsNull()) {
+ part_name ^= lookup_parts.At(1);
+ owner ^= prefix.LookupClass(part_name);
+ if (!owner.IsNull()) {
+ result ^= LookupStaticFunctionOrFieldInClass(owner, lookup_name);
+ }
+ }
+ }
+
+ // We return a tuple (list) where the first slot is a boolean indicates
+ // whether we found a field or function and the second slot contains the
+ // result. This is needed to distinguish between not finding a field and a
+ // field containing null as value.
+ const Array& result_tuple = Array::Handle(Array::New(2));
+ if (result.raw() == Object::sentinel().raw()) {
+ result_tuple.SetAt(0, Bool::False());
+ // No need to set the value.
+ } else {
+ result_tuple.SetAt(0, Bool::True());
+ result_tuple.SetAt(1, result);
+ }
+ return result_tuple.raw();
+}
+
+
DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
ASSERT(!closure.IsNull());
@@ -983,34 +1314,7 @@
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
const Class& klass = Class::Handle(ref.GetClassReferent());
GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2));
-
- // Note static fields do not have implicit getters.
- const Field& field = Field::Handle(klass.LookupStaticField(getter_name));
- if (field.IsNull() || FieldIsUninitialized(field)) {
- const String& internal_getter_name = String::Handle(
- Field::GetterName(getter_name));
- const Function& getter = Function::Handle(
- klass.LookupStaticFunctionAllowPrivate(internal_getter_name));
-
- if (getter.IsNull() || !getter.is_visible()) {
- ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
- getter_name,
- getter,
- InvocationMirror::kStatic,
- InvocationMirror::kGetter);
- UNREACHABLE();
- }
-
- // Invoke the getter and return the result.
- Object& result = Object::Handle(
- DartEntry::InvokeFunction(getter, Object::empty_array()));
- if (result.IsError()) {
- ThrowInvokeError(Error::Cast(result));
- UNREACHABLE();
- }
- return result.raw();
- }
- return field.value();
+ return InvokeClassGetter(klass, getter_name, true);
}
@@ -1237,46 +1541,7 @@
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
const Library& library = Library::Handle(ref.GetLibraryReferent());
GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2));
-
- // To access a top-level we may need to use the Field or the
- // getter Function. The getter function may either be in the
- // library or in the field's owner class, depending.
- const Field& field = Field::Handle(
- library.LookupFieldAllowPrivate(getter_name));
- Function& getter = Function::Handle();
- if (field.IsNull()) {
- // No field found and no ambiguity error. Check for a getter in the lib.
- const String& internal_getter_name =
- String::Handle(Field::GetterName(getter_name));
- getter = library.LookupFunctionAllowPrivate(internal_getter_name);
- } else if (!field.IsNull() && FieldIsUninitialized(field)) {
- // A field was found. Check for a getter in the field's owner classs.
- const Class& klass = Class::Handle(field.owner());
- const String& internal_getter_name =
- String::Handle(Field::GetterName(getter_name));
- getter = klass.LookupStaticFunctionAllowPrivate(internal_getter_name);
- }
-
- if (!getter.IsNull() && getter.is_visible()) {
- // Invoke the getter and return the result.
- const Object& result = Object::Handle(
- DartEntry::InvokeFunction(getter, Object::empty_array()));
- if (result.IsError()) {
- ThrowInvokeError(Error::Cast(result));
- UNREACHABLE();
- }
- return result.raw();
- }
- if (!field.IsNull()) {
- return field.value();
- }
- ThrowNoSuchMethod(Instance::null_instance(),
- getter_name,
- getter,
- InvocationMirror::kTopLevel,
- InvocationMirror::kGetter);
- UNREACHABLE();
- return Instance::null();
+ return InvokeLibraryGetter(library, getter_name, true);
}
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 0708da3..e20aa88 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -321,7 +321,6 @@
InstanceMirror invoke(Symbol memberName,
List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
-
int numPositionalArguments = positionalArguments.length + 1; // Receiver.
int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
int numArguments = numPositionalArguments + numNamedArguments;
@@ -375,7 +374,6 @@
// replaced with
// return this.invoke(#call, positionalArguments, namedArguments);
// and the native ClosureMirror_apply can be removed.
-
int numPositionalArguments = positionalArguments.length + 1; // Receiver.
int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
int numArguments = numPositionalArguments + numNamedArguments;
@@ -405,9 +403,16 @@
});
}
- Future<InstanceMirror> findInContext(Symbol name) {
- throw new UnimplementedError(
- 'ClosureMirror.findInContext() is not implemented');
+ InstanceMirror findInContext(Symbol name, {ifAbsent: null}) {
+ List<String> parts = _n(name).split(".").toList(growable: false);
+ if (parts.length > 3) {
+ throw new ArgumentError("Invalid symbol: ${name}");
+ }
+ List tuple = _computeFindInContext(_reflectee, parts);
+ if (tuple[0]) {
+ return reflect(tuple[1]);
+ }
+ return ifAbsent == null ? null : ifAbsent();
}
String toString() => "ClosureMirror on '${Error.safeToString(_reflectee)}'";
@@ -417,6 +422,9 @@
static _computeFunction(reflectee)
native 'ClosureMirror_function';
+
+ static _computeFindInContext(reflectee, name)
+ native 'ClosureMirror_find_in_context';
}
class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
diff --git a/runtime/lib/null_patch.dart b/runtime/lib/null_patch.dart
index cfc1f33..fb117d1 100644
--- a/runtime/lib/null_patch.dart
+++ b/runtime/lib/null_patch.dart
@@ -11,7 +11,7 @@
"class Null cannot be instantiated");
}
- int get hashCode {
+ int get _identityHashCode {
return 2011; // The year Dart was announced and a prime.
}
diff --git a/runtime/lib/object_patch.dart b/runtime/lib/object_patch.dart
index 2d42da7..6bba2c7 100644
--- a/runtime/lib/object_patch.dart
+++ b/runtime/lib/object_patch.dart
@@ -12,7 +12,9 @@
static _getHash(obj) native "Object_getHash";
static _setHash(obj, hash) native "Object_setHash";
- /* patch */ int get hashCode {
+ /* patch */ int get hashCode => _identityHashCode;
+
+ int get _identityHashCode {
var result = _getHash(this);
if (result == 0) {
// We want the hash to be a Smi value greater than 0.
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index d128e83..8f3cc3e 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -42,6 +42,12 @@
}
+DEFINE_NATIVE_ENTRY(Float32x4_fromUint32x4Bits, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, v, arguments->NativeArgAt(1));
+ return Float32x4::New(v.value());
+}
+
+
DEFINE_NATIVE_ENTRY(Float32x4_add, 2) {
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
@@ -189,14 +195,16 @@
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, lo, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, hi, arguments->NativeArgAt(2));
- float _x = self.x() > lo.x() ? self.x() : lo.x();
- float _y = self.y() > lo.y() ? self.y() : lo.y();
- float _z = self.z() > lo.z() ? self.z() : lo.z();
- float _w = self.w() > lo.w() ? self.w() : lo.w();
- _x = _x > hi.x() ? hi.x() : _x;
- _y = _y > hi.y() ? hi.y() : _y;
- _z = _z > hi.z() ? hi.z() : _z;
- _w = _w > hi.w() ? hi.w() : _w;
+ // The order of the clamping must match the order of the optimized code:
+ // MAX(MIN(self, hi), lo).
+ float _x = self.x() < hi.x() ? self.x() : hi.x();
+ float _y = self.y() < hi.y() ? self.y() : hi.y();
+ float _z = self.z() < hi.z() ? self.z() : hi.z();
+ float _w = self.w() < hi.w() ? self.w() : hi.w();
+ _x = _x < lo.x() ? lo.x() : _x;
+ _y = _y < lo.y() ? lo.y() : _y;
+ _z = _z < lo.z() ? lo.z() : _z;
+ _w = _w < lo.w() ? lo.w() : _w;
return Float32x4::New(_x, _y, _z, _w);
}
@@ -425,12 +433,6 @@
}
-DEFINE_NATIVE_ENTRY(Float32x4_toUint32x4, 1) {
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, v, arguments->NativeArgAt(0));
- return Uint32x4::New(v.value());
-}
-
-
DEFINE_NATIVE_ENTRY(Uint32x4_fromInts, 5) {
ASSERT(AbstractTypeArguments::CheckedHandle(
arguments->NativeArgAt(0)).IsNull());
@@ -461,6 +463,12 @@
}
+DEFINE_NATIVE_ENTRY(Uint32x4_fromFloat32x4Bits, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, v, arguments->NativeArgAt(1));
+ return Uint32x4::New(v.value());
+}
+
+
DEFINE_NATIVE_ENTRY(Uint32x4_or, 2) {
GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, other, arguments->NativeArgAt(1));
@@ -704,10 +712,4 @@
}
-DEFINE_NATIVE_ENTRY(Uint32x4_toFloat32x4, 1) {
- GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, v, arguments->NativeArgAt(0));
- return Float32x4::New(v.value());
-}
-
-
} // namespace dart
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 4cc4c1e..0127c15 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -181,6 +181,7 @@
return Symbols::FromCharCode(value);
}
+
DEFINE_NATIVE_ENTRY(String_codeUnitAt, 2) {
const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1));
diff --git a/runtime/lib/string_buffer_patch.dart b/runtime/lib/string_buffer_patch.dart
index 2d1acb5..9a22647 100644
--- a/runtime/lib/string_buffer_patch.dart
+++ b/runtime/lib/string_buffer_patch.dart
@@ -3,28 +3,58 @@
// BSD-style license that can be found in the LICENSE file.
patch class StringBuffer {
- /** Backing store for collected UTF-16 code units. */
- Uint16List _buffer;
- /** Number of code units collected. */
- int _length = 0;
+ static const int _BUFFER_SIZE = 64;
+ static const int _PARTS_TO_COMPACT = 128;
+ static const int _PARTS_TO_COMPACT_SIZE_LIMIT = _PARTS_TO_COMPACT * 8;
+
/**
- * Collects the approximate maximal magnitude of the added code units.
+ * When strings are written to the string buffer, we add them to a
+ * list of string parts.
+ */
+ List _parts = null;
+
+ /**
+ * Total number of code units in the string parts. Does not include
+ * the code units added to the buffer.
+ */
+ int _partsCodeUnits = 0;
+
+ /**
+ * To preserve memory, we sometimes compact the parts. This combines
+ * several smaller parts into a single larger part to cut down on the
+ * cost that comes from the per-object memory overhead. We keep track
+ * of the last index where we ended our compaction and the number of
+ * code units added since the last compaction.
+ */
+ int _partsCompactionIndex = 0;
+ int _partsCodeUnitsSinceCompaction = 0;
+ _ObjectArray _partsCompactionArray = null;
+
+ /**
+ * The buffer is used to build up a string from code units. It is
+ * used when writing short strings or individul char codes to the
+ * buffer. The buffer is allocated on demand.
+ */
+ Uint16List _buffer = null;
+ int _bufferPosition = 0;
+
+ /**
+ * Collects the approximate maximal magnitude of the code units added
+ * to the buffer.
*
* The value of each added code unit is or'ed with this variable, so the
* most significant bit set in any code unit is also set in this value.
- * If below 256, the string is a Latin-1 string.
+ * If below 256, the string in the buffer is a Latin-1 string.
*/
- int _codeUnitMagnitude = 0;
+ int _bufferCodeUnitMagnitude = 0;
/// Creates the string buffer with an initial content.
- /* patch */ StringBuffer([Object content = ""])
- : _buffer = new Uint16List(16) {
+ /* patch */ StringBuffer([Object content = ""]) {
write(content);
}
- /* patch */ int get length => _length;
+ /* patch */ int get length => _partsCodeUnits + _bufferPosition;
- /// Adds [obj] to the buffer.
/* patch */ void write(Object obj) {
String str;
if (obj is String) {
@@ -38,13 +68,8 @@
}
}
if (str.isEmpty) return;
- _ensureCapacity(str.length);
- for (int i = 0; i < str.length; i++) {
- int unit = str.codeUnitAt(i);
- _buffer[_length + i] = unit;
- _codeUnitMagnitude |= unit;
- }
- _length += str.length;
+ _consumeBuffer();
+ _addPart(str);
}
/* patch */ void writeCharCode(int charCode) {
@@ -53,50 +78,103 @@
throw new RangeError.range(charCode, 0, 0x10FFFF);
}
_ensureCapacity(1);
- _buffer[_length++] = charCode;
- _codeUnitMagnitude |= charCode;
+ _buffer[_bufferPosition++] = charCode;
+ _bufferCodeUnitMagnitude |= charCode;
} else {
if (charCode > 0x10FFFF) {
throw new RangeError.range(charCode, 0, 0x10FFFF);
}
_ensureCapacity(2);
int bits = charCode - 0x10000;
- _buffer[_length++] = 0xD800 | (bits >> 10);
- _buffer[_length++] = 0xDC00 | (bits & 0x3FF);
- _codeUnitMagnitude |= 0xFFFF;
+ _buffer[_bufferPosition++] = 0xD800 | (bits >> 10);
+ _buffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF);
+ _bufferCodeUnitMagnitude |= 0xFFFF;
}
}
/** Makes the buffer empty. */
/* patch */ void clear() {
- _length = 0;
- _codeUnitMagnitude = 0;
+ _parts = null;
+ _partsCodeUnits = _bufferPosition = _bufferCodeUnitMagnitude = 0;
}
/** Returns the contents of buffer as a string. */
/* patch */ String toString() {
- if (_length == 0) return "";
- bool isLatin1 = _codeUnitMagnitude <= 0xFF;
- return _create(_buffer, _length, isLatin1);
+ _consumeBuffer();
+ if (_partsCodeUnits == 0) return "";
+
+ // TODO(kasperl): It would be nice if concatAllNative would
+ // allow me to pass in a grownable array directly, but for
+ // now we have to copy the contents to a non-growable array.
+ int length = _parts.length;
+ _ObjectArray array = new _ObjectArray(length);
+ for (int i = 0; i < length; i++) array[i] = _parts[i];
+ return _StringBase._concatAllNative(array);
}
/** Ensures that the buffer has enough capacity to add n code units. */
void _ensureCapacity(int n) {
- int requiredCapacity = _length + n;
- if (requiredCapacity > _buffer.length) {
- _grow(requiredCapacity);
+ if (_buffer == null) {
+ _buffer = new Uint16List(_BUFFER_SIZE);
+ } else if (_bufferPosition + n > _buffer.length) {
+ _consumeBuffer();
}
}
- /** Grows the buffer until it can contain [requiredCapacity] entries. */
- void _grow(int requiredCapacity) {
- int newCapacity = _buffer.length;
- do {
- newCapacity *= 2;
- } while (newCapacity < requiredCapacity);
- List<int> newBuffer = new Uint16List(newCapacity);
- newBuffer.setRange(0, _length, _buffer);
- _buffer = newBuffer;
+ /**
+ * Consumes the content of the buffer by turning it into a string
+ * and adding it as a part. After calling this the buffer position
+ * will be reset to zero.
+ */
+ void _consumeBuffer() {
+ if (_bufferPosition == 0) return;
+ bool isLatin1 = _bufferCodeUnitMagnitude <= 0xFF;
+ String str = _create(_buffer, _bufferPosition, isLatin1);
+ _bufferPosition = _bufferCodeUnitMagnitude = 0;
+ _addPart(str);
+ }
+
+ /**
+ * Adds a new part to this string buffer and keeps track of how
+ * many code units are contained in the parts.
+ */
+ void _addPart(String str) {
+ int length = str.length;
+ _partsCodeUnits += length;
+ _partsCodeUnitsSinceCompaction += length;
+
+ if (_parts == null) {
+ _parts = [ str ];
+ } else {
+ _parts.add(str);
+ int partsSinceCompaction = _parts.length - _partsCompactionIndex;
+ if (partsSinceCompaction == _PARTS_TO_COMPACT) {
+ _compact();
+ }
+ }
+ }
+
+ /**
+ * Compacts the last N parts if their average size allows us to save a
+ * lot of memory by turning them all into a single part.
+ */
+ void _compact() {
+ if (_partsCodeUnitsSinceCompaction < _PARTS_TO_COMPACT_SIZE_LIMIT) {
+ if (_partsCompactionArray == null) {
+ _partsCompactionArray = new _ObjectArray(_PARTS_TO_COMPACT);
+ }
+ for (int i = 0; i < _PARTS_TO_COMPACT; i++) {
+ _partsCompactionArray[i] = _parts[i + _partsCompactionIndex];
+ }
+ String compacted = _StringBase._concatAllNative(_partsCompactionArray);
+ _parts.length = _parts.length - _PARTS_TO_COMPACT;
+ _parts.add(compacted);
+ for (int i = 0; i < _PARTS_TO_COMPACT; i++) {
+ _partsCompactionArray[i] = null;
+ }
+ }
+ _partsCodeUnitsSinceCompaction = 0;
+ _partsCompactionIndex = _parts.length;
}
/**
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index bd7a266..6690085 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -15,23 +15,15 @@
// TypedData.
-// Checks to see if offset_in_bytes is in the range.
-static bool RangeCheck(intptr_t offset_in_bytes, intptr_t length_in_bytes) {
- return ((offset_in_bytes >= 0) &&
- (length_in_bytes > 0) &&
- (offset_in_bytes < length_in_bytes));
-}
-
-
// Checks to see if offsetInBytes + num_bytes is in the range.
-static void SetRangeCheck(intptr_t offset_in_bytes,
- intptr_t num_bytes,
- intptr_t length_in_bytes,
- intptr_t element_size_in_bytes) {
- if (!Utils::RangeCheck(offset_in_bytes, num_bytes, length_in_bytes)) {
+static void RangeCheck(intptr_t offset_in_bytes,
+ intptr_t access_size,
+ intptr_t length_in_bytes,
+ intptr_t element_size_in_bytes) {
+ if (!Utils::RangeCheck(offset_in_bytes, access_size, length_in_bytes)) {
const String& error = String::Handle(String::NewFormatted(
"index (%" Pd ") must be in the range [0..%" Pd ")",
- (offset_in_bytes / element_size_in_bytes),
+ (offset_in_bytes + access_size) / element_size_in_bytes,
(length_in_bytes / element_size_in_bytes)));
const Array& args = Array::Handle(Array::New(1));
args.SetAt(0, error);
@@ -90,14 +82,14 @@
if (dst_array.ElementType() != src_array.ElementType()) {
return Bool::False().raw();
}
- SetRangeCheck(src_offset_in_bytes,
- length_in_bytes,
- src_array.LengthInBytes(),
- element_size_in_bytes);
- SetRangeCheck(dst_offset_in_bytes,
- length_in_bytes,
- dst_array.LengthInBytes(),
- element_size_in_bytes);
+ RangeCheck(src_offset_in_bytes,
+ length_in_bytes,
+ src_array.LengthInBytes(),
+ element_size_in_bytes);
+ RangeCheck(dst_offset_in_bytes,
+ length_in_bytes,
+ dst_array.LengthInBytes(),
+ element_size_in_bytes);
TypedData::Copy<DstType, SrcType>(dst_array, dst_offset_in_bytes,
src_array, src_offset_in_bytes,
length_in_bytes);
@@ -183,18 +175,20 @@
CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE)
-#define TYPED_DATA_GETTER(getter, object) \
+#define TYPED_DATA_GETTER(getter, object, access_size) \
DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) { \
GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
if (instance.IsTypedData()) { \
const TypedData& array = TypedData::Cast(instance); \
- ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes())); \
+ RangeCheck(offsetInBytes.Value(), access_size, \
+ array.LengthInBytes(), access_size); \
return object::New(array.getter(offsetInBytes.Value())); \
} \
if (instance.IsExternalTypedData()) { \
const ExternalTypedData& array = ExternalTypedData::Cast(instance); \
- ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes())); \
+ RangeCheck(offsetInBytes.Value(), access_size, \
+ array.LengthInBytes(), access_size); \
return object::New(array.getter(offsetInBytes.Value())); \
} \
const String& error = String::Handle(String::NewFormatted( \
@@ -206,18 +200,20 @@
} \
-#define TYPED_DATA_SETTER(setter, object, get_object_value) \
+#define TYPED_DATA_SETTER(setter, object, get_object_value, access_size) \
DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \
GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
GET_NON_NULL_NATIVE_ARGUMENT(object, value, arguments->NativeArgAt(2)); \
if (instance.IsTypedData()) { \
const TypedData& array = TypedData::Cast(instance); \
- ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes())); \
+ RangeCheck(offsetInBytes.Value(), access_size, \
+ array.LengthInBytes(), access_size); \
array.setter(offsetInBytes.Value(), value.get_object_value()); \
} else if (instance.IsExternalTypedData()) { \
const ExternalTypedData& array = ExternalTypedData::Cast(instance); \
- ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes())); \
+ RangeCheck(offsetInBytes.Value(), access_size, \
+ array.LengthInBytes(), access_size); \
array.setter(offsetInBytes.Value(), value.get_object_value()); \
} else { \
const String& error = String::Handle(String::NewFormatted( \
@@ -237,11 +233,11 @@
uint64_t value = 0; \
if (instance.IsTypedData()) { \
const TypedData& array = TypedData::Cast(instance); \
- ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes())); \
+ RangeCheck(offsetInBytes.Value(), 8, array.LengthInBytes(), 8); \
value = array.getter(offsetInBytes.Value()); \
} else if (instance.IsExternalTypedData()) { \
const ExternalTypedData& array = ExternalTypedData::Cast(instance); \
- ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes())); \
+ RangeCheck(offsetInBytes.Value(), 8, array.LengthInBytes(), 8); \
value = array.getter(offsetInBytes.Value()); \
} else { \
const String& error = String::Handle(String::NewFormatted( \
@@ -272,11 +268,11 @@
} \
if (instance.IsTypedData()) { \
const TypedData& array = TypedData::Cast(instance); \
- ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes())); \
+ RangeCheck(offsetInBytes.Value(), 8, array.LengthInBytes(), 8); \
array.setter(offsetInBytes.Value(), object_value); \
} else if (instance.IsExternalTypedData()) { \
const ExternalTypedData& array = ExternalTypedData::Cast(instance); \
- ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes())); \
+ RangeCheck(offsetInBytes.Value(), 8, array.LengthInBytes(), 8); \
array.setter(offsetInBytes.Value(), object_value); \
} else { \
const String& error = String::Handle(String::NewFormatted( \
@@ -289,9 +285,13 @@
}
-#define TYPED_DATA_NATIVES(getter, setter, object, get_object_value) \
- TYPED_DATA_GETTER(getter, object) \
- TYPED_DATA_SETTER(setter, object, get_object_value) \
+#define TYPED_DATA_NATIVES(getter, \
+ setter, \
+ object, \
+ get_object_value, \
+ access_size) \
+ TYPED_DATA_GETTER(getter, object, access_size) \
+ TYPED_DATA_SETTER(setter, object, get_object_value, access_size) \
#define TYPED_DATA_UINT64_NATIVES(getter, setter, object) \
@@ -299,17 +299,17 @@
TYPED_DATA_UINT64_SETTER(setter, object) \
-TYPED_DATA_NATIVES(GetInt8, SetInt8, Smi, Value)
-TYPED_DATA_NATIVES(GetUint8, SetUint8, Smi, Value)
-TYPED_DATA_NATIVES(GetInt16, SetInt16, Smi, Value)
-TYPED_DATA_NATIVES(GetUint16, SetUint16, Smi, Value)
-TYPED_DATA_NATIVES(GetInt32, SetInt32, Integer, AsInt64Value)
-TYPED_DATA_NATIVES(GetUint32, SetUint32, Integer, AsInt64Value)
-TYPED_DATA_NATIVES(GetInt64, SetInt64, Integer, AsInt64Value)
+TYPED_DATA_NATIVES(GetInt8, SetInt8, Smi, Value, 1)
+TYPED_DATA_NATIVES(GetUint8, SetUint8, Smi, Value, 1)
+TYPED_DATA_NATIVES(GetInt16, SetInt16, Smi, Value, 2)
+TYPED_DATA_NATIVES(GetUint16, SetUint16, Smi, Value, 2)
+TYPED_DATA_NATIVES(GetInt32, SetInt32, Integer, AsInt64Value, 4)
+TYPED_DATA_NATIVES(GetUint32, SetUint32, Integer, AsInt64Value, 4)
+TYPED_DATA_NATIVES(GetInt64, SetInt64, Integer, AsInt64Value, 8)
TYPED_DATA_UINT64_NATIVES(GetUint64, SetUint64, Integer)
-TYPED_DATA_NATIVES(GetFloat32, SetFloat32, Double, value)
-TYPED_DATA_NATIVES(GetFloat64, SetFloat64, Double, value)
-TYPED_DATA_NATIVES(GetFloat32x4, SetFloat32x4, Float32x4, value)
+TYPED_DATA_NATIVES(GetFloat32, SetFloat32, Double, value, 4)
+TYPED_DATA_NATIVES(GetFloat64, SetFloat64, Double, value, 8)
+TYPED_DATA_NATIVES(GetFloat32x4, SetFloat32x4, Float32x4, value, 16)
DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt16, 2) {
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index 1007c49..0f10690 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -254,6 +254,9 @@
/* patch */ factory Float32x4.zero() {
return new _Float32x4.zero();
}
+ /* patch */ factory Float32x4.fromUint32x4Bits(Uint32x4 x) {
+ return new _Float32x4.fromUint32x4Bits(x);
+ }
}
@@ -264,6 +267,9 @@
/* patch */ factory Uint32x4.bool(bool x, bool y, bool z, bool w) {
return new _Uint32x4.bool(x, y, z, w);
}
+ /* patch */ factory Uint32x4.fromFloat32x4Bits(Float32x4 x) {
+ return new _Uint32x4.fromFloat32x4Bits(x);
+ }
}
@@ -1947,6 +1953,8 @@
native "Float32x4_fromDoubles";
factory _Float32x4.splat(double v) native "Float32x4_splat";
factory _Float32x4.zero() native "Float32x4_zero";
+ factory _Float32x4.fromUint32x4Bits(Uint32x4 x)
+ native "Float32x4_fromUint32x4Bits";
Float32x4 operator +(Float32x4 other) {
return _add(other);
}
@@ -2048,10 +2056,6 @@
return _reciprocalSqrt();
}
Float32x4 _reciprocalSqrt() native "Float32x4_reciprocalSqrt";
- Uint32x4 toUint32x4() {
- return _toUint32x4();
- }
- Uint32x4 _toUint32x4() native "Float32x4_toUint32x4";
}
@@ -2060,6 +2064,8 @@
native "Uint32x4_fromInts";
factory _Uint32x4.bool(bool x, bool y, bool z, bool w)
native "Uint32x4_fromBools";
+ factory _Uint32x4.fromFloat32x4Bits(Float32x4 x)
+ native "Uint32x4_fromFloat32x4Bits";
Uint32x4 operator |(Uint32x4 other) {
return _or(other);
}
@@ -2104,10 +2110,6 @@
Float32x4 _select(Float32x4 trueValue,
Float32x4 falseValue)
native "Uint32x4_select";
- Float32x4 toFloat32x4() {
- return _toFloat32x4();
- }
- Float32x4 _toFloat32x4() native "Uint32x4_toFloat32x4";
}
class _TypedListIterator<E> implements Iterator<E> {
diff --git a/runtime/lib/uri.cc b/runtime/lib/uri.cc
index f75d2ec..66ab6ed 100644
--- a/runtime/lib/uri.cc
+++ b/runtime/lib/uri.cc
@@ -9,7 +9,7 @@
namespace dart {
DEFINE_NATIVE_ENTRY(Uri_isWindowsPlatform, 0) {
-#if defined(_WIN32)
+#if defined(TARGET_OS_WINDOWS)
return Bool::True().raw();
#else
return Bool::False().raw();
diff --git a/runtime/lib/uri_patch.dart b/runtime/lib/uri_patch.dart
index b07946d..93abe0d 100644
--- a/runtime/lib/uri_patch.dart
+++ b/runtime/lib/uri_patch.dart
@@ -3,10 +3,22 @@
// BSD-style license that can be found in the LICENSE file.
// VM implementation of Uri.
+typedef Uri _UriBaseClosure();
+
+Uri _unsupportedUriBase() {
+ throw new UnsupportedError("'Uri.base' is not supported");
+}
+
+// _uriBaseClosure can be overwritten by the embedder to supply a different
+// value for Uri.base.
+_UriBaseClosure _uriBaseClosure = _unsupportedUriBase;
+
patch class Uri {
static final bool _isWindowsCached = _isWindowsPlatform;
- static bool get _isWindowsPlatform native "Uri_isWindowsPlatform";
-
/* patch */ static bool get _isWindows => _isWindowsCached;
+
+ /* patch */ static Uri get base => _uriBaseClosure();
+
+ static bool get _isWindowsPlatform native "Uri_isWindowsPlatform";
}
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 3d3780b..9c41836 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -417,22 +417,6 @@
}
-// A macro to ensure that memcpy cannot be called. memcpy does not handle
-// overlapping memory regions. Even though this is well documented it seems
-// to be used in error quite often. To avoid problems we disallow the direct
-// use of memcpy here.
-//
-// On Android and Windows the basic libraries use memcpy and therefore
-// compilation will fail if memcpy is overwritten even if user code does not
-// use memcpy.
-#if defined(memcpy)
-#undef memcpy
-#endif
-#if !( defined(TARGET_OS_ANDROID) || defined(TARGET_OS_WINDOWS) )
-#define memcpy "Please use memmove instead of memcpy."
-#endif
-
-
// On Windows the reentrent version of strtok is called
// strtok_s. Unify on the posix name strtok_r.
#if defined(TARGET_OS_WINDOWS)
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 6add296..744aa61 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -37,12 +37,12 @@
[ $compiler == dart2js ]
# The source positions do not match with dart2js.
-dart/optimized_stacktrace_test: Fail
+dart/optimized_stacktrace_test: RuntimeError
[ $compiler == dart2js ]
# Methods can be missing in dart2js stack traces due to inlining. Also when
# minifying they can be renamed, which is issue 7953.
-dart/inline_stack_frame_test: Fail
+dart/inline_stack_frame_test: RuntimeError
[ $compiler == dart2dart ]
# Skip until we stabilize language tests.
@@ -59,12 +59,6 @@
cc/Cop1CvtDL: Crash
cc/Cop1CvtDL_neg: Crash
-# TODO(ajohnsen): Fix this as part of library changes.
-[ $compiler == none ]
-cc/CustomIsolates: Fail, Crash # Bug 6890
-cc/NewNativePort: Fail # Bug 6890
-cc/RunLoop_ExceptionParent: Fail # Bug 6890
-
[ $compiler == dartanalyzer ]
# has compilation error, as designed
dart/isolate_mirror_local_test: fail
diff --git a/runtime/tools/create_resources.py b/runtime/tools/create_resources.py
index d2c0cea..e3a9c84 100644
--- a/runtime/tools/create_resources.py
+++ b/runtime/tools/create_resources.py
@@ -26,7 +26,7 @@
resource_url = '/%s' % resource_file_name
result += '// %s\n' % resource_file
result += 'const char '
- resource_name = re.sub(r'(/|\.)', '_', resource_file_name) + '_'
+ resource_name = re.sub(r'(/|\.|-)', '_', resource_file_name) + '_'
result += resource_name
result += '[] = {\n '
fileHandle = open(resource_file, 'rb')
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 11639c1..f7b0ea3 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -1173,7 +1173,7 @@
EmitREX_RB(dst, src);
EmitUint8(0x0F);
EmitUint8(0xEF);
- EmitXmmRegisterOperand(dst, src);
+ EmitXmmRegisterOperand(dst & 7, src);
}
@@ -1186,7 +1186,7 @@
EmitUint8(0x0F);
EmitUint8(0x3A);
EmitUint8(0x0B);
- EmitXmmRegisterOperand(dst, src);
+ EmitXmmRegisterOperand(dst & 7, src);
// Mask precision exeption.
EmitUint8(static_cast<uint8_t>(mode) | 0x8);
}
@@ -2225,9 +2225,12 @@
bool Assembler::CanLoadFromObjectPool(const Object& object) {
- // TODO(zra, kmillikin): Move the use of large Smis into the constant pool.
+ // TODO(zra, kmillikin): Also load other large immediates from the object
+ // pool
if (object.IsSmi()) {
- return false;
+ // If the raw smi does not fit into a 32-bit signed int, then we'll keep
+ // the raw value in the object pool.
+ return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw()));
}
ASSERT(object.IsNotTemporaryScopedHandle());
ASSERT(object.IsOld());
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 826222b..f4b947c 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -186,6 +186,7 @@
V(ByteData_ToEndianFloat64, 2) \
V(Float32x4_fromDoubles, 5) \
V(Float32x4_splat, 2) \
+ V(Float32x4_fromUint32x4Bits, 2) \
V(Float32x4_zero, 1) \
V(Float32x4_add, 2) \
V(Float32x4_negate, 1) \
@@ -221,9 +222,9 @@
V(Float32x4_sqrt, 1) \
V(Float32x4_reciprocal, 1) \
V(Float32x4_reciprocalSqrt, 1) \
- V(Float32x4_toUint32x4, 1) \
V(Uint32x4_fromInts, 5) \
V(Uint32x4_fromBools, 5) \
+ V(Uint32x4_fromFloat32x4Bits, 2) \
V(Uint32x4_or, 2) \
V(Uint32x4_and, 2) \
V(Uint32x4_xor, 2) \
@@ -247,7 +248,6 @@
V(Uint32x4_setFlagZ, 2) \
V(Uint32x4_setFlagW, 2) \
V(Uint32x4_select, 3) \
- V(Uint32x4_toFloat32x4, 1) \
V(isolate_getPortInternal, 0) \
V(isolate_spawnFunction, 2) \
V(isolate_spawnUri, 1) \
@@ -260,6 +260,7 @@
V(InstanceMirror_invoke, 5) \
V(InstanceMirror_invokeGetter, 3) \
V(InstanceMirror_invokeSetter, 4) \
+ V(ClosureMirror_find_in_context, 2) \
V(ClosureMirror_function, 1) \
V(ClosureMirror_apply, 3) \
V(ClassMirror_library, 1) \
diff --git a/runtime/vm/cha.cc b/runtime/vm/cha.cc
index 01aabcc..248c309 100644
--- a/runtime/vm/cha.cc
+++ b/runtime/vm/cha.cc
@@ -73,6 +73,10 @@
bool CHA::HasOverride(const Class& cls, const String& function_name) {
const GrowableObjectArray& cls_direct_subclasses =
GrowableObjectArray::Handle(cls.direct_subclasses());
+ // Subclasses of Object are not tracked by CHA. Safely assume that overrides
+ // exist.
+ if (cls.IsObjectClass()) return true;
+
if (cls_direct_subclasses.IsNull()) {
return false;
}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 2214422..285f385 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -295,7 +295,7 @@
ASSERT(factory.IsRedirectingFactory());
// Check for redirection cycle.
- for (int i = 0; i < visited_factories.Length(); i++) {
+ for (intptr_t i = 0; i < visited_factories.Length(); i++) {
if (visited_factories.At(i) == factory.raw()) {
// A redirection cycle is reported as a compile-time error.
const Script& script = Script::Handle(cls.script());
@@ -506,6 +506,11 @@
if (cls.IsMixinApplication()) {
// Copy the type parameters to the mixin application.
ApplyMixinType(cls);
+ // Finalize the mixin type.
+ Type& mixin_type = Type::Handle(cls.mixin());
+ mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed);
+ // TODO(regis): Check for a malbounded mixin_type.
+ cls.set_mixin(mixin_type);
}
// The type parameter bounds are not finalized here.
const TypeArguments& type_parameters =
@@ -1201,7 +1206,7 @@
if (FLAG_error_on_bad_override && // Report signature conflicts only.
!function.is_static() && !function.IsConstructor()) {
// A constructor cannot override anything.
- for (int i = 0; i < interfaces.Length(); i++) {
+ for (intptr_t i = 0; i < interfaces.Length(); i++) {
super_class ^= interfaces.At(i);
overridden_function = super_class.LookupDynamicFunction(name);
if (!overridden_function.IsNull() &&
@@ -1306,115 +1311,311 @@
// mixin application class. Change type arguments of super type and of
// interfaces to refer to the respective type parameters of the mixin
// application class.
-void ClassFinalizer::CloneTypeParameters(const Class& mixin_app_class) {
+void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) {
ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null());
-
- const AbstractType& super_type =
- AbstractType::Handle(mixin_app_class.super_type());
+ const AbstractType& super_type = AbstractType::Handle(
+ mixin_app_class.super_type());
ASSERT(super_type.IsResolved());
const Class& super_class = Class::Handle(super_type.type_class());
+ const intptr_t num_super_type_params = super_class.NumTypeParameters();
const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
const Class& mixin_class = Class::Handle(mixin_type.type_class());
- const int num_super_parameters = super_class.NumTypeParameters();
- const int num_mixin_parameters = mixin_class.NumTypeParameters();
- if ((num_super_parameters + num_mixin_parameters) == 0) {
- return;
- }
+ const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
+ // The mixin class cannot be Object and this was checked earlier.
+ ASSERT(!mixin_class.IsObjectClass());
- // First, clone the super class type parameters. Rename them so that
- // there can be no name conflict between the parameters of the super
- // class and the mixin class.
- const TypeArguments& cloned_type_params = TypeArguments::Handle(
- TypeArguments::New(num_super_parameters + num_mixin_parameters));
- TypeParameter& param = TypeParameter::Handle();
- TypeParameter& cloned_param = TypeParameter::Handle();
- String& param_name = String::Handle();
- AbstractType& param_bound = AbstractType::Handle();
- int cloned_index = 0;
- if (num_super_parameters > 0) {
- const TypeArguments& super_params =
- TypeArguments::Handle(super_class.type_parameters());
- const TypeArguments& super_type_args =
- TypeArguments::Handle(TypeArguments::New(num_super_parameters));
- for (int i = 0; i < num_super_parameters; i++) {
- param ^= super_params.TypeAt(i);
- param_name = param.name();
- param_bound = param.bound();
- // TODO(hausner): handle type bounds.
- if (!param_bound.IsObjectType()) {
- const Script& script = Script::Handle(mixin_app_class.script());
- ReportError(Error::Handle(), // No previous error.
- script, param.token_pos(),
- "type parameter '%s': type bounds not yet"
- " implemented for mixins\n",
- param_name.ToCString());
+ // Add the mixin type to the interfaces that the mixin application
+ // class implements. This is necessary so that type tests work.
+ const Array& interfaces = Array::Handle(Array::New(1));
+ const Type& interface = Type::Handle(Type::New(
+ mixin_class,
+ Object::null_abstract_type_arguments(), // Set again below if generic.
+ mixin_app_class.token_pos()));
+ ASSERT(!interface.IsFinalized());
+ interfaces.SetAt(0, interface);
+ mixin_app_class.set_interfaces(interfaces);
+
+ // If both the super type and the mixin type are non generic, the mixin
+ // application class is non generic as well and we can skip type parameter
+ // cloning.
+ if ((num_super_type_params + num_mixin_type_params) > 0) {
+ // First, clone the super class type parameters. Rename them so that
+ // there can be no name conflict between the parameters of the super
+ // class and the mixin class.
+ const TypeArguments& cloned_type_params = TypeArguments::Handle(
+ TypeArguments::New(num_super_type_params + num_mixin_type_params));
+ TypeParameter& param = TypeParameter::Handle();
+ TypeParameter& cloned_param = TypeParameter::Handle();
+ String& param_name = String::Handle();
+ AbstractType& param_bound = AbstractType::Handle();
+ intptr_t cloned_index = 0;
+ if (num_super_type_params > 0) {
+ const TypeArguments& super_type_params =
+ TypeArguments::Handle(super_class.type_parameters());
+ const TypeArguments& super_type_args =
+ TypeArguments::Handle(TypeArguments::New(num_super_type_params));
+ for (intptr_t i = 0; i < num_super_type_params; i++) {
+ param ^= super_type_params.TypeAt(i);
+ param_name = param.name();
+ param_bound = param.bound();
+ // TODO(hausner): handle type bounds.
+ if (!param_bound.IsObjectType()) {
+ const Script& script = Script::Handle(mixin_app_class.script());
+ ReportError(Error::Handle(), // No previous error.
+ script, param.token_pos(),
+ "type parameter '%s': type bounds not yet"
+ " implemented for mixins\n",
+ param_name.ToCString());
+ }
+ param_name = String::Concat(param_name, Symbols::Backtick());
+ param_name = Symbols::New(param_name);
+ cloned_param = TypeParameter::New(mixin_app_class,
+ cloned_index,
+ param_name,
+ param_bound,
+ param.token_pos());
+ cloned_type_params.SetTypeAt(cloned_index, cloned_param);
+ // Change the type arguments of the super type to refer to the
+ // cloned type parameters of the mixin application class.
+ super_type_args.SetTypeAt(cloned_index, cloned_param);
+ cloned_index++;
}
- param_name = String::Concat(param_name, Symbols::Backtick());
- param_name = Symbols::New(param_name);
- cloned_param = TypeParameter::New(mixin_app_class,
- cloned_index,
- param_name,
- param_bound,
- param.token_pos());
- cloned_type_params.SetTypeAt(cloned_index, cloned_param);
- // Change the type arguments of the super type to refer to the
- // cloned type parameters of the mixin application class.
- super_type_args.SetTypeAt(cloned_index, cloned_param);
- cloned_index++;
- }
- // TODO(hausner): May need to handle BoundedType here.
- ASSERT(super_type.IsType());
- Type::Cast(super_type).set_arguments(super_type_args);
- ASSERT(!super_type.IsFinalized());
- }
-
- // Second, clone the type parameters of the mixin class.
- // We need to retain the parameter names of the mixin class
- // since the code that will be compiled in the context of the
- // mixin application class may refer to the type parameters
- // with that name.
- if (num_mixin_parameters > 0) {
- const TypeArguments& mixin_params =
- TypeArguments::Handle(mixin_class.type_parameters());
- const TypeArguments& interface_type_args = TypeArguments::Handle(
- TypeArguments::New(num_mixin_parameters));
- for (int i = 0; i < num_mixin_parameters; i++) {
- param ^= mixin_params.TypeAt(i);
- param_name = param.name();
- param_bound = param.bound();
-
- // TODO(hausner): handle type bounds.
- if (!param_bound.IsObjectType()) {
- const Script& script = Script::Handle(mixin_app_class.script());
- ReportError(Error::Handle(), // No previous error.
- script, param.token_pos(),
- "type parameter '%s': type bounds not yet"
- " implemented for mixins\n",
- param_name.ToCString());
- }
- cloned_param = TypeParameter::New(mixin_app_class,
- cloned_index,
- param_name,
- param_bound,
- param.token_pos());
- cloned_type_params.SetTypeAt(cloned_index, cloned_param);
- interface_type_args.SetTypeAt(i, cloned_param);
- cloned_index++;
+ // TODO(hausner): May need to handle BoundedType here.
+ ASSERT(super_type.IsType());
+ Type::Cast(super_type).set_arguments(super_type_args);
+ ASSERT(!super_type.IsFinalized());
}
- // Lastly, change the type arguments of the single interface type to
- // refer to the cloned type parameters of the mixin application class.
- Array& interface_types = Array::Handle(mixin_app_class.interfaces());
- ASSERT(interface_types.Length() == 1);
- AbstractType& interface_type = AbstractType::Handle();
- interface_type ^= interface_types.At(0);
- ASSERT(interface_type.IsResolved());
- // TODO(hausner): May need to handle BoundedType here.
- ASSERT(interface_type.IsType());
- Type::Cast(interface_type).set_arguments(interface_type_args);
- ASSERT(!interface_type.IsFinalized());
+ // Second, clone the type parameters of the mixin class.
+ // We need to retain the parameter names of the mixin class
+ // since the code that will be compiled in the context of the
+ // mixin application class may refer to the type parameters
+ // with that name.
+ if (num_mixin_type_params > 0) {
+ const TypeArguments& mixin_params =
+ TypeArguments::Handle(mixin_class.type_parameters());
+ const TypeArguments& interface_type_args = TypeArguments::Handle(
+ TypeArguments::New(num_mixin_type_params));
+ for (intptr_t i = 0; i < num_mixin_type_params; i++) {
+ param ^= mixin_params.TypeAt(i);
+ param_name = param.name();
+ param_bound = param.bound();
+
+ // TODO(hausner): handle type bounds.
+ if (!param_bound.IsObjectType()) {
+ const Script& script = Script::Handle(mixin_app_class.script());
+ ReportError(Error::Handle(), // No previous error.
+ script, param.token_pos(),
+ "type parameter '%s': type bounds not yet"
+ " implemented for mixins\n",
+ param_name.ToCString());
+ }
+ cloned_param = TypeParameter::New(mixin_app_class,
+ cloned_index,
+ param_name,
+ param_bound,
+ param.token_pos());
+ cloned_type_params.SetTypeAt(cloned_index, cloned_param);
+ interface_type_args.SetTypeAt(i, cloned_param);
+ cloned_index++;
+ }
+
+ // Lastly, set the type arguments of the single interface type.
+ ASSERT(!interface.IsFinalized());
+ interface.set_arguments(interface_type_args);
+ }
+ mixin_app_class.set_type_parameters(cloned_type_params);
}
- mixin_app_class.set_type_parameters(cloned_type_params);
+ // If the mixin class is a mixin application typedef class, we insert a new
+ // synthesized mixin application class in the super chain of this mixin
+ // application class. The new class will have the aliased mixin as actual
+ // mixin.
+ if (mixin_class.is_mixin_typedef()) {
+ ApplyMixinTypedef(mixin_app_class);
+ }
+}
+
+
+/* Support for mixin typedef.
+Consider the following example:
+
+class I<T> { }
+class J<T> { }
+class S<T> { }
+class M<T> { }
+typedef A<U, V> = Object with M<Map<U, V>> implements I<V>;
+typedef C<T, K> = S<T> with A<T, List<K>> implements J<K>;
+
+Before the call to ApplyMixinTypedef, the VM has already synthesized 2 mixin
+application classes Object&M and S&A:
+
+Object&M<T> extends Object implements M<T> { ... members of M applied here ... }
+A<U, V> extends Object&M<Map<U, V>> implements I<V> { }
+
+S&A<T`, U, V> extends S<T`> implements A<U, V> { }
+C<T, K> extends S&A<T, T, List<K>> implements J<K> { }
+
+In theory, class A should be an alias of Object&M instead of extending it.
+In practice, the additional class provides a hook for implemented interfaces
+(e.g. I<V>) and for type argument substitution via the super type relation (e.g.
+type parameter T of Object&M is substituted with Map<U, V>, U and V being the
+type parameters of the typedef A).
+
+Similarly, class C should be an alias of S&A instead of extending it.
+
+Since A is used as a mixin, it must extend Object. The fact that it extends
+Object&M must be hidden so that no error is wrongly reported.
+
+Now, A does not have any members to be mixed into S&A, because A is a typedef.
+The members to be mixed in are actually those of M, and they should appear in a
+scope where the type parameter T is visible. The class S&A declares the type
+parameters of A, i.e. U and V, but not T.
+
+Therefore, the call to ApplyMixinTypedef inserts another synthesized class S&A`
+as the superclass of S&A. The class S&A` declares a type argument T:
+
+Instead of
+S&A<T`, U, V> extends S<T`> implements A<U, V> { }
+
+We now have:
+S&A`<T`, T> extends S<T`> implements M<T> { ... members of M applied here ... }
+S&A<T`, U, V> extends S&A`<T`, Map<U, V>> implements A<U, V> { }
+
+The main implementation difficulty resides in the fact that the type parameters
+U and V in the super type S&A`<T`, Map<U, V>> of S&A refer to the type
+parameters U and V of S&A, not to U and V of A. An instantiation step with
+a properly crafted instantiator vector takes care of the required type parameter
+substitution.
+*/
+void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) {
+ // If this mixin typedef is aliasing another mixin typedef, another class
+ // will be inserted via recursion. No need to check here.
+ const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
+ const Class& mixin_class = Class::Handle(mixin_type.type_class());
+ ASSERT(mixin_class.is_mixin_typedef());
+ const Class& aliased_mixin_app_class = Class::Handle(
+ mixin_class.SuperClass());
+ const Type& aliased_mixin_type = Type::Handle(
+ aliased_mixin_app_class.mixin());
+ // The name of the inserted mixin application class is the name of mixin
+ // class name with a backtick added.
+ String& inserted_class_name = String::Handle(mixin_app_class.Name());
+ inserted_class_name = String::Concat(inserted_class_name,
+ Symbols::Backtick());
+ inserted_class_name = Symbols::New(inserted_class_name);
+ const Script& script = Script::Handle(mixin_app_class.script());
+ const Library& library = Library::Handle(mixin_app_class.library());
+ const Class& inserted_class = Class::Handle(Class::New(
+ inserted_class_name, script, mixin_app_class.token_pos()));
+ inserted_class.set_library(library);
+ inserted_class.set_is_synthesized_class();
+
+ // The super type of the inserted class is identical to the super type of
+ // this mixin application class, except that it must refer to the type
+ // parameters of the inserted class rather than to those of the mixin
+ // application class.
+ // The type arguments of the super type will be set properly when calling
+ // CloneMixinAppTypeParameters on the inserted class, as long as the super
+ // type class is set properly.
+ AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type());
+ inserted_class.set_super_type(super_type); // Super class only is used.
+
+ // The mixin type must also be set before calling CloneMixinAppTypeParameters.
+ // It refers to the type parameters of the mixin class typedef.
+ inserted_class.set_mixin(aliased_mixin_type); // Mixin class only is used.
+
+ // Finalize the types and call CloneMixinAppTypeParameters.
+ FinalizeTypesInClass(inserted_class);
+
+ // The super type of this mixin application class must point to the
+ // inserted class. The super type arguments are the concatenation of the
+ // old super type arguments (propagating type arguments to the super class)
+ // with new type arguments providing type arguments to the mixin.
+ // The appended type arguments are those of the aliased mixin type, except
+ // that they must refer to the type parameters of the mixin application
+ // class rather than to those of the aliased mixin class.
+ // This type parameter substitution is performed by an instantiation step.
+ // It is important that the type parameters of the mixin application class
+ // are not finalized yet, because new type parameters may have been added
+ // to the super class.
+ Class& super_class = Class::Handle(super_type.type_class());
+ ASSERT(mixin_app_class.SuperClass() == super_class.raw());
+ while (super_class.IsMixinApplication()) {
+ super_class = super_class.SuperClass();
+ }
+ const intptr_t num_super_type_params = super_class.NumTypeParameters();
+ const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
+ intptr_t offset = aliased_mixin_app_class.NumTypeArguments();
+ const TypeArguments& type_params =
+ TypeArguments::Handle(mixin_app_class.type_parameters());
+ TypeArguments& instantiator = TypeArguments::Handle(
+ TypeArguments::New(offset + num_mixin_type_params));
+ AbstractType& type = AbstractType::Handle();
+ for (intptr_t i = 0; i < num_mixin_type_params; i++) {
+ type = type_params.TypeAt(num_super_type_params + i);
+ instantiator.SetTypeAt(offset + i, type);
+ }
+ ASSERT(aliased_mixin_type.IsFinalized());
+ const Class& aliased_mixin_type_class = Class::Handle(
+ aliased_mixin_type.type_class());
+ const intptr_t num_aliased_mixin_type_params =
+ aliased_mixin_type_class.NumTypeParameters();
+ const intptr_t num_aliased_mixin_type_args =
+ aliased_mixin_type_class.NumTypeArguments();
+ offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params;
+ ASSERT(inserted_class.NumTypeParameters() ==
+ (num_super_type_params + num_aliased_mixin_type_params));
+ // The aliased_mixin_type may be raw.
+ const AbstractTypeArguments& aliased_mixin_type_args =
+ AbstractTypeArguments::Handle(aliased_mixin_type.arguments());
+ TypeArguments& new_mixin_type_args = TypeArguments::Handle();
+ if ((num_aliased_mixin_type_params > 0) &&
+ !aliased_mixin_type_args.IsNull()) {
+ new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params);
+ for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
+ type = aliased_mixin_type_args.TypeAt(offset + i);
+ new_mixin_type_args.SetTypeAt(i, type);
+ }
+ }
+ if (!new_mixin_type_args.IsNull() &&
+ !new_mixin_type_args.IsInstantiated()) {
+ Error& bound_error = Error::Handle();
+ new_mixin_type_args ^=
+ new_mixin_type_args.InstantiateFrom(instantiator, &bound_error);
+ // TODO(regis): Handle bound error.
+ ASSERT(bound_error.IsNull());
+ }
+ TypeArguments& new_super_type_args = TypeArguments::Handle();
+ if ((num_super_type_params + num_aliased_mixin_type_params) > 0) {
+ new_super_type_args = TypeArguments::New(num_super_type_params +
+ num_aliased_mixin_type_params);
+ for (intptr_t i = 0; i < num_super_type_params; i++) {
+ type = type_params.TypeAt(i);
+ new_super_type_args.SetTypeAt(i, type);
+ }
+ for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
+ if (new_mixin_type_args.IsNull()) {
+ type = Type::DynamicType();
+ } else {
+ type = new_mixin_type_args.TypeAt(i);
+ }
+ new_super_type_args.SetTypeAt(num_super_type_params + i, type);
+ }
+ }
+ super_type = Type::New(inserted_class,
+ new_super_type_args,
+ mixin_app_class.token_pos());
+ mixin_app_class.set_super_type(super_type);
+ // Mark this mixin application class as being a typedef.
+ mixin_app_class.set_is_mixin_typedef();
+ ASSERT(!mixin_app_class.is_type_finalized());
+ if (FLAG_trace_class_finalization) {
+ OS::Print("Inserting class %s to mixin typedef application %s "
+ "with super type '%s'\n",
+ inserted_class.ToCString(),
+ mixin_app_class.ToCString(),
+ String::Handle(super_type.Name()).ToCString());
+ }
}
@@ -1422,10 +1623,10 @@
if (mixin_app_class.is_mixin_type_applied()) {
return;
}
- const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
+ Type& mixin_type = Type::Handle(mixin_app_class.mixin());
ASSERT(!mixin_type.IsNull());
ASSERT(mixin_type.HasResolvedTypeClass());
- const Class& mixin_cls = Class::Handle(mixin_type.type_class());
+ const Class& mixin_class = Class::Handle(mixin_type.type_class());
if (FLAG_trace_class_finalization) {
OS::Print("Applying mixin type '%s' to %s at pos %" Pd "\n",
@@ -1434,21 +1635,44 @@
mixin_app_class.token_pos());
}
- // Check that the super class of the mixin class is extending
- // class Object.
- const AbstractType& mixin_super_type =
- AbstractType::Handle(mixin_cls.super_type());
- if (!mixin_super_type.IsObjectType()) {
+ // Check for illegal self references. This has to be done before checking
+ // that the super class of the mixin class is class Object.
+ GrowableArray<intptr_t> visited_mixins;
+ if (!IsMixinCycleFree(mixin_class, &visited_mixins)) {
+ const Script& script = Script::Handle(mixin_class.script());
+ const String& class_name = String::Handle(mixin_class.Name());
+ ReportError(Error::Handle(), // No previous error.
+ script, mixin_class.token_pos(),
+ "mixin class '%s' illegally refers to itself",
+ class_name.ToCString());
+ }
+
+ // Check that the super class of the mixin class is class Object.
+ Class& mixin_super_class = Class::Handle(mixin_class.SuperClass());
+ // Skip over mixin application typedef classes, which are aliases (but are
+ // implemented as subclasses) of the mixin application classes they name.
+ if (!mixin_super_class.IsNull() && mixin_class.is_mixin_typedef()) {
+ while (mixin_super_class.is_mixin_typedef()) {
+ mixin_super_class = mixin_super_class.SuperClass();
+ }
+ mixin_super_class = mixin_super_class.SuperClass();
+ }
+ if (mixin_super_class.IsNull() || !mixin_super_class.IsObjectClass()) {
const Script& script = Script::Handle(mixin_app_class.script());
- const String& class_name = String::Handle(mixin_cls.Name());
+ const String& class_name = String::Handle(mixin_class.Name());
ReportError(Error::Handle(), // No previous error.
script, mixin_app_class.token_pos(),
- "mixin class '%s' must extend class Object",
+ "mixin class '%s' must extend class 'Object'",
class_name.ToCString());
}
// Copy type parameters to mixin application class.
- CloneTypeParameters(mixin_app_class);
+ CloneMixinAppTypeParameters(mixin_app_class);
+
+ // Verify that no restricted class is used as a mixin by checking the
+ // interfaces of the mixin application class, which implements its mixin.
+ GrowableArray<intptr_t> visited_interfaces;
+ ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces);
if (FLAG_trace_class_finalization) {
OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n",
@@ -1477,12 +1701,17 @@
if (func.IsConstructor()) {
// Build constructor name from mixin application class name
// and name of cloned super class constructor.
- String& ctor_name = String::Handle(func.name());
- ctor_name = String::SubString(ctor_name, super_name.Length());
- String& clone_name =
- String::Handle(String::Concat(mixin_name, ctor_name));
+ const String& ctor_name = String::Handle(func.name());
+ String& clone_name = String::Handle(
+ String::SubString(ctor_name, super_name.Length()));
+ clone_name = String::Concat(mixin_name, clone_name);
clone_name = Symbols::New(clone_name);
+ if (FLAG_trace_class_finalization) {
+ OS::Print("Cloning constructor '%s' as '%s'\n",
+ ctor_name.ToCString(),
+ clone_name.ToCString());
+ }
const Function& clone = Function::Handle(
Function::New(clone_name,
func.kind(),
@@ -1498,7 +1727,7 @@
func.HasOptionalPositionalParameters());
clone.set_result_type(dynamic_type);
- const int num_parameters = func.NumParameters();
+ const intptr_t num_parameters = func.NumParameters();
// The cloned ctor shares the parameter names array with the
// original.
const Array& parameter_names = Array::Handle(func.parameter_names());
@@ -1522,6 +1751,14 @@
ASSERT(mixin_type.HasResolvedTypeClass());
const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class());
mixin_cls.EnsureIsFinalized(isolate);
+ // If the mixin is a mixin application typedef class, there are no members to
+ // apply here. A new synthesized class representing the aliased mixin
+ // application class was inserted in the super chain of this mixin application
+ // class. Members of the actual mixin class will be applied when visiting
+ // the mixin application class referring to the actual mixin.
+ ASSERT(!mixin_cls.is_mixin_typedef() ||
+ Class::Handle(isolate, cls.SuperClass()).IsMixinApplication());
+ // A default constructor will be created for the typedef class.
if (FLAG_trace_class_finalization) {
OS::Print("Applying mixin members of %s to %s at pos %" Pd "\n",
@@ -1542,7 +1779,7 @@
// Now clone the functions from the mixin class.
functions = mixin_cls.functions();
const intptr_t num_functions = functions.Length();
- for (int i = 0; i < num_functions; i++) {
+ for (intptr_t i = 0; i < num_functions; i++) {
func ^= functions.At(i);
if (func.IsConstructor()) {
// A mixin class must not have explicit constructors.
@@ -1571,7 +1808,7 @@
const GrowableObjectArray& cloned_fields =
GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
const intptr_t num_fields = fields.Length();
- for (int i = 0; i < num_fields; i++) {
+ for (intptr_t i = 0; i < num_fields; i++) {
field ^= fields.At(i);
if (!field.is_static()) {
field = field.Clone(cls);
@@ -1582,7 +1819,7 @@
cls.SetFields(fields);
if (FLAG_trace_class_finalization) {
- OS::Print("done applying mixin members of %s to %s\n",
+ OS::Print("Done applying mixin members of %s to %s\n",
mixin_cls.ToCString(),
cls.ToCString());
}
@@ -1606,12 +1843,14 @@
name.ToCString());
}
// Finalize super class.
- const Class& super_class = Class::Handle(cls.SuperClass());
+ Class& super_class = Class::Handle(cls.SuperClass());
if (!super_class.IsNull()) {
FinalizeTypesInClass(super_class);
}
// Finalize type parameters before finalizing the super type.
- FinalizeTypeParameters(cls);
+ FinalizeTypeParameters(cls); // May change super type.
+ super_class = cls.SuperClass();
+ ASSERT(super_class.IsNull() || super_class.is_type_finalized());
ResolveUpperBounds(cls);
// Finalize super type.
AbstractType& super_type = AbstractType::Handle(cls.super_type());
@@ -1733,11 +1972,14 @@
}
// Mark as parsed and finalized.
cls.Finalize();
- // Mixin typedef classes may still lack their implicit constructor.
- // TODO(regis): Implement mixin typedefs with an alias class.
- if (cls.is_synthesized_class() &&
+ // Mixin typedef classes may still lack their forwarding constructor.
+ if (cls.is_mixin_typedef() &&
(cls.functions() == Object::empty_array().raw())) {
- Parser::AddImplicitConstructor(cls);
+ const GrowableObjectArray& cloned_funcs =
+ GrowableObjectArray::Handle(GrowableObjectArray::New());
+ CreateForwardingConstructors(cls, cloned_funcs);
+ const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs));
+ cls.SetFunctions(functions);
}
// Every class should have at least a constructor, unless it is a top level
// class or a signature class.
@@ -1812,7 +2054,7 @@
ASSERT(!cls.is_type_finalized());
ASSERT(visited != NULL);
const intptr_t cls_index = cls.id();
- for (int i = 0; i < visited->length(); i++) {
+ for (intptr_t i = 0; i < visited->length(); i++) {
if ((*visited)[i] == cls_index) {
// We have already visited alias 'cls'. We found a cycle.
return false;
@@ -1840,6 +2082,38 @@
}
+// Returns false if the mixin illegally refers to itself.
+bool ClassFinalizer::IsMixinCycleFree(const Class& cls,
+ GrowableArray<intptr_t>* visited) {
+ ASSERT(visited != NULL);
+ const intptr_t cls_index = cls.id();
+ for (intptr_t i = 0; i < visited->length(); i++) {
+ if ((*visited)[i] == cls_index) {
+ // We have already visited mixin 'cls'. We found a cycle.
+ return false;
+ }
+ }
+
+ // Visit the super chain of cls.
+ visited->Add(cls.id());
+ Class& super_class = Class::Handle(cls.raw());
+ do {
+ if (super_class.IsMixinApplication()) {
+ const Type& mixin_type = Type::Handle(super_class.mixin());
+ ASSERT(!mixin_type.IsNull());
+ ASSERT(mixin_type.HasResolvedTypeClass());
+ const Class& mixin_class = Class::Handle(mixin_type.type_class());
+ if (!IsMixinCycleFree(mixin_class, visited)) {
+ return false;
+ }
+ }
+ super_class = super_class.SuperClass();
+ } while (!super_class.IsNull());
+ visited->RemoveLast();
+ return true;
+}
+
+
void ClassFinalizer::CollectTypeArguments(
const Class& cls,
const Type& type,
@@ -1854,7 +2128,7 @@
AbstractType& arg = AbstractType::Handle();
if (num_type_arguments > 0) {
if (num_type_arguments == num_type_parameters) {
- for (int i = 0; i < num_type_arguments; i++) {
+ for (intptr_t i = 0; i < num_type_arguments; i++) {
arg = type_args.TypeAt(i);
collected_args.Add(arg);
}
@@ -1871,7 +2145,7 @@
// Discard provided type arguments and treat type as raw.
}
// Fill arguments with type dynamic.
- for (int i = 0; i < num_type_parameters; i++) {
+ for (intptr_t i = 0; i < num_type_parameters; i++) {
arg = Type::DynamicType();
collected_args.Add(arg);
}
@@ -1891,7 +2165,7 @@
CollectTypeArguments(cls, Type::Cast(type), type_args);
Class& mixin_app_class = Class::Handle();
const intptr_t depth = mixin_app.Depth();
- for (int i = 0; i < depth; i++) {
+ for (intptr_t i = 0; i < depth; i++) {
mixin_app_class = mixin_app.MixinAppAt(i);
type = mixin_app_class.mixin();
ASSERT(!type.IsNull());
@@ -1902,7 +2176,7 @@
}
const TypeArguments& mixin_app_args =
TypeArguments::Handle(TypeArguments::New(type_args.Length()));
- for (int i = 0; i < type_args.Length(); i++) {
+ for (intptr_t i = 0; i < type_args.Length(); i++) {
type ^= type_args.At(i);
mixin_app_args.SetTypeAt(i, type);
}
@@ -1934,7 +2208,7 @@
OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
}
const intptr_t cls_index = cls.id();
- for (int i = 0; i < visited->length(); i++) {
+ for (intptr_t i = 0; i < visited->length(); i++) {
if ((*visited)[i] == cls_index) {
// We have already visited class 'cls'. We found a cycle.
const String& class_name = String::Handle(cls.Name());
@@ -2067,10 +2341,8 @@
"function type alias '%s' may not be used as interface",
String::Handle(interface_class.Name()).ToCString());
}
- // Verify that unless cls belongs to core lib, it cannot extend or implement
- // any of Null, bool, num, int, double, String, Function, dynamic.
- // The exception is signature classes, which are compiler generated and
- // represent a function type, therefore implementing the Function interface.
+ // Verify that unless cls belongs to core lib, it cannot extend, implement,
+ // or mixin any of Null, bool, num, int, double, String, dynamic.
if (!cls_belongs_to_core_lib) {
if (interface.IsBoolType() ||
interface.IsNullType() ||
@@ -2080,11 +2352,19 @@
interface.IsStringType() ||
interface.IsDynamicType()) {
const Script& script = Script::Handle(cls.script());
- ReportError(Error::Handle(), // No previous error.
- script, cls.token_pos(),
- "'%s' is not allowed to extend or implement '%s'",
- String::Handle(cls.Name()).ToCString(),
- String::Handle(interface_class.Name()).ToCString());
+ const String& interface_name = String::Handle(interface_class.Name());
+ if (cls.IsMixinApplication()) {
+ ReportError(Error::Handle(), // No previous error.
+ script, cls.token_pos(),
+ "illegal mixin of '%s'",
+ interface_name.ToCString());
+ } else {
+ ReportError(Error::Handle(), // No previous error.
+ script, cls.token_pos(),
+ "'%s' is not allowed to extend or implement '%s'",
+ String::Handle(cls.Name()).ToCString(),
+ interface_name.ToCString());
+ }
}
}
interface_class.set_is_implemented();
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 2d632e8..e2689d0 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -103,6 +103,8 @@
GrowableArray<intptr_t>* visited);
static bool IsAliasCycleFree(const Class& cls,
GrowableArray<intptr_t>* visited);
+ static bool IsMixinCycleFree(const Class& cls,
+ GrowableArray<intptr_t>* visited);
static void CheckForLegalConstClass(const Class& cls);
static RawClass* ResolveClass(const Class& cls,
const UnresolvedClass& unresolved_class);
@@ -110,7 +112,8 @@
const Class& cls,
const Function& factory,
const GrowableObjectArray& visited_factories);
- static void CloneTypeParameters(const Class& mixin_app_class);
+ static void CloneMixinAppTypeParameters(const Class& mixin_app_class);
+ static void ApplyMixinTypedef(const Class& mixin_app_class);
static void ApplyMixinMembers(const Class& cls);
static void CreateForwardingConstructors(
const Class& mixin_app,
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 2527c3b..d9f1a53 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -270,9 +270,7 @@
LongJump bailout_jump;
isolate->set_long_jump_base(&bailout_jump);
if (setjmp(*bailout_jump.Set()) == 0) {
- FlowGraphBuilder* builder = NULL;
FlowGraph* flow_graph = NULL;
- GrowableArray<const Field*> guarded_fields;
// TimerScope needs an isolate to be properly terminated in case of a
// LongJump.
{
@@ -292,12 +290,11 @@
}
// Build the flow graph.
- builder = new FlowGraphBuilder(parsed_function,
- ic_data_array,
- NULL, // NULL = not inlining.
- &guarded_fields,
- osr_id);
- flow_graph = builder->BuildGraph();
+ FlowGraphBuilder builder(parsed_function,
+ ic_data_array,
+ NULL, // NULL = not inlining.
+ osr_id);
+ flow_graph = builder.BuildGraph();
}
if (FLAG_print_flow_graph ||
@@ -551,9 +548,11 @@
}
function.SetCode(code);
- for (intptr_t i = 0; i < guarded_fields.length(); i++) {
- const Field& field = *guarded_fields[i];
- field.RegisterDependentCode(code);
+ for (intptr_t i = 0;
+ i < flow_graph->guarded_fields()->length();
+ i++) {
+ const Field* field = (*flow_graph->guarded_fields())[i];
+ field->RegisterDependentCode(code);
}
} else {
function.set_unoptimized_code(code);
diff --git a/runtime/vm/coverage.cc b/runtime/vm/coverage.cc
index be99d26..5d284d2 100644
--- a/runtime/vm/coverage.cc
+++ b/runtime/vm/coverage.cc
@@ -4,6 +4,8 @@
#include "vm/coverage.h"
+#include "include/dart_api.h"
+
#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/object.h"
@@ -11,7 +13,8 @@
namespace dart {
-DEFINE_FLAG(bool, print_coverage, false, "Print code coverage.");
+DEFINE_FLAG(charp, coverage_dir, NULL,
+ "Enable writing coverage data into specified directory.");
void CodeCoverage::PrintClass(const Class& cls, const JSONArray& jsarr) {
const Array& functions = Array::Handle(cls.functions());
@@ -26,20 +29,22 @@
ICData& ic_data = ICData::Handle();
for (int i = 0; i < functions.Length(); i++) {
function ^= functions.At(i);
+
+ JSONObject jsobj(&jsarr);
+ script = function.script();
+ url = script.url();
+ name = function.QualifiedUserVisibleName();
+ jsobj.AddProperty("source", url.ToCString());
+ jsobj.AddProperty("function", name.ToCString());
+
+ JSONArray jsarr(&jsobj, "hits");
+
if (function.HasCode()) {
- JSONObject jsobj(&jsarr);
-
- script = function.script();
- url = script.url();
- name = function.QualifiedUserVisibleName();
- jsobj.AddProperty("source", url.ToCString());
- jsobj.AddProperty("function", name.ToCString());
-
+ // Print the hit counts for all IC datas.
code = function.unoptimized_code();
ic_array = code.ExtractTypeFeedbackArray();
descriptors = code.pc_descriptors();
- JSONArray jsarr(&jsobj, "hits");
for (int j = 0; j < descriptors.Length(); j++) {
PcDescriptors::Kind kind = descriptors.DescriptorKind(j);
// Only IC based calls have counting.
@@ -47,7 +52,7 @@
(kind == PcDescriptors::kUnoptStaticCall)) {
intptr_t deopt_id = descriptors.DeoptId(j);
ic_data ^= ic_array.At(deopt_id);
- if (!ic_data.IsNull() && (ic_data.AggregateCount() > 0)) {
+ if (!ic_data.IsNull()) {
intptr_t token_pos = descriptors.TokenPos(j);
intptr_t line = -1;
intptr_t col = -1;
@@ -59,14 +64,34 @@
}
}
}
+ } else {
+ // The function has no code so it was never executed and thus we add one
+ // zero count hit at the first token index.
+ intptr_t line = -1;
+ intptr_t col = -1;
+ script.GetTokenLocation(function.token_pos(), &line, &col);
+ JSONObject func_info(&jsarr);
+ func_info.AddProperty("line", line);
+ func_info.AddProperty("col", col);
+ func_info.AddProperty("count", static_cast<intptr_t>(0));
}
}
}
-void CodeCoverage::Print(Isolate* isolate) {
- JSONStream stream;
+void CodeCoverage::Write(Isolate* isolate) {
+ if (FLAG_coverage_dir == NULL) {
+ return;
+ }
+ Dart_FileOpenCallback file_open = Isolate::file_open_callback();
+ Dart_FileWriteCallback file_write = Isolate::file_write_callback();
+ Dart_FileCloseCallback file_close = Isolate::file_close_callback();
+ if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
+ return;
+ }
+
+ JSONStream stream;
{
const GrowableObjectArray& libs = GrowableObjectArray::Handle(
isolate, isolate->object_store()->libraries());
@@ -87,9 +112,20 @@
}
}
- OS::Print("### COVERAGE DATA ###\n"
- "%s\n"
- "### END ###\n", stream.ToCString());
+ const char* format = "%s/dart-cov-%" Pd "-%" Pd ".json";
+ intptr_t pid = OS::ProcessId();
+ intptr_t len = OS::SNPrint(NULL, 0, format,
+ FLAG_coverage_dir, pid, isolate->main_port());
+ char* filename = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+ OS::SNPrint(filename, len + 1, format,
+ FLAG_coverage_dir, pid, isolate->main_port());
+ void* file = (*file_open)(filename, true);
+ if (file == NULL) {
+ OS::Print("Failed to write coverage file: %s\n", filename);
+ return;
+ }
+ (*file_write)(stream.buffer()->buf(), stream.buffer()->length(), file);
+ (*file_close)(file);
}
} // namespace dart
diff --git a/runtime/vm/coverage.h b/runtime/vm/coverage.h
index 9819105..ef7ee82 100644
--- a/runtime/vm/coverage.h
+++ b/runtime/vm/coverage.h
@@ -10,7 +10,7 @@
namespace dart {
-DECLARE_FLAG(bool, print_coverage);
+DECLARE_FLAG(charp, coverage_dir);
// Forward declarations.
class Class;
@@ -19,7 +19,7 @@
class CodeCoverage : public AllStatic {
public:
- static void Print(Isolate* isolate);
+ static void Write(Isolate* isolate);
private:
static void PrintClass(const Class& cls, const JSONArray& arr);
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index a32c36e9..d64e836 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -22,7 +22,6 @@
static const char* kCustomIsolateScriptChars =
- "import 'dart:async';\n"
"import 'dart:isolate';\n"
"\n"
"ReceivePort mainPort;\n"
@@ -34,11 +33,8 @@
" echo('Constructing isolate');\n"
" }\n"
"\n"
- " Future<SendPort> spawn() {\n"
- " Completer<SendPort> completer = new Completer<SendPort>();\n"
- " SendPort port = _start(_entry);\n"
- " completer.complete(port);\n"
- " return completer.future;\n"
+ " SendPort spawn() {\n"
+ " return _start(_entry);\n"
" }\n"
"\n"
" static SendPort _start(entry)\n"
@@ -50,7 +46,7 @@
"abstract class CustomIsolate {\n"
" factory CustomIsolate(String entry) = CustomIsolateImpl;\n"
"\n"
- " Future<SendPort> spawn();\n"
+ " SendPort spawn();\n"
"}\n"
"\n"
"isolateMain() {\n"
@@ -63,10 +59,12 @@
"\n"
"main() {\n"
" var isolate = new CustomIsolate(\"isolateMain\");\n"
- " isolate.spawn().then((SendPort port) {\n"
- " port.call(42).then((message) {\n"
- " echo('Received: $message');\n"
- " });\n"
+ " var receivePort = new ReceivePort();\n"
+ " SendPort port = isolate.spawn();\n"
+ " port.send(42, receivePort.toSendPort());\n"
+ " receivePort.receive((message, _) {\n"
+ " receivePort.close();\n"
+ " echo('Received: $message');\n"
" });\n"
" return 'success';\n"
"}\n";
@@ -174,7 +172,6 @@
Dart_Handle lib = TestCase::LoadTestScript(kCustomIsolateScriptChars,
NativeLookup);
EXPECT_VALID(lib);
- EXPECT_VALID(Dart_CompileAll());
Dart_Handle recv_port = Dart_GetReceivePort(Dart_GetMainPortId());
EXPECT_VALID(recv_port);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 0ba9638..7a6bc66 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -124,7 +124,9 @@
FinalizablePersistentHandle* Api::UnwrapAsWeakPersistentHandle(
Dart_WeakPersistentHandle object) {
- ASSERT(Isolate::Current()->api_state()->IsValidWeakPersistentHandle(object));
+ ASSERT(Isolate::Current()->api_state()->IsValidWeakPersistentHandle(object) ||
+ Isolate::Current()->api_state()->
+ IsValidPrologueWeakPersistentHandle(object));
return reinterpret_cast<FinalizablePersistentHandle*>(object);
}
@@ -497,8 +499,18 @@
DART_EXPORT bool Dart_IdentityEquals(Dart_Handle obj1, Dart_Handle obj2) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
- NoGCScope ngc;
- return Api::UnwrapHandle(obj1) == Api::UnwrapHandle(obj2);
+ {
+ NoGCScope ngc;
+ if (Api::UnwrapHandle(obj1) == Api::UnwrapHandle(obj2)) {
+ return true;
+ }
+ }
+ const Object& object1 = Object::Handle(isolate, Api::UnwrapHandle(obj1));
+ const Object& object2 = Object::Handle(isolate, Api::UnwrapHandle(obj2));
+ if (object1.IsInstance() && object2.IsInstance()) {
+ return Instance::Cast(object1).IsIdenticalTo(Instance::Cast(object2));
+ }
+ return false;
}
@@ -1304,14 +1316,6 @@
}
-DART_EXPORT bool Dart_IsClass(Dart_Handle handle) {
- Isolate* isolate = Isolate::Current();
- DARTSCOPE(isolate);
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle));
- return obj.IsClass();
-}
-
-
DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) {
TRACE_API_CALL(CURRENT_FUNC);
return Api::ClassId(handle) == kFunctionCid;
@@ -1356,17 +1360,6 @@
return Api::NewHandle(isolate, type.Canonicalize());
}
-// TODO(asiva): Deprecate this method.
-DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance) {
- Isolate* isolate = Isolate::Current();
- DARTSCOPE(isolate);
- const Instance& obj = Api::UnwrapInstanceHandle(isolate, instance);
- if (obj.IsNull()) {
- RETURN_TYPE_ERROR(isolate, instance, Instance);
- }
- return Api::NewHandle(isolate, obj.clazz());
-}
-
// --- Numbers, Integers and Doubles ----
@@ -2841,29 +2834,15 @@
}
// Get the class to instantiate.
- result = Api::UnwrapHandle(type);
- if (result.IsNull()) {
+ const Type& type_obj = Api::UnwrapTypeHandle(isolate, type);
+ if (type_obj.IsNull()) {
RETURN_TYPE_ERROR(isolate, type, Type);
}
- Class& cls = Class::Handle(isolate);
- AbstractTypeArguments& type_arguments =
- AbstractTypeArguments::Handle(isolate);
+ Class& cls = Class::Handle(isolate, type_obj.type_class());
+ const AbstractTypeArguments& type_arguments =
+ AbstractTypeArguments::Handle(isolate, type_obj.arguments());
- if (result.IsType()) {
- cls = Type::Cast(result).type_class();
- type_arguments = Type::Cast(result).arguments();
- } else if (result.IsClass()) {
- // For backwards compatibility we allow class objects to be passed in
- // for now. This needs to be removed once all code that uses class
- // objects to invoke Dart_New is removed.
- cls ^= result.raw();
- type_arguments = Type::Handle(cls.RareType()).arguments();
- } else {
- RETURN_TYPE_ERROR(isolate, type, Type);
- }
-
- String& base_constructor_name = String::Handle();
- base_constructor_name = cls.Name();
+ const String& base_constructor_name = String::Handle(isolate, cls.Name());
// And get the name of the constructor to invoke.
String& dot_name = String::Handle(isolate);
@@ -2965,23 +2944,13 @@
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
CHECK_CALLBACK_STATE(isolate);
- const Object& result = Object::Handle(isolate, Api::UnwrapHandle(type));
+ const Type& type_obj = Api::UnwrapTypeHandle(isolate, type);
// Get the class to instantiate.
- if (result.IsNull()) {
+ if (type_obj.IsNull()) {
RETURN_TYPE_ERROR(isolate, type, Type);
}
- Class& cls = Class::Handle(isolate);
- if (result.IsType()) {
- cls = Type::Cast(result).type_class();
- } else if (result.IsClass()) {
- // For backwards compatibility we allow class objects to be passed in
- // for now. This needs to be removed once all code that uses class
- // objects to invoke Dart_New is removed.
- cls ^= result.raw();
- } else {
- RETURN_TYPE_ERROR(isolate, type, Type);
- }
+ const Class& cls = Class::Handle(isolate, type_obj.type_class());
// Allocate an object for the given class.
return Api::NewHandle(isolate, Instance::New(cls));
@@ -3030,22 +2999,14 @@
args.SetAt((i + num_receiver), arg);
}
- if (obj.IsType() || obj.IsClass()) {
+ if (obj.IsType()) {
// Finalize all classes.
Dart_Handle state = Api::CheckIsolateState(isolate);
if (::Dart_IsError(state)) {
return state;
}
- // For backwards compatibility we allow class objects to be passed in
- // for now. This needs to be removed once all code that uses class
- // objects to invoke Dart_Invoke is removed.
- Class& cls = Class::Handle();
- if (obj.IsType()) {
- cls = Type::Cast(obj).type_class();
- } else {
- cls = Class::Cast(obj).raw();
- }
+ const Class& cls = Class::Handle(isolate, Type::Cast(obj).type_class());
const Function& function = Function::Handle(
isolate,
Resolver::ResolveStatic(cls,
@@ -3092,8 +3053,9 @@
return state;
}
- Function& function = Function::Handle(isolate);
- function = lib.LookupFunctionAllowPrivate(function_name);
+ const Function& function =
+ Function::Handle(isolate,
+ lib.LookupFunctionAllowPrivate(function_name));
if (function.IsNull()) {
return Api::NewError("%s: did not find top-level function '%s'.",
CURRENT_FUNC,
@@ -3154,18 +3116,6 @@
}
-static bool FieldIsUninitialized(Isolate* isolate, const Field& fld) {
- ASSERT(!fld.IsNull());
-
- // Return getter method for uninitialized fields, rather than the
- // field object, since the value in the field object will not be
- // initialized until the first time the getter is invoked.
- const Instance& value = Instance::Handle(isolate, fld.value());
- ASSERT(value.raw() != Object::transition_sentinel().raw());
- return value.raw() == Object::sentinel().raw();
-}
-
-
DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
@@ -3188,20 +3138,13 @@
if (obj.IsNull()) {
return Api::NewError("%s expects argument 'container' to be non-null.",
CURRENT_FUNC);
- } else if (obj.IsType() || obj.IsClass()) {
+ } else if (obj.IsType()) {
// To access a static field we may need to use the Field or the
// getter Function.
- // For backwards compatibility we allow class objects to be passed in
- // for now. This needs to be removed once all code that uses class
- // objects to invoke Dart_GetField is removed.
- Class& cls = Class::Handle();
- if (obj.IsType()) {
- cls = Type::Cast(obj).type_class();
- } else {
- cls = Class::Cast(obj).raw();
- }
+ Class& cls = Class::Handle(isolate, Type::Cast(obj).type_class());
+
field = cls.LookupStaticField(field_name);
- if (field.IsNull() || FieldIsUninitialized(isolate, field)) {
+ if (field.IsNull() || field.IsUninitialized()) {
const String& getter_name =
String::Handle(isolate, Field::GetterName(field_name));
getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
@@ -3260,7 +3203,7 @@
const String& getter_name =
String::Handle(isolate, Field::GetterName(field_name));
getter = lib.LookupFunctionAllowPrivate(getter_name);
- } else if (!field.IsNull() && FieldIsUninitialized(isolate, field)) {
+ } else if (!field.IsNull() && field.IsUninitialized()) {
// A field was found. Check for a getter in the field's owner classs.
const Class& cls = Class::Handle(isolate, field.owner());
const String& getter_name =
@@ -3320,18 +3263,11 @@
if (obj.IsNull()) {
return Api::NewError("%s expects argument 'container' to be non-null.",
CURRENT_FUNC);
- } else if (obj.IsType() || obj.IsClass()) {
+ } else if (obj.IsType()) {
// To access a static field we may need to use the Field or the
// setter Function.
- // For backwards compatibility we allow class objects to be passed in
- // for now. This needs to be removed once all code that uses class
- // objects to invoke Dart_SetField is removed.
- Class& cls = Class::Handle();
- if (obj.IsType()) {
- cls = Type::Cast(obj).type_class();
- } else {
- cls = Class::Cast(obj).raw();
- }
+ Class& cls = Class::Handle(isolate, Type::Cast(obj).type_class());
+
field = cls.LookupStaticField(field_name);
if (field.IsNull()) {
String& setter_name =
@@ -3550,7 +3486,7 @@
return Api::NewError(
"Unable to create native wrapper class : already exists");
}
- return Api::NewHandle(isolate, cls.raw());
+ return Api::NewHandle(isolate, cls.RareType());
}
@@ -3606,6 +3542,14 @@
}
+DART_EXPORT void* Dart_GetNativeIsolateData(Dart_NativeArguments args) {
+ NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+ Isolate* isolate = arguments->isolate();
+ ASSERT(isolate);
+ return isolate->init_callback_data();
+}
+
+
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args,
int index) {
TRACE_API_CALL(CURRENT_FUNC);
@@ -3705,6 +3649,9 @@
if (RawObject::IsStringClassId(obj.GetClassId())) {
return Api::NewHandle(isolate, obj.raw());
}
+ if (obj.IsNull()) {
+ return Api::Null();
+ }
return Api::NewError("%s expects argument to be of"
" type String.", CURRENT_FUNC);
}
@@ -4034,7 +3981,7 @@
return Api::NewError("Class '%s' not found in library '%s'.",
cls_name.ToCString(), lib_name.ToCString());
}
- return Api::NewHandle(isolate, cls.raw());
+ return Api::NewHandle(isolate, cls.RareType());
}
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index a88df07..e5fce0d 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -189,6 +189,8 @@
Dart_Handle five = NewString("5");
Dart_Handle five_again = NewString("5");
Dart_Handle seven = NewString("7");
+ Dart_Handle dart_core = NewString("dart:core");
+ Dart_Handle dart_mirrors = NewString("dart:mirrors");
// Same objects.
EXPECT(Dart_IdentityEquals(five, five));
@@ -199,16 +201,25 @@
// Different objects.
EXPECT(!Dart_IdentityEquals(five, seven));
+ // Case where identical() is not the same as pointer equality.
+ Dart_Handle nan1 = Dart_NewDouble(NAN);
+ Dart_Handle nan2 = Dart_NewDouble(NAN);
+ EXPECT(Dart_IdentityEquals(nan1, nan2));
+
// Non-instance objects.
{
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
- Dart_Handle class1 = Api::NewHandle(isolate, Object::void_class());
- Dart_Handle class2 = Api::NewHandle(isolate, Object::class_class());
+ Dart_Handle lib1 = Dart_LookupLibrary(dart_core);
+ Dart_Handle lib2 = Dart_LookupLibrary(dart_mirrors);
- EXPECT(Dart_IdentityEquals(class1, class1));
+ EXPECT(Dart_IdentityEquals(lib1, lib1));
+ EXPECT(Dart_IdentityEquals(lib2, lib2));
+ EXPECT(!Dart_IdentityEquals(lib1, lib2));
- EXPECT(!Dart_IdentityEquals(class1, class2));
+ // Mix instance and non-instance.
+ EXPECT(!Dart_IdentityEquals(lib1, nan1));
+ EXPECT(!Dart_IdentityEquals(nan1, lib1));
}
}
@@ -263,34 +274,13 @@
const Type& bool_type_obj = Api::UnwrapTypeHandle(isolate, type);
EXPECT(bool_type_obj.raw() == Type::BoolType());
- // Errors propagate.
- Dart_Handle error = Dart_NewApiError("MyError");
- Dart_Handle error_type = Dart_InstanceGetType(error);
- EXPECT_ERROR(error_type, "MyError");
-
- // Get the handle from a non-instance handle
- Dart_Handle obj = Api::NewHandle(isolate,
- isolate->object_store()->type_class());
- Dart_Handle type_type = Dart_InstanceGetType(obj);
- EXPECT_ERROR(type_type,
- "Dart_InstanceGetType expects argument 'instance' to be of "
- "type Instance.");
-}
-
-
-TEST_CASE(InstanceGetClass) {
- // Get the handle from a valid instance handle.
- Dart_Handle instance = Dart_True();
- Dart_Handle cls = Dart_InstanceGetClass(instance);
- EXPECT_VALID(cls);
- EXPECT(Dart_IsClass(cls));
- Dart_Handle cls_name = Dart_ClassName(cls);
+ Dart_Handle cls_name = Dart_TypeName(type);
EXPECT_VALID(cls_name);
const char* cls_name_cstr = "";
EXPECT_VALID(Dart_StringToCString(cls_name, &cls_name_cstr));
EXPECT_STREQ("bool", cls_name_cstr);
- Dart_Handle qual_cls_name = Dart_QualifiedClassName(cls);
+ Dart_Handle qual_cls_name = Dart_QualifiedTypeName(type);
EXPECT_VALID(qual_cls_name);
const char* qual_cls_name_cstr = "";
EXPECT_VALID(Dart_StringToCString(qual_cls_name, &qual_cls_name_cstr));
@@ -298,14 +288,15 @@
// Errors propagate.
Dart_Handle error = Dart_NewApiError("MyError");
- Dart_Handle error_cls = Dart_InstanceGetClass(error);
- EXPECT_ERROR(error_cls, "MyError");
+ Dart_Handle error_type = Dart_InstanceGetType(error);
+ EXPECT_ERROR(error_type, "MyError");
- // Get the handle from a non-instance handle
- ASSERT(Dart_IsClass(cls));
- Dart_Handle cls_cls = Dart_InstanceGetClass(cls);
- EXPECT_ERROR(cls_cls,
- "Dart_InstanceGetClass expects argument 'instance' to be of "
+ // Get the handle from a non-instance handle.
+ Dart_Handle dart_core = NewString("dart:core");
+ Dart_Handle obj = Dart_LookupLibrary(dart_core);
+ Dart_Handle type_type = Dart_InstanceGetType(obj);
+ EXPECT_ERROR(type_type,
+ "Dart_InstanceGetType expects argument 'instance' to be of "
"type Instance.");
}
@@ -2725,7 +2716,7 @@
Dart_Handle tmp = (handle); \
EXPECT_VALID(tmp); \
EXPECT(Dart_IsClass(tmp)); \
- Dart_Handle intf_name = Dart_ClassName(tmp); \
+ Dart_Handle intf_name = Dart_TypeName(tmp); \
EXPECT_VALID(intf_name); \
const char* intf_name_cstr = ""; \
EXPECT_VALID(Dart_StringToCString(intf_name, &intf_name_cstr)); \
@@ -5754,9 +5745,12 @@
const char* kScriptChars =
"import 'dart:isolate';\n"
"void callPort(SendPort port) {\n"
- " port.call(null).then((message) {\n"
- " throw new Exception(message);\n"
- " });\n"
+ " var receivePort = new ReceivePort();\n"
+ " port.send(null, receivePort.toSendPort());\n"
+ " receivePort.receive((message, _) {\n"
+ " receivePort.close();\n"
+ " throw new Exception(message);\n"
+ " });\n"
"}\n";
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
Dart_EnterScope();
@@ -5818,7 +5812,10 @@
"\n"
"void main(exc_child, exc_parent) {\n"
" var port = spawnFunction(entry);\n"
- " port.call(exc_child).then((message) {\n"
+ " var receivePort = new ReceivePort();\n"
+ " port.send(exc_child, receivePort.toSendPort());\n"
+ " receivePort.receive((message, _) {\n"
+ " receivePort.close();\n"
" if (message != 'hello') throw new Exception('ShouldNotHappen');\n"
" if (exc_parent) throw new Exception('MakeParentExit');\n"
" });\n"
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 9e02f77..66930ed 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -102,8 +102,7 @@
// Compute line number lazily since it causes scanning of the script.
if (line_number_ < 0) {
const Script& script = Script::Handle(SourceCode());
- intptr_t ignore_column;
- script.GetTokenLocation(token_pos_, &line_number_, &ignore_column);
+ script.GetTokenLocation(token_pos_, &line_number_, NULL);
}
return line_number_;
}
@@ -280,8 +279,7 @@
// Compute line number lazily since it causes scanning of the script.
if ((line_number_ < 0) && (TokenPos() >= 0)) {
const Script& script = Script::Handle(SourceScript());
- intptr_t ignore_column;
- script.GetTokenLocation(TokenPos(), &line_number_, &ignore_column);
+ script.GetTokenLocation(TokenPos(), &line_number_, NULL);
}
return line_number_;
}
@@ -664,8 +662,7 @@
// Compute line number lazily since it causes scanning of the script.
if (line_number_ < 0) {
const Script& script = Script::Handle(SourceCode());
- intptr_t ignore_column;
- script.GetTokenLocation(token_pos_, &line_number_, &ignore_column);
+ script.GetTokenLocation(token_pos_, &line_number_, NULL);
}
return line_number_;
}
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 65eedb6..130decd 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -459,19 +459,12 @@
DART_EXPORT Dart_Handle Dart_GetStaticFields(Dart_Handle target) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
- // For backwards compatibility we allow class objects to be passed in
- // for now. This needs to be removed once all code that uses class
- // objects is removed.
- Class& cls = Class::Handle();
- if (obj.IsType()) {
- cls = Type::Cast(obj).type_class();
- } else if (obj.IsClass()) {
- cls = Class::Cast(obj).raw();
- } else {
+ const Type& type_obj = Api::UnwrapTypeHandle(isolate, target);
+ if (type_obj.IsNull()) {
return Api::NewError("%s expects argument 'target' to be a type",
CURRENT_FUNC);
}
+ const Class& cls = Class::Handle(isolate, type_obj.type_class());
return Api::NewHandle(isolate, isolate->debugger()->GetStaticFields(cls));
}
@@ -514,10 +507,11 @@
CURRENT_FUNC);
}
UNWRAP_AND_CHECK_PARAM(String, expr, expr_in);
- if (target.IsInstance()) {
+ if (target.IsType()) {
+ const Class& cls = Class::Handle(isolate, Type::Cast(target).type_class());
+ return Api::NewHandle(isolate, cls.Evaluate(expr));
+ } else if (target.IsInstance()) {
return Api::NewHandle(isolate, Instance::Cast(target).Evaluate(expr));
- } else if (target.IsClass()) {
- return Api::NewHandle(isolate, Class::Cast(target).Evaluate(expr));
} else if (target.IsLibrary()) {
return Api::NewHandle(isolate, Library::Cast(target).Evaluate(expr));
}
@@ -529,7 +523,7 @@
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
UNWRAP_AND_CHECK_PARAM(Instance, obj, object_in);
- return Api::NewHandle(isolate, obj.clazz());
+ return Api::NewHandle(isolate, obj.GetType());
}
@@ -555,14 +549,6 @@
}
-DART_EXPORT Dart_Handle Dart_GetSuperclass(Dart_Handle cls_in) {
- Isolate* isolate = Isolate::Current();
- DARTSCOPE(isolate);
- UNWRAP_AND_CHECK_PARAM(Class, cls, cls_in);
- return Api::NewHandle(isolate, cls.SuperClass());
-}
-
-
DART_EXPORT Dart_Handle Dart_GetSupertype(Dart_Handle type_in) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 2426b3f..d73e812 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -963,7 +963,7 @@
EXPECT_STREQ("blah blah", value);
// Check static field of B's superclass.
- Dart_Handle class_A = Dart_GetSuperclass(class_B);
+ Dart_Handle class_A = Dart_GetSupertype(class_B);
EXPECT_VALID(class_A);
EXPECT(!Dart_IsNull(class_A));
fields = Dart_GetStaticFields(class_A);
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index e0a71b0..0f6dce3 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -38,11 +38,28 @@
licm_allowed_(true),
use_far_branches_(false),
loop_headers_(NULL),
- loop_invariant_loads_(NULL) {
+ loop_invariant_loads_(NULL),
+ guarded_fields_(builder.guarded_fields()) {
DiscoverBlocks();
}
+void FlowGraph::AddToGuardedFields(
+ ZoneGrowableArray<const Field*>* array,
+ const Field* field) {
+ if ((field->guarded_cid() == kDynamicCid) ||
+ (field->guarded_cid() == kIllegalCid)) {
+ return;
+ }
+ for (intptr_t j = 0; j < array->length(); j++) {
+ if ((*array)[j]->raw() == field->raw()) {
+ return;
+ }
+ }
+ array->Add(field);
+}
+
+
GrowableArray<BlockEntryInstr*>* FlowGraph::codegen_block_order(
bool is_optimized) {
return (is_optimized && FLAG_reorder_basic_blocks)
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 7b4be08be..db384d0 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -197,6 +197,13 @@
bool IsCompiledForOsr() const { return graph_entry()->IsCompiledForOsr(); }
+ static void AddToGuardedFields(ZoneGrowableArray<const Field*>* array,
+ const Field* field);
+
+ ZoneGrowableArray<const Field*>* guarded_fields() const {
+ return guarded_fields_;
+ }
+
private:
friend class IfConverter;
friend class BranchSimplifier;
@@ -269,6 +276,7 @@
ZoneGrowableArray<BlockEntryInstr*>* loop_headers_;
ZoneGrowableArray<BitVector*>* loop_invariant_loads_;
+ ZoneGrowableArray<const Field*>* guarded_fields_;
};
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 42a4ffa..ec2b202 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -45,7 +45,6 @@
FlowGraphBuilder::FlowGraphBuilder(ParsedFunction* parsed_function,
const Array& ic_data_array,
InlineExitCollector* exit_collector,
- GrowableArray<const Field*>* guarded_fields,
intptr_t osr_id)
: parsed_function_(parsed_function),
ic_data_array_(ic_data_array),
@@ -56,7 +55,7 @@
: 0),
num_stack_locals_(parsed_function->num_stack_locals()),
exit_collector_(exit_collector),
- guarded_fields_(guarded_fields),
+ guarded_fields_(new ZoneGrowableArray<const Field*>()),
last_used_block_id_(0), // 0 is used for the graph entry.
context_level_(0),
try_index_(CatchClauseNode::kInvalidTryIndex),
@@ -72,20 +71,6 @@
}
-void FlowGraphBuilder::AddToGuardedFields(const Field& field) const {
- if ((field.guarded_cid() == kDynamicCid) ||
- (field.guarded_cid() == kIllegalCid)) {
- return;
- }
- for (intptr_t j = 0; j < guarded_fields_->length(); j++) {
- if ((*guarded_fields_)[j]->raw() == field.raw()) {
- return;
- }
- }
- guarded_fields_->Add(&field);
-}
-
-
void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) {
ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id());
@@ -2044,14 +2029,8 @@
const Function& function = node->function();
if (function.IsImplicitStaticClosureFunction()) {
- Instance& closure = Instance::ZoneHandle();
- closure ^= function.implicit_static_closure();
- if (closure.IsNull()) {
- ObjectStore* object_store = Isolate::Current()->object_store();
- const Context& context = Context::Handle(object_store->empty_context());
- closure ^= Closure::New(function, context, Heap::kOld);
- function.set_implicit_static_closure(closure);
- }
+ const Instance& closure =
+ Instance::ZoneHandle(function.ImplicitStaticClosure());
ReturnDefinition(new ConstantInstr(closure));
return;
}
@@ -3063,7 +3042,7 @@
(node->field().guarded_cid() == kNullCid)) {
load->set_result_cid(node->field().guarded_cid());
}
- owner()->AddToGuardedFields(node->field());
+ FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field());
}
}
ReturnDefinition(load);
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 2b9f455..5013f3e 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -98,14 +98,13 @@
// Build a flow graph from a parsed function's AST.
-class FlowGraphBuilder: public ZoneAllocated {
+class FlowGraphBuilder: public ValueObject {
public:
// The inlining context is NULL if not inlining. The osr_id is the deopt
// id of the OSR entry or Isolate::kNoDeoptId if not compiling for OSR.
FlowGraphBuilder(ParsedFunction* parsed_function,
const Array& ic_data_array,
InlineExitCollector* exit_collector,
- GrowableArray<const Field*>* guarded_fields,
intptr_t osr_id);
FlowGraph* BuildGraph();
@@ -148,12 +147,10 @@
bool IsInlining() const { return (exit_collector_ != NULL); }
InlineExitCollector* exit_collector() const { return exit_collector_; }
- GrowableArray<const Field*>* guarded_fields() const {
+ ZoneGrowableArray<const Field*>* guarded_fields() const {
return guarded_fields_;
}
- void AddToGuardedFields(const Field& field) const;
-
intptr_t args_pushed() const { return args_pushed_; }
void add_args_pushed(intptr_t n) { args_pushed_ += n; }
@@ -176,7 +173,7 @@
const intptr_t num_non_copied_params_;
const intptr_t num_stack_locals_; // Does not include any parameters.
InlineExitCollector* const exit_collector_;
- GrowableArray<const Field*>* guarded_fields_;
+ ZoneGrowableArray<const Field*>* guarded_fields_;
intptr_t last_used_block_id_;
intptr_t context_level_;
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index f58a97b..83a631b 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -542,19 +542,17 @@
// Build the callee graph.
InlineExitCollector* exit_collector =
new InlineExitCollector(caller_graph_, call);
- GrowableArray<const Field*> inlined_guarded_fields;
- FlowGraphBuilder* builder = new FlowGraphBuilder(parsed_function,
- ic_data_array,
- exit_collector,
- &inlined_guarded_fields,
- Isolate::kNoDeoptId);
- builder->SetInitialBlockId(caller_graph_->max_block_id());
+ FlowGraphBuilder builder(parsed_function,
+ ic_data_array,
+ exit_collector,
+ Isolate::kNoDeoptId);
+ builder.SetInitialBlockId(caller_graph_->max_block_id());
FlowGraph* callee_graph;
{
TimerScope timer(FLAG_compiler_stats,
&CompilerStats::graphinliner_build_timer,
isolate);
- callee_graph = builder->BuildGraph();
+ callee_graph = builder.BuildGraph();
}
// The parameter stubs are a copy of the actual arguments providing
@@ -671,8 +669,9 @@
// When inlined, we add the guarded fields of the callee to the caller's
// list of guarded fields.
- for (intptr_t i = 0; i < inlined_guarded_fields.length(); ++i) {
- caller_graph_->builder().AddToGuardedFields(*inlined_guarded_fields[i]);
+ for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) {
+ FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(),
+ (*callee_graph->guarded_fields())[i]);
}
TRACE_INLINING(OS::Print(" Success\n"));
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 44aad69..7da716a 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1573,6 +1573,7 @@
void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
ASSERT(call->HasICData());
const ICData& ic_data = *call->ic_data();
+ ASSERT(ic_data.HasOneTarget());
Function& target = Function::Handle();
GrowableArray<intptr_t> class_ids;
ic_data.GetCheckAt(0, &class_ids, &target);
@@ -1596,7 +1597,7 @@
if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
load->set_result_cid(field.guarded_cid());
}
- flow_graph_->builder().AddToGuardedFields(field);
+ FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
}
// Discard the environment from the original instruction because the load
@@ -1791,51 +1792,21 @@
// No type feedback collected.
return false;
}
- Function& target = Function::Handle(ic_data.GetTargetAt(0));
- if (target.kind() == RawFunction::kImplicitGetter) {
- if (!ic_data.HasOneTarget()) {
- // TODO(srdjan): Implement for mutiple targets.
- return false;
- }
- InlineImplicitInstanceGetter(call);
- return true;
- } else if (target.kind() == RawFunction::kMethodExtractor) {
- return false;
- } else if (target.kind() == RawFunction::kNoSuchMethodDispatcher) {
+
+ if (!ic_data.HasOneTarget()) {
+ // Polymorphic sites are inlined like normal methods by conventional
+ // inlining in FlowGraphInliner.
return false;
}
- // Not an implicit getter.
- MethodRecognizer::Kind recognized_kind =
- MethodRecognizer::RecognizeKind(target);
-
- // VM objects length getter.
- switch (recognized_kind) {
- case MethodRecognizer::kFloat32x4ShuffleX:
- case MethodRecognizer::kFloat32x4ShuffleY:
- case MethodRecognizer::kFloat32x4ShuffleZ:
- case MethodRecognizer::kFloat32x4ShuffleW:
- case MethodRecognizer::kFloat32x4GetSignMask:
- if (!ic_data.HasReceiverClassId(kFloat32x4Cid) ||
- !ic_data.HasOneTarget()) {
- return false;
- }
- return InlineFloat32x4Getter(call, recognized_kind);
- case MethodRecognizer::kUint32x4GetFlagX:
- case MethodRecognizer::kUint32x4GetFlagY:
- case MethodRecognizer::kUint32x4GetFlagZ:
- case MethodRecognizer::kUint32x4GetFlagW:
- case MethodRecognizer::kUint32x4GetSignMask: {
- if (!ic_data.HasReceiverClassId(kUint32x4Cid) ||
- !ic_data.HasOneTarget()) {
- return false;
- }
- return InlineUint32x4Getter(call, recognized_kind);
- }
- default:
- break;
+ const Function& target = Function::Handle(ic_data.GetTargetAt(0));
+ if (target.kind() != RawFunction::kImplicitGetter) {
+ // Non-implicit getters are inlined like normal methods by conventional
+ // inlining in FlowGraphInliner.
+ return false;
}
- return false;
+ InlineImplicitInstanceGetter(call);
+ return true;
}
@@ -2212,6 +2183,12 @@
call->deopt_id());
ReplaceCall(call, con);
return true;
+ } else if (recognized_kind == MethodRecognizer::kFloat32x4FromUint32x4Bits) {
+ Uint32x4ToFloat32x4Instr* cast =
+ new Uint32x4ToFloat32x4Instr(new Value(call->ArgumentAt(1)),
+ call->deopt_id());
+ ReplaceCall(call, cast);
+ return true;
}
return false;
}
@@ -2232,6 +2209,12 @@
call->deopt_id());
ReplaceCall(call, con);
return true;
+ } else if (recognized_kind == MethodRecognizer::kUint32x4FromFloat32x4Bits) {
+ Float32x4ToUint32x4Instr* cast =
+ new Float32x4ToUint32x4Instr(new Value(call->ArgumentAt(1)),
+ call->deopt_id());
+ ReplaceCall(call, cast);
+ return true;
}
return false;
}
@@ -2245,6 +2228,15 @@
}
ASSERT(call->HasICData());
switch (recognized_kind) {
+ case MethodRecognizer::kFloat32x4ShuffleX:
+ case MethodRecognizer::kFloat32x4ShuffleY:
+ case MethodRecognizer::kFloat32x4ShuffleZ:
+ case MethodRecognizer::kFloat32x4ShuffleW:
+ case MethodRecognizer::kFloat32x4GetSignMask:
+ ASSERT(call->ic_data()->HasReceiverClassId(kFloat32x4Cid));
+ ASSERT(call->ic_data()->HasOneTarget());
+ return InlineFloat32x4Getter(call, recognized_kind);
+
case MethodRecognizer::kFloat32x4Equal:
case MethodRecognizer::kFloat32x4GreaterThan:
case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
@@ -2393,20 +2385,6 @@
ReplaceCall(call, clamp);
return true;
}
- case MethodRecognizer::kFloat32x4ToUint32x4: {
- Definition* left = call->ArgumentAt(0);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
- Float32x4ToUint32x4Instr* cast =
- new Float32x4ToUint32x4Instr(new Value(left), call->deopt_id());
- ReplaceCall(call, cast);
- return true;
- }
case MethodRecognizer::kFloat32x4Shuffle: {
return InlineFloat32x4Getter(call, recognized_kind);
}
@@ -2424,6 +2402,15 @@
}
ASSERT(call->HasICData());
switch (recognized_kind) {
+ case MethodRecognizer::kUint32x4GetFlagX:
+ case MethodRecognizer::kUint32x4GetFlagY:
+ case MethodRecognizer::kUint32x4GetFlagZ:
+ case MethodRecognizer::kUint32x4GetFlagW:
+ case MethodRecognizer::kUint32x4GetSignMask:
+ ASSERT(call->ic_data()->HasReceiverClassId(kUint32x4Cid));
+ ASSERT(call->ic_data()->HasOneTarget());
+ return InlineUint32x4Getter(call, recognized_kind);
+
case MethodRecognizer::kUint32x4Select: {
Definition* mask = call->ArgumentAt(0);
Definition* trueValue = call->ArgumentAt(1);
@@ -2443,20 +2430,6 @@
ReplaceCall(call, select);
return true;
}
- case MethodRecognizer::kUint32x4ToUint32x4: {
- Definition* left = call->ArgumentAt(0);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
- Uint32x4ToFloat32x4Instr* cast =
- new Uint32x4ToFloat32x4Instr(new Value(left), call->deopt_id());
- ReplaceCall(call, cast);
- return true;
- }
case MethodRecognizer::kUint32x4WithFlagX:
case MethodRecognizer::kUint32x4WithFlagY:
case MethodRecognizer::kUint32x4WithFlagZ:
@@ -2635,9 +2608,27 @@
call->deopt_id());
InsertBefore(call, len_in_bytes, call->env(), Definition::kValue);
- // Check byte_index < len_in_bytes.
+ ConstantInstr* length_adjustment =
+ flow_graph()->GetConstant(Smi::Handle(Smi::New(
+ FlowGraphCompiler::ElementSizeFor(view_cid) - 1)));
+ // adjusted_length = len_in_bytes - (element_size - 1).
+ BinarySmiOpInstr* adjusted_length =
+ new BinarySmiOpInstr(Token::kSUB,
+ new Value(len_in_bytes),
+ new Value(length_adjustment),
+ call->deopt_id());
+ InsertBefore(call, adjusted_length, call->env(), Definition::kValue);
+ // Check adjusted_length > 0.
+ ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0)));
InsertBefore(call,
- new CheckArrayBoundInstr(new Value(len_in_bytes),
+ new CheckArrayBoundInstr(new Value(adjusted_length),
+ new Value(zero),
+ call->deopt_id()),
+ call->env(),
+ Definition::kEffect);
+ // Check 0 <= byte_index < adjusted_length.
+ InsertBefore(call,
+ new CheckArrayBoundInstr(new Value(adjusted_length),
new Value(byte_index),
call->deopt_id()),
call->env(),
@@ -2960,7 +2951,8 @@
ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
(unary_ic_data.num_args_tested() == 1));
if (FLAG_enable_type_checks) {
- // TODO(srdjan): Add assignable check node if --enable_type_checks.
+ // Checked mode setters are inlined like normal methods by conventional
+ // inlining.
return false;
}
@@ -2970,15 +2962,15 @@
return false;
}
if (!unary_ic_data.HasOneTarget()) {
- // TODO(srdjan): Implement when not all targets are the same.
+ // Polymorphic sites are inlined like normal method calls by conventional
+ // inlining.
return false;
}
Function& target = Function::Handle();
intptr_t class_id;
unary_ic_data.GetOneClassCheckAt(0, &class_id, &target);
if (target.kind() != RawFunction::kImplicitSetter) {
- // Not an implicit setter.
- // TODO(srdjan): Inline special setters.
+ // Non-implicit setter are inlined like normal method calls.
return false;
}
// Inline implicit instance setter.
@@ -6429,11 +6421,17 @@
const Integer& left_int = Integer::Cast(left);
const Integer& right_int = Integer::Cast(right);
switch (op_kind) {
+ case Token::kTRUNCDIV:
+ case Token::kMOD:
+ // Check right value for zero.
+ if (right_int.AsInt64Value() == 0) {
+ SetValue(instr, non_constant_);
+ break;
+ }
+ // Fall through.
case Token::kADD:
case Token::kSUB:
- case Token::kMUL:
- case Token::kTRUNCDIV:
- case Token::kMOD: {
+ case Token::kMUL: {
Instance& result = Integer::ZoneHandle(
left_int.ArithmeticOp(op_kind, right_int));
result = result.CheckAndCanonicalize(NULL);
diff --git a/runtime/vm/heap_histogram.cc b/runtime/vm/heap_histogram.cc
index 8f6123d..a2043a2 100644
--- a/runtime/vm/heap_histogram.cc
+++ b/runtime/vm/heap_histogram.cc
@@ -78,7 +78,12 @@
int ObjectHistogram::compare(const Element** a, const Element** b) {
- return (*b)->size_ - (*a)->size_;
+ // Be careful to return a 32bit integer.
+ intptr_t a_size = (*a)->size_;
+ intptr_t b_size = (*b)->size_;
+ if (a_size > b_size) return -1;
+ if (a_size < b_size) return 1;
+ return 0;
}
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 84e9f9d..766fcaa 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -83,12 +83,14 @@
V(::, sqrt, MathSqrt, 465520247) \
V(::, sin, MathSin, 730107143) \
V(::, cos, MathCos, 1282146521) \
- V(::, min, MathMin, 1602283410) \
- V(::, max, MathMax, 997766696) \
+ V(::, min, MathMin, 1830216388) \
+ V(::, max, MathMax, 234565686) \
V(::, _doublePow, MathDoublePow, 1728171041) \
V(Float32x4, Float32x4., Float32x4Constructor, 786169160) \
V(Float32x4, Float32x4.zero, Float32x4Zero, 1589383280) \
- V(Float32x4, Float32x4.splat, Float32x4Splat, 62513275) \
+ V(Float32x4, Float32x4.splat, Float32x4Splat, 62513275) \
+ V(Float32x4, Float32x4.fromUint32x4Bits, Float32x4FromUint32x4Bits, \
+ 770033146) \
V(_Float32x4, shuffle, Float32x4Shuffle, 1178727105) \
V(_Float32x4, get:x, Float32x4ShuffleX, 1351717838) \
V(_Float32x4, get:y, Float32x4ShuffleY, 217386410) \
@@ -114,13 +116,14 @@
V(_Float32x4, withY, Float32x4WithY, 1806065938) \
V(_Float32x4, withZ, Float32x4WithZ, 320659034) \
V(_Float32x4, withW, Float32x4WithW, 1108437255) \
- V(_Float32x4, _toUint32x4, Float32x4ToUint32x4, 754564339) \
V(_Float32x4, withZWInXY, Float32x4WithZWInXY, 1198101679) \
V(_Float32x4, interleaveXY, Float32x4InterleaveXY, 2001324072) \
V(_Float32x4, interleaveZW, Float32x4InterleaveZW, 928280031) \
V(_Float32x4, interleaveXYPairs, Float32x4InterleaveXYPairs, 1046078993) \
V(_Float32x4, interleaveZWPairs, Float32x4InterleaveZWPairs, 1001751955) \
V(Uint32x4, Uint32x4.bool, Uint32x4BoolConstructor, 517444095) \
+ V(Uint32x4, Uint32x4.fromFloat32x4Bits, Uint32x4FromFloat32x4Bits, \
+ 1080034855) \
V(_Uint32x4, get:flagX, Uint32x4GetFlagX, 1674696792) \
V(_Uint32x4, get:flagY, Uint32x4GetFlagY, 2013200152) \
V(_Uint32x4, get:flagZ, Uint32x4GetFlagZ, 944733935) \
@@ -131,7 +134,6 @@
V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 830610988) \
V(_Uint32x4, withFlagZ, Uint32x4WithFlagZ, 1714792414) \
V(_Uint32x4, withFlagW, Uint32x4WithFlagW, 1516924162) \
- V(_Uint32x4, _toFloat32x4, Uint32x4ToUint32x4, 2054503505) \
V(_ObjectArray, [], ObjectArrayGetIndexed, 544020319) \
V(_ImmutableArray, [], ImmutableArrayGetIndexed, 1345387065) \
V(_GrowableObjectArray, [], GrowableArrayGetIndexed, 951312767) \
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index de1647a..096ff06 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -4228,19 +4228,18 @@
Register temp = locs()->temp(0).reg();
XmmRegister zero_temp = locs()->temp(1).fpu_reg();
- Label check_base_is_one;
// Check if exponent is 0.0 -> return 1.0;
__ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP);
__ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
__ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP);
__ movsd(result, FieldAddress(temp, Double::value_offset()));
// 'result' contains 1.0.
+ Label exp_is_nan;
__ comisd(exp, zero_temp);
- __ j(PARITY_EVEN, &check_base_is_one, Assembler::kNearJump); // NaN.
+ __ j(PARITY_EVEN, &exp_is_nan, Assembler::kNearJump); // NaN.
__ j(EQUAL, &skip_call, Assembler::kNearJump); // exp is 0, result is 1.0.
Label base_is_nan;
- __ Bind(&check_base_is_one);
// Checks if base == 1.0.
__ comisd(base, result);
__ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump);
@@ -4251,7 +4250,14 @@
// Returns NaN.
__ movsd(result, base);
__ jmp(&skip_call, Assembler::kNearJump);
- // exp is Nan case is handled correctly in the C-library.
+
+ __ Bind(&exp_is_nan);
+ // Checks if base == 1.0.
+ __ comisd(base, result);
+ __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump);
+ __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0
+ __ movsd(result, exp); // result is NaN
+ __ jmp(&skip_call, Assembler::kNearJump);
}
__ Bind(&do_call);
__ CallRuntime(TargetFunction(), InputCount());
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index f4863d4..5d12dc6 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -785,9 +785,8 @@
PrintInvokedFunctions();
}
- if (FLAG_print_coverage) {
- CodeCoverage::Print(this);
- }
+ // Write out the coverage data if collection has been enabled.
+ CodeCoverage::Write(this);
// Finalize any weak persistent handles with a non-null referent.
FinalizeWeakPersistentHandlesVisitor visitor;
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index d970968..6565d38 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -28,7 +28,7 @@
" try {\n"
" spawnFunction(entry);\n"
" } catch (e) {\n"
- " throw;\n"
+ " rethrow;\n"
" }\n"
" return 0;\n"
"}\n";
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index ebbd8ae..0a544d5 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -19,6 +19,7 @@
explicit JSONStream(intptr_t buf_size = 256);
~JSONStream();
+ TextBuffer* buffer() { return &buffer_; }
const char* ToCString() { return buffer_.buf(); }
void SetArguments(const char** arguments, intptr_t num_arguments);
diff --git a/runtime/vm/mirrors_api_impl.cc b/runtime/vm/mirrors_api_impl.cc
index 673621d..caa1346 100644
--- a/runtime/vm/mirrors_api_impl.cc
+++ b/runtime/vm/mirrors_api_impl.cc
@@ -22,20 +22,20 @@
// --- Classes and Interfaces Reflection ---
-DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle object) {
+DART_EXPORT Dart_Handle Dart_TypeName(Dart_Handle object) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object));
- if (obj.IsType() || obj.IsClass()) {
- const Class& cls = (obj.IsType()) ?
- Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj);
+ if (obj.IsType()) {
+ const Class& cls = Class::Handle(Type::Cast(obj).type_class());
return Api::NewHandle(isolate, cls.UserVisibleName());
} else {
RETURN_TYPE_ERROR(isolate, object, Class/Type);
}
}
-DART_EXPORT Dart_Handle Dart_QualifiedClassName(Dart_Handle object) {
+
+DART_EXPORT Dart_Handle Dart_QualifiedTypeName(Dart_Handle object) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object));
@@ -48,6 +48,7 @@
}
}
+
// --- Function and Variable Reflection ---
// Outside of the vm, we expose setter names with a trailing '='.
@@ -75,12 +76,8 @@
Function& func = Function::Handle();
String& name = String::Handle();
- if (obj.IsType() || obj.IsClass()) {
- // For backwards compatibility we allow class objects to be passed in
- // for now. This needs to be removed once all code that uses class
- // objects to invoke Dart_Invoke is removed.
- const Class& cls = (obj.IsType()) ?
- Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj);
+ if (obj.IsType()) {
+ const Class& cls = Class::Handle(Type::Cast(obj).type_class());
const Error& error = Error::Handle(isolate, cls.EnsureIsFinalized(isolate));
if (!error.IsNull()) {
return Api::NewHandle(isolate, error.raw());
@@ -141,12 +138,8 @@
Function& func = Function::Handle(isolate);
String& tmp_name = String::Handle(isolate);
- if (obj.IsType() || obj.IsClass()) {
- // For backwards compatibility we allow class objects to be passed in
- // for now. This needs to be removed once all code that uses class
- // objects to invoke Dart_Invoke is removed.
- const Class& cls = (obj.IsType()) ?
- Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj);
+ if (obj.IsType()) {
+ const Class& cls = Class::Handle(Type::Cast(obj).type_class());
// Case 1. Lookup the unmodified function name.
func = cls.LookupFunctionAllowPrivate(func_name);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 85f0f08..d7ad1f5 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -64,7 +64,7 @@
DECLARE_FLAG(bool, trace_deoptimization);
DECLARE_FLAG(bool, trace_deoptimization_verbose);
DECLARE_FLAG(bool, verbose_stacktrace);
-DECLARE_FLAG(bool, print_coverage);
+DECLARE_FLAG(charp, coverage_dir);
static const char* kGetterPrefix = "get:";
static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix);
@@ -163,6 +163,29 @@
V(CoreLibrary, int, _parse) \
V(CoreLibrary, StackTrace, _setupFullStackTrace) \
V(CoreLibrary, _OneByteString, _setAt) \
+ V(TypedDataLibrary, _TypedList, _getInt8) \
+ V(TypedDataLibrary, _TypedList, _setInt8) \
+ V(TypedDataLibrary, _TypedList, _getUint8) \
+ V(TypedDataLibrary, _TypedList, _setUint8) \
+ V(TypedDataLibrary, _TypedList, _getInt16) \
+ V(TypedDataLibrary, _TypedList, _setInt16) \
+ V(TypedDataLibrary, _TypedList, _getUint16) \
+ V(TypedDataLibrary, _TypedList, _setUint16) \
+ V(TypedDataLibrary, _TypedList, _getInt32) \
+ V(TypedDataLibrary, _TypedList, _setInt32) \
+ V(TypedDataLibrary, _TypedList, _getUint32) \
+ V(TypedDataLibrary, _TypedList, _setUint32) \
+ V(TypedDataLibrary, _TypedList, _getInt64) \
+ V(TypedDataLibrary, _TypedList, _setInt64) \
+ V(TypedDataLibrary, _TypedList, _getUint64) \
+ V(TypedDataLibrary, _TypedList, _setUint64) \
+ V(TypedDataLibrary, _TypedList, _getFloat32) \
+ V(TypedDataLibrary, _TypedList, _setFloat32) \
+ V(TypedDataLibrary, _TypedList, _getFloat64) \
+ V(TypedDataLibrary, _TypedList, _setFloat64) \
+ V(TypedDataLibrary, _TypedList, _getFloat32x4) \
+ V(TypedDataLibrary, _TypedList, _setFloat32x4) \
+
static void MarkFunctionAsInvisible(const Library& lib,
@@ -1705,7 +1728,6 @@
type_params ^= cls.type_parameters();
num_type_args += type_params.Length();
}
-
// Super type of Object class is null.
if (cls.super_type() == AbstractType::null() ||
cls.super_type() == isolate->object_store()->object_type()) {
@@ -1733,10 +1755,7 @@
if (super_type() == AbstractType::null()) {
return Class::null();
}
- Isolate* isolate = Isolate::Current();
- ReusableHandleScope reused_handles(isolate);
- AbstractType& sup_type = reused_handles.AbstractTypeHandle();
- sup_type ^= super_type();
+ const AbstractType& sup_type = AbstractType::Handle(super_type());
return sup_type.type_class();
}
@@ -4166,7 +4185,8 @@
bool Function::is_optimizable() const {
- if (FLAG_print_coverage) {
+ if (FLAG_coverage_dir != NULL) {
+ // Do not optimize if collecting coverage data.
return false;
}
if (OptimizableBit::decode(raw_ptr()->kind_tag_) &&
@@ -4833,46 +4853,21 @@
}
-RawString* Function::BuildSignature(
- bool instantiate,
- NameVisibility name_visibility,
- const AbstractTypeArguments& instantiator) const {
+RawString* Function::UserVisibleFormalParameters() const {
const GrowableObjectArray& pieces =
GrowableObjectArray::Handle(GrowableObjectArray::New());
- String& name = String::Handle();
- if (!instantiate && !is_static() && (name_visibility == kInternalName)) {
- // Prefix the signature with its signature class and type parameters, if any
- // (e.g. "Map<K, V>(K) => bool"). In case of a function type alias, the
- // signature class name is the alias name.
- // The signature of static functions cannot be type parameterized.
- const Class& function_class = Class::Handle(Owner());
- ASSERT(!function_class.IsNull());
- const TypeArguments& type_parameters = TypeArguments::Handle(
- function_class.type_parameters());
- if (!type_parameters.IsNull()) {
- const String& function_class_name = String::Handle(function_class.Name());
- pieces.Add(function_class_name);
- const intptr_t num_type_parameters = type_parameters.Length();
- pieces.Add(Symbols::LAngleBracket());
- TypeParameter& type_parameter = TypeParameter::Handle();
- AbstractType& bound = AbstractType::Handle();
- for (intptr_t i = 0; i < num_type_parameters; i++) {
- type_parameter ^= type_parameters.TypeAt(i);
- name = type_parameter.name();
- pieces.Add(name);
- bound = type_parameter.bound();
- if (!bound.IsNull() && !bound.IsObjectType()) {
- pieces.Add(Symbols::SpaceExtendsSpace());
- name = bound.BuildName(name_visibility);
- pieces.Add(name);
- }
- if (i < num_type_parameters - 1) {
- pieces.Add(Symbols::CommaSpace());
- }
- }
- pieces.Add(Symbols::RAngleBracket());
- }
- }
+ const TypeArguments& instantiator = TypeArguments::Handle();
+ BuildSignatureParameters(false, kUserVisibleName, instantiator, pieces);
+ const Array& strings = Array::Handle(Array::MakeArray(pieces));
+ return String::ConcatAll(strings);
+}
+
+
+void Function::BuildSignatureParameters(
+ bool instantiate,
+ NameVisibility name_visibility,
+ const AbstractTypeArguments& instantiator,
+ const GrowableObjectArray& pieces) const {
AbstractType& param_type = AbstractType::Handle();
const intptr_t num_params = NumParameters();
const intptr_t num_fixed_params = num_fixed_parameters();
@@ -4880,7 +4875,7 @@
const intptr_t num_opt_named_params = NumOptionalNamedParameters();
const intptr_t num_opt_params = num_opt_pos_params + num_opt_named_params;
ASSERT((num_fixed_params + num_opt_params) == num_params);
- pieces.Add(Symbols::LParen());
+ String& name = String::Handle();
intptr_t i = 0;
if (name_visibility == kUserVisibleName) {
// Hide implicit parameters.
@@ -4930,6 +4925,66 @@
pieces.Add(Symbols::RBrace());
}
}
+}
+
+
+RawInstance* Function::ImplicitStaticClosure() const {
+ if (implicit_static_closure() == Instance::null()) {
+ ObjectStore* object_store = Isolate::Current()->object_store();
+ const Context& context = Context::Handle(object_store->empty_context());
+ const Instance& closure =
+ Instance::Handle(Closure::New(*this, context, Heap::kOld));
+ set_implicit_static_closure(closure);
+ }
+ return implicit_static_closure();
+}
+
+
+RawString* Function::BuildSignature(
+ bool instantiate,
+ NameVisibility name_visibility,
+ const AbstractTypeArguments& instantiator) const {
+ const GrowableObjectArray& pieces =
+ GrowableObjectArray::Handle(GrowableObjectArray::New());
+ String& name = String::Handle();
+ if (!instantiate && !is_static() && (name_visibility == kInternalName)) {
+ // Prefix the signature with its signature class and type parameters, if any
+ // (e.g. "Map<K, V>(K) => bool"). In case of a function type alias, the
+ // signature class name is the alias name.
+ // The signature of static functions cannot be type parameterized.
+ const Class& function_class = Class::Handle(Owner());
+ ASSERT(!function_class.IsNull());
+ const TypeArguments& type_parameters = TypeArguments::Handle(
+ function_class.type_parameters());
+ if (!type_parameters.IsNull()) {
+ const String& function_class_name = String::Handle(function_class.Name());
+ pieces.Add(function_class_name);
+ const intptr_t num_type_parameters = type_parameters.Length();
+ pieces.Add(Symbols::LAngleBracket());
+ TypeParameter& type_parameter = TypeParameter::Handle();
+ AbstractType& bound = AbstractType::Handle();
+ for (intptr_t i = 0; i < num_type_parameters; i++) {
+ type_parameter ^= type_parameters.TypeAt(i);
+ name = type_parameter.name();
+ pieces.Add(name);
+ bound = type_parameter.bound();
+ if (!bound.IsNull() && !bound.IsObjectType()) {
+ pieces.Add(Symbols::SpaceExtendsSpace());
+ name = bound.BuildName(name_visibility);
+ pieces.Add(name);
+ }
+ if (i < num_type_parameters - 1) {
+ pieces.Add(Symbols::CommaSpace());
+ }
+ }
+ pieces.Add(Symbols::RAngleBracket());
+ }
+ }
+ pieces.Add(Symbols::LParen());
+ BuildSignatureParameters(instantiate,
+ name_visibility,
+ instantiator,
+ pieces);
pieces.Add(Symbols::RParenArrow());
AbstractType& res_type = AbstractType::Handle(result_type());
if (instantiate && !res_type.IsInstantiated()) {
@@ -5598,6 +5653,13 @@
}
+bool Field::IsUninitialized() const {
+ const Instance& value = Instance::Handle(raw_ptr()->value_);
+ ASSERT(value.raw() != Object::transition_sentinel().raw());
+ return value.raw() == Object::sentinel().raw();
+}
+
+
void Field::UpdateCid(intptr_t cid) const {
if (guarded_cid() == kIllegalCid) {
// Field is assigned first time.
@@ -5748,7 +5810,7 @@
RawString* TokenStream::GenerateSource() const {
- Iterator iterator(*this, 0);
+ Iterator iterator(*this, 0, Iterator::kAllTokens);
const ExternalTypedData& data = ExternalTypedData::Handle(GetStream());
const GrowableObjectArray& literals =
GrowableObjectArray::Handle(GrowableObjectArray::New(data.Length()));
@@ -5809,35 +5871,47 @@
const String* separator = NULL;
switch (curr) {
case Token::kLBRACE:
- indent++;
- separator = &Symbols::NewLine();
- break;
case Token::kRBRACE:
- if (indent == 0) {
- separator = &Symbols::TwoNewlines();
- } else {
- separator = &Symbols::NewLine();
- }
- break;
- case Token::kSEMICOLON:
- separator = &Symbols::NewLine();
- break;
case Token::kPERIOD:
- case Token::kLPAREN:
case Token::kLBRACK:
case Token::kINTERPOL_VAR:
case Token::kINTERPOL_START:
case Token::kINTERPOL_END:
+ case Token::kBIT_NOT:
+ break;
+ // In case we see an opening parentheses '(' we increase the indent to
+ // align multi-line parameters accordingly. The indent will be removed as
+ // soon as we see the matching closing parentheses ')'.
+ //
+ // Example:
+ // SomeVeryLongMethod(
+ // "withVeryLongParameter",
+ // "andAnotherVeryLongParameter",
+ // "andAnotherVeryLongParameter2") { ...
+ case Token::kLPAREN:
+ indent += 2;
+ break;
+ case Token::kRPAREN:
+ indent -= 2;
+ separator = &Symbols::Blank();
+ break;
+ case Token::kNEWLINE:
+ if (prev == Token::kLBRACE) {
+ indent++;
+ }
+ if (next == Token::kRBRACE) {
+ indent--;
+ }
break;
default:
separator = &Symbols::Blank();
break;
}
+
// Determine whether the separation text needs to be updated based on the
// next token.
switch (next) {
case Token::kRBRACE:
- indent--;
break;
case Token::kSEMICOLON:
case Token::kPERIOD:
@@ -5853,27 +5927,41 @@
break;
case Token::kELSE:
separator = &Symbols::Blank();
+ break;
default:
// Do nothing.
break;
}
+
// Update the few cases where both tokens need to be taken into account.
if (((curr == Token::kIF) || (curr == Token::kFOR)) &&
(next == Token::kLPAREN)) {
separator = &Symbols::Blank();
} else if ((curr == Token::kASSIGN) && (next == Token::kLPAREN)) {
separator = &Symbols::Blank();
+ } else if ((curr == Token::kRETURN ||
+ curr == Token::kCONDITIONAL ||
+ Token::IsBinaryOperator(curr) ||
+ Token::IsEqualityOperator(curr)) && (next == Token::kLPAREN)) {
+ separator = &Symbols::Blank();
} else if ((curr == Token::kLBRACE) && (next == Token::kRBRACE)) {
separator = NULL;
+ } else if ((curr == Token::kSEMICOLON) && (next != Token::kNEWLINE)) {
+ separator = &Symbols::Blank();
}
+
+ // Add the separator.
if (separator != NULL) {
literals.Add(*separator);
- if (separator == &Symbols::NewLine()) {
+ }
+
+ // Account for indentation in case we printed a newline.
+ if (curr == Token::kNEWLINE) {
for (int i = 0; i < indent; i++) {
literals.Add(Symbols::TwoSpaces());
}
- }
}
+
// Setup for next iteration.
prev = curr;
curr = next;
@@ -6337,17 +6425,31 @@
void Script::GetTokenLocation(intptr_t token_pos,
intptr_t* line,
intptr_t* column) const {
- const String& src = String::Handle(Source());
+ ASSERT(line != NULL);
const TokenStream& tkns = TokenStream::Handle(tokens());
- intptr_t src_pos = tkns.ComputeSourcePosition(token_pos);
- Scanner scanner(src, Symbols::Empty());
- scanner.ScanTo(src_pos);
- intptr_t relative_line = scanner.CurrentPosition().line;
- *line = relative_line + line_offset();
- *column = scanner.CurrentPosition().column;
- // On the first line of the script we must add the column offset.
- if (relative_line == 1) {
- *column += col_offset();
+ if (column == NULL) {
+ TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
+ intptr_t cur_line = line_offset() + 1;
+ while (tkit.CurrentPosition() < token_pos &&
+ tkit.CurrentTokenKind() != Token::kEOS) {
+ if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
+ cur_line++;
+ }
+ tkit.Advance();
+ }
+ *line = cur_line;
+ } else {
+ const String& src = String::Handle(Source());
+ intptr_t src_pos = tkns.ComputeSourcePosition(token_pos);
+ Scanner scanner(src, Symbols::Empty());
+ scanner.ScanTo(src_pos);
+ intptr_t relative_line = scanner.CurrentPosition().line;
+ *line = relative_line + line_offset();
+ *column = scanner.CurrentPosition().column;
+ // On the first line of the script we must add the column offset.
+ if (relative_line == 1) {
+ *column += col_offset();
+ }
}
}
@@ -6355,18 +6457,48 @@
void Script::TokenRangeAtLine(intptr_t line_number,
intptr_t* first_token_index,
intptr_t* last_token_index) const {
- const String& src = String::Handle(Source());
+ ASSERT(first_token_index != NULL && last_token_index != NULL);
+ ASSERT(line_number > 0);
+ *first_token_index = -1;
+ *last_token_index = -1;
const TokenStream& tkns = TokenStream::Handle(tokens());
line_number -= line_offset();
if (line_number < 1) line_number = 1;
- Scanner scanner(src, Symbols::Empty());
- scanner.TokenRangeAtLine(line_number, first_token_index, last_token_index);
- if (*first_token_index >= 0) {
- *first_token_index = tkns.ComputeTokenPosition(*first_token_index);
+ TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
+ // Scan through the token stream to the required line.
+ intptr_t cur_line = 1;
+ while (cur_line < line_number && tkit.CurrentTokenKind() != Token::kEOS) {
+ if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
+ cur_line++;
+ }
+ tkit.Advance();
}
- if (*last_token_index >= 0) {
- *last_token_index = tkns.ComputeTokenPosition(*last_token_index);
+ if (tkit.CurrentTokenKind() == Token::kEOS) {
+ // End of token stream before reaching required line.
+ return;
}
+ if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
+ // No tokens on the current line. If there is a valid token afterwards, put
+ // it into first_token_index.
+ while (tkit.CurrentTokenKind() == Token::kNEWLINE &&
+ tkit.CurrentTokenKind() != Token::kEOS) {
+ tkit.Advance();
+ }
+ if (tkit.CurrentTokenKind() != Token::kEOS) {
+ *first_token_index = tkit.CurrentPosition();
+ }
+ return;
+ }
+ *first_token_index = tkit.CurrentPosition();
+ // We cannot do "CurrentPosition() - 1" for the last token, because we do not
+ // know whether the previous token is a simple one or not.
+ intptr_t end_pos = *first_token_index;
+ while (tkit.CurrentTokenKind() != Token::kNEWLINE &&
+ tkit.CurrentTokenKind() != Token::kEOS) {
+ end_pos = tkit.CurrentPosition();
+ tkit.Advance();
+ }
+ *last_token_index = end_pos;
}
@@ -10457,6 +10589,24 @@
}
+bool Instance::IsIdenticalTo(const Instance& other) const {
+ if (raw() == other.raw()) return true;
+ if (IsInteger() && other.IsInteger()) {
+ return Equals(other);
+ }
+ if (IsDouble() && other.IsDouble()) {
+ if (Equals(other)) return true;
+ // Check for NaN.
+ const Double& a_double = Double::Cast(*this);
+ const Double& b_double = Double::Cast(other);
+ if (isnan(a_double.value()) && isnan(b_double.value())) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
void Instance::SetNativeField(int index, intptr_t value) const {
ASSERT(IsValidNativeIndex(index));
Object& native_fields = Object::Handle(*NativeFieldsAddr());
@@ -11769,9 +11919,7 @@
RawClass* MixinAppType::MixinAppAt(intptr_t depth) const {
- Class& mixin_app = Class::Handle();
- mixin_app ^= Array::Handle(mixins()).At(depth);
- return mixin_app.raw();
+ return Class::RawCast(Array::Handle(mixins()).At(depth));
}
@@ -14743,7 +14891,8 @@
const Function& function,
const Code& code,
intptr_t frame_index) {
- const char* kFormat = "#%-6d %s (%s:%d:%d)\n";
+ const char* kFormatWithCol = "#%-6d %s (%s:%d:%d)\n";
+ const char* kFormatNoCol = "#%-6d %s (%s:%d)\n";
const intptr_t token_pos = code.GetTokenIndexOfPC(pc);
const Script& script = Script::Handle(isolate, function.script());
const String& function_name =
@@ -14752,19 +14901,32 @@
intptr_t line = -1;
intptr_t column = -1;
if (token_pos >= 0) {
- script.GetTokenLocation(token_pos, &line, &column);
+ if (script.HasSource()) {
+ script.GetTokenLocation(token_pos, &line, &column);
+ } else {
+ script.GetTokenLocation(token_pos, &line, NULL);
+ }
}
- intptr_t len = OS::SNPrint(NULL, 0, kFormat,
- frame_index,
- function_name.ToCString(),
- url.ToCString(),
- line, column);
- char* chars = isolate->current_zone()->Alloc<char>(len + 1);
- OS::SNPrint(chars, (len + 1), kFormat,
- frame_index,
- function_name.ToCString(),
- url.ToCString(),
- line, column);
+ intptr_t len = 0;
+ char* chars = NULL;
+ if (column >= 0) {
+ len = OS::SNPrint(NULL, 0, kFormatWithCol,
+ frame_index, function_name.ToCString(),
+ url.ToCString(), line, column);
+ chars = isolate->current_zone()->Alloc<char>(len + 1);
+ OS::SNPrint(chars, (len + 1), kFormatWithCol,
+ frame_index,
+ function_name.ToCString(),
+ url.ToCString(), line, column);
+ } else {
+ len = OS::SNPrint(NULL, 0, kFormatNoCol,
+ frame_index, function_name.ToCString(),
+ url.ToCString(), line);
+ chars = isolate->current_zone()->Alloc<char>(len + 1);
+ OS::SNPrint(chars, (len + 1), kFormatNoCol,
+ frame_index, function_name.ToCString(),
+ url.ToCString(), line);
+ }
frame_strings->Add(chars);
return len;
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index d5c8cad..ffceea0 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1416,6 +1416,10 @@
// does not involve generic parameter types or generic result type.
bool HasInstantiatedSignature() const;
+ // Build a string of the form 'T, {b: B, c: C} representing the user
+ // visible formal parameters of the function.
+ RawString* UserVisibleFormalParameters() const;
+
RawClass* Owner() const;
RawClass* origin() const;
RawScript* script() const;
@@ -1464,9 +1468,6 @@
RawClass* signature_class() const;
void set_signature_class(const Class& value) const;
- RawInstance* implicit_static_closure() const;
- void set_implicit_static_closure(const Instance& closure) const;
-
RawCode* closure_allocation_stub() const;
void set_closure_allocation_stub(const Code& value) const;
@@ -1498,6 +1499,10 @@
// If none exists yet, create one and remember it.
RawFunction* ImplicitClosureFunction() const;
+ // Return the closure implicitly created for this function.
+ // If none exists yet, create one and remember it.
+ RawInstance* ImplicitStaticClosure() const;
+
// Redirection information for a redirecting factory.
bool IsRedirectingFactory() const;
RawType* RedirectionType() const;
@@ -1858,11 +1863,17 @@
void set_owner(const Object& value) const;
RawFunction* implicit_closure_function() const;
void set_implicit_closure_function(const Function& value) const;
+ RawInstance* implicit_static_closure() const;
+ void set_implicit_static_closure(const Instance& closure) const;
void set_num_optional_parameters(intptr_t value) const; // Encoded value.
void set_kind_tag(intptr_t value) const;
void set_data(const Object& value) const;
static RawFunction* New();
+ void BuildSignatureParameters(bool instantiate,
+ NameVisibility name_visibility,
+ const AbstractTypeArguments& instantiator,
+ const GrowableObjectArray& pieces) const;
RawString* BuildSignature(bool instantiate,
NameVisibility name_visibility,
const AbstractTypeArguments& instantiator) const;
@@ -2074,6 +2085,8 @@
// Deoptimize all dependent code objects.
void DeoptimizeDependentCode() const;
+ bool IsUninitialized() const;
+
// Constructs getter and setter names for fields and vice versa.
static RawString* GetterName(const String& field_name);
static RawString* GetterSymbol(const String& field_name);
@@ -2261,6 +2274,10 @@
void GetTokenLocation(intptr_t token_pos,
intptr_t* line, intptr_t* column) const;
+ // Returns index of first and last token on the given line. Returns both
+ // indices < 0 if no token exists on or after the line. If a token exists
+ // after, but not on given line, returns in *first_token_index the index of
+ // the first token after the line, and a negative value in *last_token_index.
void TokenRangeAtLine(intptr_t line_number,
intptr_t* first_token_index,
intptr_t* last_token_index) const;
@@ -3753,6 +3770,10 @@
const AbstractTypeArguments& type_instantiator,
Error* bound_error) const;
+ // Check whether this instance is identical to the argument according to the
+ // specification of dare:core's identical().
+ bool IsIdenticalTo(const Instance& other) const;
+
bool IsValidNativeIndex(int index) const {
return ((index >= 0) && (index < clazz()->ptr()->num_native_fields_));
}
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index dcb3bbe..78a3d0c 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2064,24 +2064,50 @@
str = script.GetLine(last_dart_line);
EXPECT_STREQ(" }", str.ToCString());
-
script.Tokenize(String::Handle(String::New("ABC")));
+ // Tokens: 0: kIDENT, 1: kLPAREN, 2: kRPAREN, 3: kLBRACE, 4: kNEWLINE,
+ // 5: kRETURN, 6: kSTRING, 7: kSEMICOLON, 8: kNEWLINE,
+ // 9: kRBRACE, 10: kNEWLINE
+
intptr_t line, col;
+ intptr_t fast_line;
script.GetTokenLocation(0, &line, &col);
EXPECT_EQ(first_dart_line, line);
EXPECT_EQ(col, col_offset + 1);
- script.GetTokenLocation(4, &line, &col); // Token 'return'
+ // We allow asking for only the line number, which only scans the token stream
+ // instead of rescanning the script.
+ script.GetTokenLocation(0, &fast_line, NULL);
+ EXPECT_EQ(line, fast_line);
+
+ script.GetTokenLocation(5, &line, &col); // Token 'return'
EXPECT_EQ(4, line); // 'return' is in line 4.
EXPECT_EQ(5, col); // Four spaces before 'return'.
+ // We allow asking for only the line number, which only scans the token stream
+ // instead of rescanning the script.
+ script.GetTokenLocation(5, &fast_line, NULL);
+ EXPECT_EQ(line, fast_line);
+
intptr_t first_idx, last_idx;
script.TokenRangeAtLine(3, &first_idx, &last_idx);
EXPECT_EQ(0, first_idx); // Token 'main' is first token.
EXPECT_EQ(3, last_idx); // Token { is last token.
+ script.TokenRangeAtLine(4, &first_idx, &last_idx);
+ EXPECT_EQ(5, first_idx); // Token 'return' is first token.
+ EXPECT_EQ(7, last_idx); // Token ; is last token.
script.TokenRangeAtLine(5, &first_idx, &last_idx);
EXPECT_EQ(9, first_idx); // Token } is first and only token.
EXPECT_EQ(9, last_idx);
+ script.TokenRangeAtLine(1, &first_idx, &last_idx);
+ EXPECT_EQ(0, first_idx);
+ EXPECT_EQ(3, last_idx);
+ script.TokenRangeAtLine(6, &first_idx, &last_idx);
+ EXPECT_EQ(-1, first_idx);
+ EXPECT_EQ(-1, last_idx);
+ script.TokenRangeAtLine(1000, &first_idx, &last_idx);
+ EXPECT_EQ(-1, first_idx);
+ EXPECT_EQ(-1, last_idx);
}
diff --git a/runtime/vm/object_x64_test.cc b/runtime/vm/object_x64_test.cc
index 42e872c..f24d1e5 100644
--- a/runtime/vm/object_x64_test.cc
+++ b/runtime/vm/object_x64_test.cc
@@ -45,7 +45,7 @@
// This is used to test Embedded Smi objects in the instructions.
void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value) {
const Smi& smi_object = Smi::ZoneHandle(Smi::New(value));
- __ LoadObject(RAX, smi_object, PP);
+ __ movq(RAX, Immediate(reinterpret_cast<int64_t>(smi_object.raw())));
__ ret();
}
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index 0363b50..9eddae5 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -21,6 +21,9 @@
// Returns the name of the given OS. For example "linux".
static const char* Name();
+ // Returns the current process id.
+ static intptr_t ProcessId();
+
// Returns the abbreviated time-zone name for the given instant.
// For example "CET" or "CEST".
static const char* GetTimeZoneName(int64_t seconds_since_epoch);
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 1c625e4..cbce25c 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -189,6 +189,11 @@
}
+intptr_t OS::ProcessId() {
+ return static_cast<intptr_t>(getpid());
+}
+
+
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
time_t seconds = static_cast<time_t>(seconds_since_epoch);
if (seconds != seconds_since_epoch) return false;
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 450f581..091b601 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -129,12 +129,13 @@
if (file_open == NULL) {
return;
}
- const char* format = "/tmp/perf-%ld.map";
+ const char* format = "/tmp/perf-%"Pd".map";
intptr_t pid = getpid();
intptr_t len = OS::SNPrint(NULL, 0, format, pid);
char* filename = new char[len + 1];
OS::SNPrint(filename, len + 1, format, pid);
out_file_ = (*file_open)(filename, true);
+ delete[] filename;
}
~PerfCodeObserver() {
@@ -273,6 +274,11 @@
}
+intptr_t OS::ProcessId() {
+ return static_cast<intptr_t>(getpid());
+}
+
+
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
time_t seconds = static_cast<time_t>(seconds_since_epoch);
if (seconds != seconds_since_epoch) return false;
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 62c9376..76d9fb6 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -26,6 +26,11 @@
}
+intptr_t OS::ProcessId() {
+ return static_cast<intptr_t>(getpid());
+}
+
+
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
time_t seconds = static_cast<time_t>(seconds_since_epoch);
if (seconds != seconds_since_epoch) return false;
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 2062314..2765953 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -9,6 +9,7 @@
#include "vm/vtune.h"
#include <malloc.h> // NOLINT
+#include <process.h> // NOLINT
#include <time.h> // NOLINT
#include "platform/utils.h"
@@ -21,6 +22,11 @@
}
+intptr_t OS::ProcessId() {
+ return static_cast<intptr_t>(GetCurrentProcessId());
+}
+
+
// As a side-effect sets the globals _timezone, _daylight and _tzname.
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
time_t seconds = static_cast<time_t>(seconds_since_epoch);
@@ -196,7 +202,7 @@
return NULL;
}
result[len] = '\0';
- return reinterpret_cast<char*>(memcpy(result, s, len));
+ return reinterpret_cast<char*>(memmove(result, s, len));
}
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index aeb31c6..11ce280 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -2450,13 +2450,16 @@
current_class(), receiver, &initialized_fields);
receiver->set_invisible(false);
+ // If the class of this implicit constructor is a mixin typedef class,
+ // it is a forwarding constructor of the aliased mixin application class.
// If the class of this implicit constructor is a mixin application class,
// it is a forwarding constructor of the mixin. The forwarding
// constructor initializes the instance fields that have initializer
// expressions and then calls the respective super constructor with
// the same name and number of parameters.
ArgumentListNode* forwarding_args = NULL;
- if (current_class().IsMixinApplication()) {
+ if (current_class().is_mixin_typedef() ||
+ current_class().IsMixinApplication()) {
// At this point we don't support forwarding constructors
// that have optional parameters because we don't know the default
// values of the optional parameters. We would have to compile the super
@@ -2903,7 +2906,8 @@
func.is_static() ?
InvocationMirror::kStatic :
InvocationMirror::kDynamic,
- InvocationMirror::kMethod));
+ InvocationMirror::kMethod,
+ NULL)); // No existing function.
end_token_pos = TokenPos();
} else {
UnexpectedToken();
@@ -3793,7 +3797,7 @@
String::Handle(super_type.UserVisibleName()).ToCString());
}
if (CurrentToken() == Token::kWITH) {
- super_type = ParseMixins(super_type);
+ super_type = ParseMixins(pending_classes, super_type);
}
} else {
// No extends clause: implicitly extend Object, unless Object itself.
@@ -4003,7 +4007,7 @@
if (CurrentToken() != Token::kWITH) {
ErrorMsg("mixin application 'with Type' expected");
}
- type = ParseMixins(type);
+ type = ParseMixins(pending_classes, type);
// TODO(12773): Treat the mixin application as an alias, not as a base
// class whose super class is the mixin application! This is difficult because
@@ -4389,7 +4393,8 @@
}
-RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) {
+RawAbstractType* Parser::ParseMixins(const GrowableObjectArray& pending_classes,
+ const AbstractType& super_type) {
TRACE_PARSER("ParseMixins");
ASSERT(CurrentToken() == Token::kWITH);
ASSERT(super_type.IsType()); // TODO(regis): Could be a BoundedType.
@@ -4399,7 +4404,6 @@
GrowableObjectArray::Handle(GrowableObjectArray::New());
AbstractType& mixin_type = AbstractType::Handle();
Class& mixin_app_class = Class::Handle();
- Array& mixin_app_interfaces = Array::Handle();
String& mixin_app_class_name = String::Handle();
String& mixin_type_class_name = String::Handle();
do {
@@ -4427,12 +4431,12 @@
mixin_app_class.set_mixin(Type::Cast(mixin_type));
mixin_app_class.set_library(library_);
mixin_app_class.set_is_synthesized_class();
+ pending_classes.Add(mixin_app_class, Heap::kOld);
- // Add the mixin type to the interfaces that the mixin application
- // class implements. This is necessary so that type tests work.
- mixin_app_interfaces = Array::New(1);
- mixin_app_interfaces.SetAt(0, mixin_type);
- mixin_app_class.set_interfaces(mixin_app_interfaces);
+ // The class finalizer will add the mixin type to the interfaces that the
+ // mixin application class implements. This is necessary so that type tests
+ // work. The mixin class may not be resolved yet, so it is not possible to
+ // add the interface with the correct type arguments here.
// Add the synthesized class to the list of mixin apps.
mixin_apps.Add(mixin_app_class);
@@ -6043,7 +6047,55 @@
}
+// Check that all case expressions are of the same type, either int, String,
+// double or any other class that does not override the == operator.
+// The expressions are compile-time constants and are thus in the form
+// of a LiteralNode.
+void Parser::CheckCaseExpressions(const GrowableArray<LiteralNode*>& values) {
+ const intptr_t num_expressions = values.length();
+ if (num_expressions == 0) {
+ return;
+ }
+ const Instance& first_value = values[0]->literal();
+ for (intptr_t i = 0; i < num_expressions; i++) {
+ const Instance& val = values[i]->literal();
+ const intptr_t val_pos = values[i]->token_pos();
+ if (first_value.IsInteger()) {
+ if (!val.IsInteger()) {
+ ErrorMsg(val_pos, "expected case expression of type int");
+ }
+ continue;
+ }
+ if (first_value.IsString()) {
+ if (!val.IsString()) {
+ ErrorMsg(val_pos, "expected case expression of type String");
+ }
+ continue;
+ }
+ if (first_value.IsDouble()) {
+ if (!val.IsDouble()) {
+ ErrorMsg(val_pos, "expected case expression of type double");
+ }
+ continue;
+ }
+ if (val.clazz() != first_value.clazz()) {
+ ErrorMsg(val_pos, "all case expressions must be of same type");
+ }
+ Class& cls = Class::Handle(val.clazz());
+ const Function& equal_op = Function::Handle(
+ Resolver::ResolveDynamicAnyArgs(cls, Symbols::EqualOperator()));
+ ASSERT(!equal_op.IsNull());
+ cls = equal_op.Owner();
+ if (!cls.IsObjectClass()) {
+ ErrorMsg(val_pos,
+ "type class of case expression must not implement operator ==");
+ }
+ }
+}
+
+
CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value,
+ GrowableArray<LiteralNode*>* case_expr_values,
SourceLabel* case_label) {
TRACE_PARSER("ParseCaseClause");
bool default_seen = false;
@@ -6058,6 +6110,9 @@
ConsumeToken(); // Keyword case.
const intptr_t expr_pos = TokenPos();
AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades);
+ ASSERT(expr->IsLiteralNode());
+ case_expr_values->Add(expr->AsLiteralNode());
+
AstNode* switch_expr_load = new LoadLocalNode(case_pos,
switch_expr_value);
AstNode* case_comparison = new ComparisonNode(expr_pos,
@@ -6146,6 +6201,7 @@
// Parse case clauses
bool default_seen = false;
+ GrowableArray<LiteralNode*> case_expr_values;
while (true) {
// Check for statement label
SourceLabel* case_label = NULL;
@@ -6176,7 +6232,8 @@
if (default_seen) {
ErrorMsg("no case clauses allowed after default clause");
}
- CaseNode* case_clause = ParseCaseClause(temp_variable, case_label);
+ CaseNode* case_clause =
+ ParseCaseClause(temp_variable, &case_expr_values, case_label);
default_seen = case_clause->contains_default();
current_block_->statements->Add(case_clause);
} else if (CurrentToken() != Token::kRBRACE) {
@@ -6188,8 +6245,9 @@
}
}
- // TODO(hausner): Check that all expressions in case clauses are
- // of the same class, or implement int or String (issue 7307).
+ // Check that all expressions in case clauses are of the same class,
+ // or implement int, double or String.
+ CheckCaseExpressions(case_expr_values);
// Check for unresolved label references.
SourceLabel* unresolved_label =
@@ -6995,12 +7053,8 @@
} else if (CurrentToken() == Token::kSEMICOLON) {
// Empty statement, nothing to do.
ConsumeToken();
- } else if ((CurrentToken() == Token::kRETHROW) ||
- ((CurrentToken() == Token::kTHROW) &&
- (LookaheadToken(1) == Token::kSEMICOLON))) {
- // Rethrow of current exception. Throwing of an exception object
- // is an expression and is handled in ParseExpr().
- // TODO(hausner): remove support for 'throw;'.
+ } else if (CurrentToken() == Token::kRETHROW) {
+ // Rethrow of current exception.
ConsumeToken();
ExpectSemicolon();
// Check if it is ok to do a rethrow.
@@ -7311,7 +7365,8 @@
const String& function_name,
ArgumentListNode* function_arguments,
InvocationMirror::Call im_call,
- InvocationMirror::Type im_type) {
+ InvocationMirror::Type im_type,
+ Function* func) {
ArgumentListNode* arguments = new ArgumentListNode(call_pos);
// Object receiver.
// TODO(regis): For now, we pass a class literal of the unresolved
@@ -7347,22 +7402,37 @@
} else {
arguments->Add(new LiteralNode(call_pos, function_arguments->names()));
}
+
// List existingArgumentNames.
- // Check if there exists a function with the same name.
- Function& function =
- Function::Handle(cls.LookupStaticFunction(function_name));
- if (function.IsNull()) {
- arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
+ // Check if there exists a function with the same name unless caller
+ // has done the lookup already. If there is a function with the same
+ // name but incompatible parameters, inform the NoSuchMethodError what the
+ // expected parameters are.
+ Function& function = Function::Handle();
+ if (func != NULL) {
+ function = func->raw();
} else {
- const int total_num_parameters = function.NumParameters();
- Array& array =
- Array::ZoneHandle(Array::New(total_num_parameters, Heap::kOld));
- // Skip receiver.
- for (int i = 0; i < total_num_parameters; i++) {
- array.SetAt(i, String::Handle(function.ParameterNameAt(i)));
- }
- arguments->Add(new LiteralNode(call_pos, array));
+ function = cls.LookupStaticFunction(function_name);
}
+ Array& array = Array::ZoneHandle();
+ if (!function.IsNull()) {
+ // The constructor for NoSuchMethodError takes a list of existing
+ // parameter names to produce a descriptive error message explaining
+ // the parameter mismatch. The problem is that the array of names
+ // does not describe which parameters are optional positional or
+ // named, which can lead to confusing error messages.
+ // Since the NoSuchMethodError class only uses the list to produce
+ // a string describing the expected parameters, we construct a more
+ // descriptive string here and pass it as the only element of the
+ // "existingArgumentNames" array of the NoSuchMethodError constructor.
+ // TODO(13471): Separate the implementations of NoSuchMethodError
+ // between dart2js and VM. Update the constructor to accept a string
+ // describing the formal parameters of an incompatible call target.
+ array = Array::New(1, Heap::kOld);
+ array.SetAt(0, String::Handle(function.UserVisibleFormalParameters()));
+ }
+ arguments->Add(new LiteralNode(call_pos, array));
+
return MakeStaticCall(Symbols::NoSuchMethodError(),
PrivateCoreLibName(Symbols::ThrowNew()),
arguments);
@@ -7650,7 +7720,8 @@
name,
NULL, // No arguments.
InvocationMirror::kStatic,
- InvocationMirror::kSetter);
+ InvocationMirror::kSetter,
+ NULL); // No existing function.
} else if (result->IsStoreIndexedNode() ||
result->IsInstanceSetterNode() ||
result->IsStaticSetterNode() ||
@@ -7729,7 +7800,9 @@
if (CurrentToken() == Token::kTHROW) {
ConsumeToken();
- ASSERT(CurrentToken() != Token::kSEMICOLON);
+ if (CurrentToken() == Token::kSEMICOLON) {
+ ErrorMsg("expression expected after throw");
+ }
AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades);
return new ThrowNode(expr_pos, expr, NULL);
}
@@ -7944,7 +8017,8 @@
func_name,
arguments,
InvocationMirror::kStatic,
- InvocationMirror::kMethod);
+ InvocationMirror::kMethod,
+ NULL); // No existing function.
} else if (cls.IsTopLevel() &&
(cls.library() == Library::CoreLibrary()) &&
(func.name() == Symbols::Identical().raw())) {
@@ -8045,7 +8119,8 @@
field_name,
NULL, // No arguments.
InvocationMirror::kStatic,
- InvocationMirror::kField);
+ InvocationMirror::kField,
+ NULL); // No existing function.
}
// Explicit setter function for the field found, field does not exist.
@@ -8090,7 +8165,8 @@
field_name,
NULL, // No arguments.
InvocationMirror::kStatic,
- InvocationMirror::kGetter);
+ InvocationMirror::kGetter,
+ NULL); // No existing function.
}
access = CreateImplicitClosureNode(func, call_pos, NULL);
} else {
@@ -8130,7 +8206,8 @@
name,
NULL, // No arguments.
InvocationMirror::kStatic,
- InvocationMirror::kField);
+ InvocationMirror::kField,
+ NULL); // No existing function.
} else {
AstNode* receiver = LoadReceiver(primary->token_pos());
return CallGetter(node->token_pos(), receiver, name);
@@ -8302,7 +8379,8 @@
name,
NULL, // No arguments.
InvocationMirror::kStatic,
- InvocationMirror::kMethod);
+ InvocationMirror::kMethod,
+ NULL); // No existing function.
} else {
// Treat as call to unresolved (instance) method.
AstNode* receiver = LoadReceiver(primary->token_pos());
@@ -8318,7 +8396,8 @@
name,
NULL, // No arguments.
InvocationMirror::kStatic,
- InvocationMirror::kMethod);
+ InvocationMirror::kMethod,
+ NULL); // No existing function.
} else if (primary->primary().IsClass()) {
const Class& type_class = Class::Cast(primary->primary());
Type& type = Type::ZoneHandle(
@@ -9052,7 +9131,8 @@
ident,
NULL, // No arguments.
InvocationMirror::kStatic,
- InvocationMirror::kField);
+ InvocationMirror::kField,
+ NULL); // No existing function.
} else {
// Treat as call to unresolved instance field.
resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
@@ -9754,7 +9834,8 @@
external_constructor_name,
arguments,
InvocationMirror::kConstructor,
- InvocationMirror::kMethod);
+ InvocationMirror::kMethod,
+ &constructor);
} else if (constructor.IsRedirectingFactory()) {
ClassFinalizer::ResolveRedirectingFactory(type_class, constructor);
Type& redirect_type = Type::Handle(constructor.RedirectionType());
@@ -9822,7 +9903,8 @@
external_constructor_name,
arguments,
InvocationMirror::kConstructor,
- InvocationMirror::kMethod);
+ InvocationMirror::kMethod,
+ &constructor);
}
// Return a throw in case of a malformed type or report a compile-time error
@@ -9839,8 +9921,11 @@
AstNode* new_object = NULL;
if (is_const) {
if (!constructor.is_const()) {
- ErrorMsg("'const' requires const constructor: '%s'",
- String::Handle(constructor.name()).ToCString());
+ const String& external_constructor_name =
+ (named_constructor ? constructor_name : type_class_name);
+ ErrorMsg("non-const constructor '%s' cannot be used in "
+ "const object creation",
+ external_constructor_name.ToCString());
}
const Object& constructor_result = Object::Handle(
EvaluateConstConstructorCall(type_class,
@@ -10064,7 +10149,8 @@
unresolved_name,
NULL, // No arguments.
InvocationMirror::kTopLevel,
- call_type);
+ call_type,
+ NULL); // No existing function.
}
}
ASSERT(primary != NULL);
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 20fc8ca..4abfda0 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -187,8 +187,6 @@
const char* format,
va_list args);
- static void AddImplicitConstructor(const Class& cls);
-
private:
friend class EffectGraphVisitor; // For BuildNoSuchMethodArguments.
@@ -398,6 +396,7 @@
bool evaluate_metadata,
ParamList* params);
void CheckConstFieldsInitialized(const Class& cls);
+ static void AddImplicitConstructor(const Class& cls);
void CheckConstructors(ClassDesc* members);
AstNode* ParseExternalInitializedField(const Field& field);
void ParseInitializedInstanceFields(
@@ -420,7 +419,8 @@
GrowableArray<Field*>* initialized_fields);
String& ParseNativeDeclaration();
void ParseInterfaceList(const Class& cls);
- RawAbstractType* ParseMixins(const AbstractType& super_type);
+ RawAbstractType* ParseMixins(const GrowableObjectArray& pending_classes,
+ const AbstractType& super_type);
static StaticCallNode* BuildInvocationMirrorAllocation(
intptr_t call_pos,
const String& function_name,
@@ -495,7 +495,9 @@
AstNode* ParseDoWhileStatement(String* label_name);
AstNode* ParseForStatement(String* label_name);
AstNode* ParseForInStatement(intptr_t forin_pos, SourceLabel* label);
+ void CheckCaseExpressions(const GrowableArray<LiteralNode*>& values);
CaseNode* ParseCaseClause(LocalVariable* switch_expr_value,
+ GrowableArray<LiteralNode*>* case_expr_values,
SourceLabel* case_label);
AstNode* ParseSwitchStatement(String* label_name);
@@ -641,7 +643,8 @@
const String& function_name,
ArgumentListNode* function_arguments,
InvocationMirror::Call call,
- InvocationMirror::Type type);
+ InvocationMirror::Type type,
+ Function* func);
void CheckOperatorArity(const MemberDesc& member);
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index c003f6e..d63f95f 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -251,6 +251,9 @@
size = element->Size();
break;
}
+ case kNullCid:
+ size = Size();
+ break;
default:
OS::Print("Class Id: %" Pd "\n", class_id);
UNREACHABLE();
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index 4021d71..17028e1 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -119,9 +119,11 @@
// Now look for an instance function whose name matches function_name
// in the class.
Function& function = Function::Handle();
- while (function.IsNull() && !cls.IsNull()) {
+ while (!cls.IsNull()) {
function ^= cls.LookupDynamicFunction(function_name);
-
+ if (!function.IsNull()) {
+ return function.raw();
+ }
// Getter invocation might actually be a method extraction.
if (is_getter && function.IsNull()) {
function ^= cls.LookupDynamicFunction(field_name);
@@ -129,9 +131,50 @@
// We were looking for the getter but found a method with the same name.
// Create a method extractor and return it.
function ^= CreateMethodExtractor(function_name, function);
+ return function.raw();
}
}
+ cls = cls.SuperClass();
+ }
+ return function.raw();
+}
+
+// TODO(13355): Remove.
+RawFunction* Resolver::ResolveDynamicAnyArgsAllowPrivate(
+ const Class& receiver_class,
+ const String& function_name) {
+ Class& cls = Class::Handle(receiver_class.raw());
+ if (FLAG_trace_resolving) {
+ OS::Print("ResolveDynamic '%s' for class %s\n",
+ function_name.ToCString(),
+ String::Handle(cls.Name()).ToCString());
+ }
+
+ const bool is_getter = Field::IsGetterName(function_name);
+ String& field_name = String::Handle();
+ if (is_getter) {
+ field_name ^= Field::NameFromGetter(function_name);
+ }
+
+ // Now look for an instance function whose name matches function_name
+ // in the class.
+ Function& function = Function::Handle();
+ while (!cls.IsNull()) {
+ function ^= cls.LookupDynamicFunctionAllowPrivate(function_name);
+ if (!function.IsNull()) {
+ return function.raw();
+ }
+ // Getter invocation might actually be a method extraction.
+ if (is_getter && function.IsNull()) {
+ function ^= cls.LookupDynamicFunction(field_name);
+ if (!function.IsNull()) {
+ // We were looking for the getter but found a method with the same name.
+ // Create a method extractor and return it.
+ function ^= CreateMethodExtractor(function_name, function);
+ return function.raw();
+ }
+ }
cls = cls.SuperClass();
}
return function.raw();
diff --git a/runtime/vm/resolver.h b/runtime/vm/resolver.h
index a0f2b33..87df67f 100644
--- a/runtime/vm/resolver.h
+++ b/runtime/vm/resolver.h
@@ -37,6 +37,11 @@
const Class& receiver_class,
const String& function_name);
+ // TODO(13355): Remove.
+ static RawFunction* ResolveDynamicAnyArgsAllowPrivate(
+ const Class& receiver_class,
+ const String& function_name);
+
enum StaticResolveType {
kIsQualified,
kNotQualified
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index ecbe709..3cb4e01 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -422,19 +422,14 @@
// Entering string scanning mode.
BeginStringLiteral(c0_);
- string_is_multiline_ = (LookaheadChar(1) == c0_) &&
- (LookaheadChar(2) == c0_);
+ ReadChar();
- ReadChar(); // Skip opening delimiter.
- if (string_is_multiline_) {
+ if ((c0_ == string_delimiter_) && (LookaheadChar(1) == string_delimiter_)) {
+ string_is_multiline_ = true;
ReadChar(); // Skip two additional string delimiters.
ReadChar();
- if (c0_ == '\n') {
- // Skip first character of multiline string if it is a newline.
- ReadChar();
- }
}
- ScanLiteralStringChars(is_raw);
+ ScanLiteralStringChars(is_raw, string_is_multiline_);
}
@@ -497,7 +492,7 @@
}
-void Scanner::ScanLiteralStringChars(bool is_raw) {
+void Scanner::ScanLiteralStringChars(bool is_raw, bool remove_whitespace) {
GrowableArray<int32_t> string_chars(64);
ASSERT(IsScanningString());
@@ -595,6 +590,25 @@
}
string_chars.Add(ch1);
}
+ // The first line of a multi-line string is discarded if it only
+ // contains whitespace.
+ if (remove_whitespace && (string_chars.Last() == '\n')) {
+ bool whitespace_only = true;
+ // Last character is the newline, don't inspect it.
+ const intptr_t len = string_chars.length() - 1;
+ for (int i = 0; i < len; i++) {
+ int32_t ch = string_chars[i];
+ if ((ch != ' ') && (ch != '\t')) {
+ // Non-whitespace character, keep the first line.
+ whitespace_only = false;
+ break;
+ }
+ }
+ if (whitespace_only) {
+ string_chars.Clear(); // Discard characters on first line.
+ }
+ remove_whitespace = false;
+ }
ReadChar();
}
}
@@ -627,7 +641,7 @@
break;
}
} else {
- ScanLiteralStringChars(false);
+ ScanLiteralStringChars(false, false);
}
break;
}
@@ -895,41 +909,6 @@
}
-void Scanner::TokenRangeAtLine(intptr_t line_number,
- intptr_t* first_token_index,
- intptr_t* last_token_index) {
- ASSERT(line_number > 0);
- ASSERT((first_token_index != NULL) && (last_token_index != NULL));
- Reset();
- *first_token_index = -1;
- *last_token_index = -1;
- int token_index = 0;
- do {
- Scan();
- if (current_token_.position.line >= line_number) {
- *first_token_index = token_index;
- break;
- }
- token_index++;
- } while (current_token_.kind != Token::kEOS);
- if (current_token_.kind == Token::kEOS) {
- return;
- }
- if (current_token_.position.line > line_number) {
- // *last_token_index is -1 to signal that the first token is past
- // the requested line.
- return;
- }
- ASSERT(current_token_.position.line == line_number);
- while ((current_token_.kind != Token::kEOS) &&
- (current_token_.position.line == line_number)) {
- *last_token_index = token_index;
- Scan();
- token_index++;
- }
-}
-
-
const Scanner::GrowableTokenStream& Scanner::GetStream() {
GrowableTokenStream* ts = new GrowableTokenStream(128);
ScanAll(ts);
diff --git a/runtime/vm/scanner.h b/runtime/vm/scanner.h
index 5d59dee..e0d20fc 100644
--- a/runtime/vm/scanner.h
+++ b/runtime/vm/scanner.h
@@ -64,15 +64,6 @@
// Use CurrentPosition() to extract position.
void ScanTo(intptr_t token_index);
- // Returns index of first and last token on the given line.
- // Returns both indices < 0 if no token exists on or after the line.
- // If a token exists after, but not on given line, returns in
- // *fisrt_token_index the index of the first token after the line,
- // and a negative value in *last_token_index.
- void TokenRangeAtLine(intptr_t line_number,
- intptr_t* first_token_index,
- intptr_t* last_token_index);
-
// Scans entire source and returns a stream of tokens.
// Should be called only once.
const GrowableTokenStream& GetStream();
@@ -174,8 +165,10 @@
// Starts reading a string literal.
void ScanLiteralString(bool is_raw);
- // Read the characters of a string literal.
- void ScanLiteralStringChars(bool is_raw);
+ // Read the characters of a string literal. Remove whitespace up to
+ // and including the first newline character if remove_whitespace
+ // is true.
+ void ScanLiteralStringChars(bool is_raw, bool remove_whitespace);
// Reads a fixed number of hexadecimal digits.
bool ScanHexDigits(int digits, int32_t* value);
diff --git a/runtime/vm/scanner_test.cc b/runtime/vm/scanner_test.cc
index bf56873..7e8a053 100644
--- a/runtime/vm/scanner_test.cc
+++ b/runtime/vm/scanner_test.cc
@@ -410,28 +410,6 @@
}
-void FindLineTest() {
- const char* source =
- "/*1*/ \n"
- "/*2*/ class A {\n"
- "/*3*/ void foo() { }\n"
- "/*4*/ }\n";
-
- Scanner scanner(String::Handle(String::New(source)),
- String::Handle(String::New("")));
-
- intptr_t first_token_index, last_token_index;
- scanner.TokenRangeAtLine(3, &first_token_index, &last_token_index);
- EXPECT_EQ(3, first_token_index);
- EXPECT_EQ(8, last_token_index);
- scanner.TokenRangeAtLine(100, &first_token_index, &last_token_index);
- EXPECT(first_token_index < 0);
- scanner.TokenRangeAtLine(1, &first_token_index, &last_token_index);
- EXPECT_EQ(0, first_token_index);
- EXPECT(last_token_index < 0);
-}
-
-
void NewlinesTest() {
const char* source =
"var es = /* a\n"
@@ -479,7 +457,6 @@
EmptyMultilineString();
NumberLiteral();
InvalidText();
- FindLineTest();
NewlinesTest();
}
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 17b95f2..efcdf74 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -408,7 +408,11 @@
void Scavenger::IterateObjectIdTable(Isolate* isolate,
ScavengerVisitor* visitor) {
ObjectIdRing* ring = isolate->object_id_ring();
- ASSERT(ring != NULL);
+ if (ring == NULL) {
+ // --gc_at_alloc can get us here before the ring has been initialized.
+ ASSERT(FLAG_gc_at_alloc);
+ return;
+ }
ring->VisitPointers(visitor);
}
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index fdcf6c0..647b802 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -839,14 +839,16 @@
// Rescan this source and compare the token stream to see if they are
// the same.
const TokenStream& expected_tokens = TokenStream::Handle(script.tokens());
- TokenStream::Iterator expected_iterator(expected_tokens, 0);
+ TokenStream::Iterator expected_iterator(
+ expected_tokens, 0, TokenStream::Iterator::kAllTokens);
const String& str = String::Handle(expected_tokens.GenerateSource());
const String& private_key = String::Handle(expected_tokens.PrivateKey());
Scanner scanner(str, private_key);
const TokenStream& reconstructed_tokens =
TokenStream::Handle(TokenStream::New(scanner.GetStream(), private_key));
expected_iterator.SetCurrentPosition(0);
- TokenStream::Iterator reconstructed_iterator(reconstructed_tokens, 0);
+ TokenStream::Iterator reconstructed_iterator(
+ reconstructed_tokens, 0, TokenStream::Iterator::kAllTokens);
Token::Kind expected_kind = expected_iterator.CurrentTokenKind();
Token::Kind reconstructed_kind = reconstructed_iterator.CurrentTokenKind();
String& expected_literal = String::Handle();
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index f0c7c5d..dc8dcf2 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -78,8 +78,12 @@
void Zone::DeleteAll() {
// Traverse the chained list of segments, zapping (in debug mode)
// and freeing every zone segment.
- Segment::DeleteSegmentList(head_);
- Segment::DeleteSegmentList(large_segments_);
+ if (head_ != NULL) {
+ Segment::DeleteSegmentList(head_);
+ }
+ if (large_segments_ != NULL) {
+ Segment::DeleteSegmentList(large_segments_);
+ }
// Reset zone state.
#ifdef DEBUG
diff --git a/sdk/lib/chrome/dart2js/chrome_dart2js.dart b/sdk/lib/_chrome/dart2js/chrome_dart2js.dart
similarity index 99%
rename from sdk/lib/chrome/dart2js/chrome_dart2js.dart
rename to sdk/lib/_chrome/dart2js/chrome_dart2js.dart
index 77338a8..93f8f75 100644
--- a/sdk/lib/chrome/dart2js/chrome_dart2js.dart
+++ b/sdk/lib/_chrome/dart2js/chrome_dart2js.dart
@@ -5,7 +5,7 @@
///
/// For more information on these APIs, see the
/// [chrome.* API documentation](http://developer.chrome.com/apps/api_index.html).
-library chrome;
+library _chrome;
import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper';
@@ -17,7 +17,7 @@
// BSD-style license that can be found in the LICENSE file.
// DO NOT EDIT
-// Auto-generated dart:chrome library.
+// Auto-generated dart:_chrome library.
/* TODO(sashab): Add "show convertDartClosureToJS" once 'show' works. */
diff --git a/sdk/lib/chrome/dartium/chrome_dartium.dart b/sdk/lib/_chrome/dartium/chrome_dartium.dart
similarity index 90%
rename from sdk/lib/chrome/dartium/chrome_dartium.dart
rename to sdk/lib/_chrome/dartium/chrome_dartium.dart
index b741b3b..c16c9e5 100644
--- a/sdk/lib/chrome/dartium/chrome_dartium.dart
+++ b/sdk/lib/_chrome/dartium/chrome_dartium.dart
@@ -5,12 +5,12 @@
///
/// For more information on these APIs, see the
/// [Chrome APIs Documentation](http://developer.chrome.com/extensions/api_index.html)
-library chrome;
+library _chrome;
// 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.
// DO NOT EDIT
-// Auto-generated dart:chrome library.
+// Auto-generated dart:_chrome library.
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index 99659ac..9e7b990 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -20,6 +20,8 @@
// tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
// tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
// sdk/lib/core/regexp.dart
+// TODO(floitsch): also used in dart:async until end of September for
+// deprecation of runZonedExperimental.
const deprecated = 0;
diff --git a/sdk/lib/_collection_dev/sort.dart b/sdk/lib/_collection_dev/sort.dart
index 73276b2..9bc7c9a 100644
--- a/sdk/lib/_collection_dev/sort.dart
+++ b/sdk/lib/_collection_dev/sort.dart
@@ -54,13 +54,13 @@
*/
static void _doSort(List a, int left, int right, int compare(a, b)) {
if ((right - left) <= _INSERTION_SORT_THRESHOLD) {
- insertionSort_(a, left, right, compare);
+ _insertionSort(a, left, right, compare);
} else {
_dualPivotQuicksort(a, left, right, compare);
}
}
- static void insertionSort_(List a, int left, int right, int compare(a, b)) {
+ static void _insertionSort(List a, int left, int right, int compare(a, b)) {
for (int i = left + 1; i <= right; i++) {
var el = a[i];
int j = i;
diff --git a/sdk/lib/_internal/compiler/implementation/code_buffer.dart b/sdk/lib/_internal/compiler/implementation/code_buffer.dart
index 4934ea3..f63a99a 100644
--- a/sdk/lib/_internal/compiler/implementation/code_buffer.dart
+++ b/sdk/lib/_internal/compiler/implementation/code_buffer.dart
@@ -5,22 +5,18 @@
part of dart2js;
class CodeBuffer implements StringBuffer {
- StringBuffer buffer;
- List<CodeBufferMarker> markers;
+
+ StringBuffer buffer = new StringBuffer();
+ List<CodeBufferMarker> markers = new List<CodeBufferMarker>();
+
int lastBufferOffset = 0;
int mappedRangeCounter = 0;
- CodeBuffer()
- : buffer = new StringBuffer(),
- markers = new List<CodeBufferMarker>();
+ CodeBuffer();
int get length => buffer.length;
-
- bool get isEmpty {
- return buffer.isEmpty;
- }
-
- bool get isNotEmpty => !isEmpty;
+ bool get isEmpty => buffer.isEmpty;
+ bool get isNotEmpty => buffer.isNotEmpty;
CodeBuffer add(var object) {
write(object);
@@ -81,7 +77,8 @@
CodeBuffer addCharCode(int charCode) => writeCharCode(charCode);
CodeBuffer writeCharCode(int charCode) {
- return write(new String.fromCharCodes([charCode]));
+ buffer.writeCharCode(charCode);
+ return this;
}
CodeBuffer clear() {
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index 5c2e393..48bc9f4 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -149,8 +149,15 @@
Constant result = initialVariableValues[element];
return result;
}
- return compiler.withCurrentElement(element, () {
- TreeElements definitions = compiler.analyzeElement(element.declaration);
+ Element currentElement = element;
+ if (element.isParameter()
+ || element.isFieldParameter()
+ || element.isVariable()) {
+ currentElement = element.enclosingElement;
+ }
+ return compiler.withCurrentElement(currentElement, () {
+ TreeElements definitions =
+ compiler.analyzeElement(currentElement.declaration);
Constant constant = compileVariableWithDefinitions(
element, definitions, isConst: isConst);
return constant;
@@ -483,6 +490,7 @@
}
Constant visitLiteralSymbol(LiteralSymbol node) {
+ handler.registerStringInstance(elements);
InterfaceType type = compiler.symbolClass.computeType(compiler);
List<Constant> createArguments(_) {
return [constantSystem.createString(
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 2b51ade..04c0df0 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -970,9 +970,12 @@
Future runCompiler(Uri uri) {
// TODO(ahe): This prevents memory leaks when invoking the compiler
- // multiple times. Implement a better mechanism where StringWrapper
- // instances are shared on a per library basis.
+ // multiple times. Implement a better mechanism where we can store
+ // such caches in the compiler and get access to them through a
+ // suitably maintained static reference to the current compiler.
SourceString.canonicalizedValues.clear();
+ Selector.canonicalizedValues.clear();
+ TypedSelector.canonicalizedValues.clear();
assert(uri != null || analyzeOnly);
return scanBuiltinLibraries().then((_) {
@@ -1010,21 +1013,21 @@
reportFatalError(
mainApp,
MessageKind.GENERIC,
- {'text': 'Error: Could not find "${MAIN.slowToString()}".'});
+ {'text': "Error: Could not find '${MAIN.slowToString()}'."});
} else if (!analyzeAll) {
reportFatalError(
mainApp,
MessageKind.GENERIC,
- {'text': 'Error: Could not find "${MAIN.slowToString()}". '
- 'No source will be analyzed. '
- 'Use "--analyze-all" to analyze all code in the library.'});
+ {'text': "Error: Could not find '${MAIN.slowToString()}'. "
+ "No source will be analyzed. "
+ "Use '--analyze-all' to analyze all code in the library."});
}
} else {
if (!main.isFunction()) {
reportFatalError(
main,
MessageKind.GENERIC,
- {'text': 'Error: "${MAIN.slowToString()}" is not a function.'});
+ {'text': "Error: '${MAIN.slowToString()}' is not a function."});
}
FunctionElement mainMethod = main;
FunctionSignature parameters = mainMethod.computeSignature(this);
@@ -1190,6 +1193,14 @@
}
TreeElements analyzeElement(Element element) {
+ assert(invariant(element,
+ element.impliesType() ||
+ element.isField() ||
+ element.isFunction() ||
+ element.isGenerativeConstructor() ||
+ element.isGetter() ||
+ element.isSetter(),
+ message: 'Unexpected element kind: ${element.kind}'));
assert(invariant(element, element.isDeclaration));
ResolutionEnqueuer world = enqueuer.resolution;
TreeElements elements = world.getCachedElements(element);
@@ -1270,17 +1281,14 @@
() => resolver.computeFunctionType(element, signature));
}
- reportWarning(Node node, var message) {
+ reportWarning(Spannable node, var message) {
if (message is TypeWarning) {
// TODO(ahe): Don't supress these warning when the type checker
// is more complete.
- if (identical(message.message.kind, MessageKind.MISSING_RETURN)) return;
- if (identical(message.message.kind, MessageKind.MAYBE_MISSING_RETURN)) {
- return;
- }
+ if (message.message.kind == MessageKind.MISSING_RETURN) return;
+ if (message.message.kind == MessageKind.MAYBE_MISSING_RETURN) return;
}
- SourceSpan span = spanFromNode(node);
-
+ SourceSpan span = spanFromSpannable(node);
reportDiagnostic(span, '$message', api.Diagnostic.WARNING);
}
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index 68f7358..5a33070 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -92,6 +92,8 @@
}
}
+FormattingDiagnosticHandler diagnosticHandler;
+
Future compile(List<String> argv) {
bool isWindows = (Platform.operatingSystem == 'windows');
stackTraceFilePrefix = '$currentDirectory';
@@ -106,10 +108,10 @@
String outputLanguage = 'JavaScript';
bool stripArgumentSet = false;
bool analyzeOnly = false;
+ bool hasDisallowUnsafeEval = false;
// TODO(johnniwinther): Measure time for reading files.
SourceFileProvider inputProvider = new SourceFileProvider();
- FormattingDiagnosticHandler diagnosticHandler =
- new FormattingDiagnosticHandler(inputProvider);
+ diagnosticHandler = new FormattingDiagnosticHandler(inputProvider);
passThrough(String argument) => options.add(argument);
@@ -223,6 +225,17 @@
}
}
+ Uri computePrecompiledUri() {
+ String extension = 'precompiled.js';
+ String outPath = out.path;
+ if (outPath.endsWith('.js')) {
+ outPath = outPath.substring(0, outPath.length - 3);
+ return out.resolve('$outPath.$extension');
+ } else {
+ return out.resolve(extension);
+ }
+ }
+
List<String> arguments = <String>[];
List<OptionHandler> handlers = <OptionHandler>[
new OptionHandler('-[chv?]+', handleShortOptions),
@@ -240,7 +253,6 @@
new OptionHandler('--allow-mock-compilation', passThrough),
new OptionHandler('--minify', passThrough),
new OptionHandler('--force-strip=.*', setStrip),
- // TODO(ahe): Remove the --no-colors option.
new OptionHandler('--disable-diagnostic-colors',
(_) => diagnosticHandler.enableColors = false),
new OptionHandler('--enable-diagnostic-colors',
@@ -261,6 +273,8 @@
new OptionHandler('--global-js-name=.*', checkGlobalName),
new OptionHandler('--disable-type-inference', passThrough),
new OptionHandler('--terse', passThrough),
+ new OptionHandler('--disallow-unsafe-eval',
+ (_) => hasDisallowUnsafeEval = true),
// The following two options must come last.
new OptionHandler('-.*', (String argument) {
@@ -276,6 +290,14 @@
helpAndExit(wantHelp, wantVersion, diagnosticHandler.verbose);
}
+ if (hasDisallowUnsafeEval) {
+ String precompiledName =
+ relativize(currentDirectory, computePrecompiledUri(), isWindows);
+ helpAndFail("Error: option '--disallow-unsafe-eval' has been removed."
+ " Instead, the compiler generates a file named"
+ " '$precompiledName'.");
+ }
+
if (outputLanguage != OUTPUT_LANGUAGE_DART && stripArgumentSet) {
helpAndFail('Error: --force-strip may only be used with '
'--output-type=dart');
@@ -313,7 +335,7 @@
if (!explicitOut) {
String input = uriPathToNative(arguments[0]);
String output = relativize(currentDirectory, out, isWindows);
- print('Dart file $input compiled to $outputLanguage: $output');
+ print('Dart file ($input) compiled to $outputLanguage: $output');
}
}
@@ -327,6 +349,11 @@
uri = out;
sourceMapFileName =
sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1);
+ } else if (extension == 'precompiled.js') {
+ uri = computePrecompiledUri();
+ diagnosticHandler.info(
+ "File ($uri) is compatible with header"
+ " \"Content-Security-Policy: script-src 'self'\"");
} else if (extension == 'js.map' || extension == 'dart.map') {
uri = sourceMapOut;
} else {
@@ -416,7 +443,12 @@
}
void fail(String message) {
- print(message);
+ if (diagnosticHandler != null) {
+ diagnosticHandler.diagnosticHandler(
+ null, -1, -1, message, api.Diagnostic.ERROR);
+ } else {
+ print(message);
+ }
exit(1);
}
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index b8a13a7..47febfa 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -32,7 +32,7 @@
import 'source_file.dart' show SourceFile;
import 'js/js.dart' as js;
import 'deferred_load.dart' show DeferredLoadTask;
-import 'types/container_tracer.dart' show ContainerTracer;
+import 'inferrer/container_tracer.dart' show ContainerTracer;
import 'mirrors_used.dart' show MirrorUsageAnalyzerTask;
export 'resolution/resolution.dart' show TreeElements, TreeElementMapping;
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index 13a21595..6dea904 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -211,7 +211,18 @@
ClassElement classElement = coreLibrary.findLocal(new SourceString(name));
classElement.ensureResolved(compiler);
}
+ // Enqueue the methods that the VM might invoke on user objects because
+ // we don't trust the resolution to always get these included.
+ world.registerInvocation(
+ new Selector.call(const SourceString("toString"), null, 0));
+ world.registerInvokedGetter(
+ new Selector.getter(const SourceString("hashCode"), null));
+ world.registerInvocation(
+ new Selector.binaryOperator(const SourceString("==")));
+ world.registerInvocation(
+ new Selector.call(const SourceString("compareTo"), null, 1));
}
+
void codegen(CodegenWorkItem work) { }
void processNativeClasses(Enqueuer world,
Iterable<LibraryElement> libraries) { }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
index a4e367f..6f07e12 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -244,6 +244,13 @@
});
}
+ // TODO(karlklose): should we create placeholders for these?
+ bool isTypedefParameter(Element element) {
+ return element != null &&
+ element.enclosingElement != null &&
+ element.enclosingElement.isTypedef();
+ }
+
void tryMakeLocalPlaceholder(Element element, Identifier node) {
bool isNamedOptionalParameter() {
FunctionElement function = element.enclosingElement;
@@ -258,9 +265,10 @@
// TODO(smok): Maybe we should rename privates as well, their privacy
// should not matter if they are local vars.
if (node.source.isPrivate()) return;
- if (element.isParameter() && isNamedOptionalParameter()) {
+ if (element.isParameter() && !isTypedefParameter(element) &&
+ isNamedOptionalParameter()) {
currentFunctionScope.registerParameter(node);
- } else if (Elements.isLocal(element)) {
+ } else if (Elements.isLocal(element) && !isTypedefParameter(element)) {
makeLocalPlaceholder(node);
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index cb7c4a7..f842ac3 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -68,7 +68,7 @@
Map<LibraryElement, String> imports,
Set<String> fixedMemberNames,
bool cutDeclarationTypes,
- {uniqueGlobalNaming: false}) {
+ {bool uniqueGlobalNaming: false}) {
final Map<LibraryElement, Map<String, String>> renamed
= new Map<LibraryElement, Map<String, String>>();
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 6aa85be..c09dfb3 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -882,11 +882,11 @@
[Element noMatch(Element)]);
void forEachMember(void f(ClassElement enclosingClass, Element member),
- {includeBackendMembers: false,
- includeSuperAndInjectedMembers: false});
+ {bool includeBackendMembers: false,
+ bool includeSuperAndInjectedMembers: false});
void forEachInstanceField(void f(ClassElement enclosingClass, Element field),
- {includeSuperAndInjectedMembers: false});
+ {bool includeSuperAndInjectedMembers: false});
/// Similar to [forEachInstanceField] but visits static fields.
void forEachStaticField(void f(ClassElement enclosingClass, Element field));
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 82f5e73..42ef97c 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -677,6 +677,7 @@
SourceString name = element.name;
Element existing = importScope.putIfAbsent(name, () => element);
if (existing != element) {
+ // TODO(johnniwinther): Only emit these warnings if [element] is used.
if (existing.getLibrary().isPlatformLibrary &&
!element.getLibrary().isPlatformLibrary) {
// [existing] is implicitly hidden.
@@ -688,10 +689,19 @@
} else if (!existing.getLibrary().isPlatformLibrary &&
element.getLibrary().isPlatformLibrary) {
// [element] is implicitly hidden.
- listener.reportWarningCode(import, MessageKind.HIDDEN_IMPORT,
- {'name': name,
- 'hiddenUri': element.getLibrary().canonicalUri,
- 'hidingUri': existing.getLibrary().canonicalUri});
+ if (import == null) {
+ // [element] is imported implicitly (probably through dart:core).
+ listener.reportWarningCode(importers[existing].head,
+ MessageKind.HIDDEN_IMPLICIT_IMPORT,
+ {'name': name,
+ 'hiddenUri': element.getLibrary().canonicalUri,
+ 'hidingUri': existing.getLibrary().canonicalUri});
+ } else {
+ listener.reportWarningCode(import, MessageKind.HIDDEN_IMPORT,
+ {'name': name,
+ 'hiddenUri': element.getLibrary().canonicalUri,
+ 'hidingUri': existing.getLibrary().canonicalUri});
+ }
} else {
// TODO(johnniwinther): Provide access to the import tags from which
// the elements came.
@@ -1879,7 +1889,7 @@
* origin and in the patch are included.
*/
void forEachInstanceField(void f(ClassElement enclosingClass, Element field),
- {includeSuperAndInjectedMembers: false}) {
+ {bool includeSuperAndInjectedMembers: false}) {
// Filters so that [f] is only invoked with instance fields.
void fieldFilter(ClassElement enclosingClass, Element member) {
if (member.isInstanceMember() && member.kind == ElementKind.FIELD) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
similarity index 98%
rename from sdk/lib/_internal/compiler/implementation/types/container_tracer.dart
rename to sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
index 3737a48..d491aa4 100644
--- a/sdk/lib/_internal/compiler/implementation/types/container_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
@@ -11,7 +11,7 @@
import '../util/util.dart' show Link;
import 'simple_types_inferrer.dart'
show InferrerEngine, InferrerVisitor, LocalsHandler, TypeMaskSystem;
-import 'types.dart';
+import '../types/types.dart';
import 'inferrer_visitor.dart';
/**
@@ -164,8 +164,7 @@
void recordTypeOfNonFinalField(Node node,
Element field,
- TypeMask type,
- CallSite constraint) {}
+ TypeMask type) {}
}
/**
@@ -179,6 +178,7 @@
bool analyze() {
measure(() {
+ if (compiler.disableTypeInference) return;
TypesInferrer inferrer = compiler.typesTask.typesInferrer;
InferrerEngineForContainerTracer engine =
new InferrerEngineForContainerTracer(compiler);
@@ -588,24 +588,27 @@
}
}
- if (Elements.isLocal(element)) {
- locals.update(element, rhsType, node);
- }
-
+ TypeMask result;
if (node.isPostfix) {
// We don't check if [getterSelector] could be the container because
// a list++ will always throw.
- return inferrer.returnTypeOfSelector(getterSelector);
+ result = inferrer.returnTypeOfSelector(getterSelector);
} else if (op != '=') {
// We don't check if [getterSelector] could be the container because
// a list += 42 will always throw.
- return inferrer.returnTypeOfSelector(operatorSelector);
+ result = inferrer.returnTypeOfSelector(operatorSelector);
} else {
if (isValueEscaping) {
escaping = true;
}
- return rhsType;
+ result = rhsType;
}
+
+ if (Elements.isLocal(element)) {
+ locals.update(element, result, node);
+ }
+
+ return result;
}
TypeMask visitSuperSend(Send node) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
similarity index 98%
rename from sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
rename to sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
index 7f9cef0..bc58690 100644
--- a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
@@ -254,14 +254,6 @@
}
}
-class CallSite {
- final Selector selector;
- final ArgumentsTypes arguments;
- CallSite(this.selector, this.arguments) {
- assert(selector != null);
- }
-}
-
abstract class MinimalInferrerEngine<T> {
/**
* Returns the type of [element].
@@ -271,14 +263,8 @@
/**
* Records that [node] sets non-final field [element] to be of type
* [type].
- *
- * [constraint] is a field assignment constraint, as described in
- * [InternalSimpleTypesInferrer].
*/
- void recordTypeOfNonFinalField(Node node,
- Element field,
- T type,
- CallSite constraint);
+ void recordTypeOfNonFinalField(Node node, Element field, T type);
}
/**
@@ -343,7 +329,7 @@
}
if (capturedAndBoxed.containsKey(local)) {
inferrer.recordTypeOfNonFinalField(
- node, capturedAndBoxed[local], type, null);
+ node, capturedAndBoxed[local], type);
} else if (inTryBlock) {
// We don't know if an assignment in a try block
// will be executed, so all assigments in that block are
@@ -691,7 +677,10 @@
}
T visitLiteralSymbol(LiteralSymbol node) {
- return types.nonNullExact(compiler.symbolClass.rawType);
+ // TODO(kasperl): We should be able to tell that the type of a literal
+ // symbol is always a non-null exact symbol implementation -- not just
+ // any non-null subtype of the symbol interface.
+ return types.nonNullSubtype(compiler.symbolClass.rawType);
}
T visitTypeReferenceSend(Send node) {
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
new file mode 100644
index 0000000..6cdbd1f
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
@@ -0,0 +1,1084 @@
+// 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 simple_types_inferrer;
+
+import '../closure.dart' show ClosureClassMap, ClosureScope;
+import '../dart_types.dart'
+ show DartType, InterfaceType, FunctionType, TypeKind;
+import '../elements/elements.dart';
+import '../native_handler.dart' as native;
+import '../tree/tree.dart';
+import '../util/util.dart' show Link, Spannable;
+import '../types/types.dart'
+ show TypesInferrer, FlatTypeMask, TypeMask, ContainerTypeMask,
+ ElementTypeMask, TypeSystem, MinimalInferrerEngine;
+import 'inferrer_visitor.dart';
+
+// BUG(8802): There's a bug in the analyzer that makes the re-export
+// of Selector from dart2jslib.dart fail. For now, we work around that
+// by importing universe.dart explicitly and disabling the re-export.
+import '../dart2jslib.dart' hide Selector, TypedSelector;
+import '../universe/universe.dart' show Selector, SideEffects, TypedSelector;
+
+/**
+ * An implementation of [TypeSystem] for [TypeMask].
+ */
+class TypeMaskSystem implements TypeSystem<TypeMask> {
+ final Compiler compiler;
+ TypeMaskSystem(this.compiler);
+
+ TypeMask narrowType(TypeMask type,
+ DartType annotation,
+ {bool isNullable: true}) {
+ if (annotation.treatAsDynamic) return type;
+ if (annotation.isVoid) return nullType;
+ if (annotation.element == compiler.objectClass) return type;
+ TypeMask otherType;
+ if (annotation.kind == TypeKind.TYPEDEF
+ || annotation.kind == TypeKind.FUNCTION) {
+ otherType = functionType;
+ } else if (annotation.kind == TypeKind.TYPE_VARIABLE) {
+ // TODO(ngeoffray): Narrow to bound.
+ return type;
+ } else {
+ assert(annotation.kind == TypeKind.INTERFACE);
+ otherType = new TypeMask.nonNullSubtype(annotation);
+ }
+ if (isNullable) otherType = otherType.nullable();
+ if (type == null) return otherType;
+ return type.intersection(otherType, compiler);
+ }
+
+ TypeMask computeLUB(TypeMask firstType, TypeMask secondType) {
+ if (firstType == null) {
+ return secondType;
+ } else if (secondType == dynamicType || firstType == dynamicType) {
+ return dynamicType;
+ } else if (firstType == secondType) {
+ return firstType;
+ } else {
+ TypeMask union = firstType.union(secondType, compiler);
+ // TODO(kasperl): If the union isn't nullable it seems wasteful
+ // to use dynamic. Fix that.
+ return union.containsAll(compiler) ? dynamicType : union;
+ }
+ }
+
+ TypeMask allocateDiamondPhi(TypeMask firstType, TypeMask secondType) {
+ return computeLUB(firstType, secondType);
+ }
+
+ TypeMask get dynamicType => compiler.typesTask.dynamicType;
+ TypeMask get nullType => compiler.typesTask.nullType;
+ TypeMask get intType => compiler.typesTask.intType;
+ TypeMask get doubleType => compiler.typesTask.doubleType;
+ TypeMask get numType => compiler.typesTask.numType;
+ TypeMask get boolType => compiler.typesTask.boolType;
+ TypeMask get functionType => compiler.typesTask.functionType;
+ TypeMask get listType => compiler.typesTask.listType;
+ TypeMask get constListType => compiler.typesTask.constListType;
+ TypeMask get fixedListType => compiler.typesTask.fixedListType;
+ TypeMask get growableListType => compiler.typesTask.growableListType;
+ TypeMask get mapType => compiler.typesTask.mapType;
+ TypeMask get constMapType => compiler.typesTask.constMapType;
+ TypeMask get stringType => compiler.typesTask.stringType;
+ TypeMask get typeType => compiler.typesTask.typeType;
+
+ TypeMask nonNullSubtype(DartType type) => new TypeMask.nonNullSubtype(type);
+ TypeMask nonNullSubclass(DartType type) => new TypeMask.nonNullSubclass(type);
+ TypeMask nonNullExact(DartType type) => new TypeMask.nonNullExact(type);
+ TypeMask nonNullEmpty() => new TypeMask.nonNullEmpty();
+
+ TypeMask allocateContainer(TypeMask type,
+ Node node,
+ Element enclosing,
+ [TypeMask elementType, int length]) {
+ ContainerTypeMask mask = new ContainerTypeMask(type, node, enclosing);
+ mask.elementType = elementType;
+ mask.length = length;
+ return mask;
+ }
+
+ Selector newTypedSelector(TypeMask receiver, Selector selector) {
+ return new TypedSelector(receiver, selector);
+ }
+
+ TypeMask addPhiInput(Element element, TypeMask phiType, TypeMask newType) {
+ return computeLUB(phiType, newType);
+ }
+
+ TypeMask allocatePhi(Node node, Element element, TypeMask inputType) {
+ return inputType;
+ }
+
+ TypeMask simplifyPhi(Node node, Element element, TypeMask phiType) {
+ return phiType;
+ }
+
+ TypeMask refineReceiver(Selector selector, TypeMask receiverType) {
+ TypeMask newType = compiler.world.allFunctions.receiverType(selector);
+ return receiverType.intersection(newType, compiler);
+ }
+}
+
+/**
+ * Common super class used by [SimpleTypeInferrerVisitor] to propagate
+ * type information about visited nodes, as well as to request type
+ * information of elements.
+ */
+abstract class InferrerEngine<T, V extends TypeSystem>
+ implements MinimalInferrerEngine<T> {
+ final Compiler compiler;
+ final V types;
+ final Map<Node, T> concreteTypes = new Map<Node, T>();
+
+ InferrerEngine(this.compiler, this.types);
+
+ /**
+ * Records the default type of parameter [parameter].
+ */
+ void setDefaultTypeOfParameter(Element parameter, T type);
+
+ /**
+ * Returns the type of [element].
+ */
+ T typeOfElement(Element element);
+
+ /**
+ * Records that [node] sets final field [element] to be of type [type].
+ *
+ * [nodeHolder] is the element holder of [node].
+ */
+ void recordTypeOfFinalField(Node node,
+ Element nodeHolder,
+ Element field,
+ T type);
+
+ /**
+ * Records that [node] sets non-final field [element] to be of type
+ * [type].
+ */
+ void recordTypeOfNonFinalField(Spannable node, Element field, T type);
+
+ /**
+ * Records that [element] is of type [type]. Returns whether the
+ * type is useful for the inferrer.
+ */
+ bool recordType(Element element, T type);
+
+ /**
+ * Records that the return type [element] is of type [type].
+ */
+ void recordReturnType(Element element, T type);
+
+ /**
+ * Registers that [caller] calls [callee] at location [node], with
+ * [selector], and [arguments]. Note that [selector] is null for
+ * forwarding constructors.
+ *
+ * [sideEffects] will be updated to incorporate [callee]'s side
+ * effects.
+ *
+ * [inLoop] tells whether the call happens in a loop.
+ */
+ T registerCalledElement(Spannable node,
+ Selector selector,
+ Element caller,
+ Element callee,
+ ArgumentsTypes<T> arguments,
+ SideEffects sideEffects,
+ bool inLoop);
+
+ /**
+ * Registers that [caller] calls [selector] with [receiverType] as
+ * receiver, and [arguments].
+ *
+ * [sideEffects] will be updated to incorporate the potential
+ * callees' side effects.
+ *
+ * [inLoop] tells whether the call happens in a loop.
+ */
+ T registerCalledSelector(Node node,
+ Selector selector,
+ T receiverType,
+ Element caller,
+ ArgumentsTypes<T> arguments,
+ SideEffects sideEffects,
+ bool inLoop);
+
+ /**
+ * Registers that [caller] calls [closure] with [arguments].
+ *
+ * [sideEffects] will be updated to incorporate the potential
+ * callees' side effects.
+ *
+ * [inLoop] tells whether the call happens in a loop.
+ */
+ T registerCalledClosure(Node node,
+ Selector selector,
+ T closure,
+ Element caller,
+ ArgumentsTypes<T> arguments,
+ SideEffects sideEffects,
+ bool inLoop);
+
+ /**
+ * Returns the callers of [elements].
+ */
+ Iterable<Element> getCallersOf(Element element);
+
+ /**
+ * Notifies to the inferrer that [analyzedElement] can have return
+ * type [newType]. [currentType] is the type the [InferrerVisitor]
+ * currently found.
+ *
+ * Returns the new type for [analyzedElement].
+ */
+ T addReturnTypeFor(Element analyzedElement, T currentType, T newType);
+
+ /**
+ * Applies [f] to all elements in the universe that match
+ * [selector]. If [f] returns false, aborts the iteration.
+ */
+ void forEachElementMatching(Selector selector, bool f(Element element)) {
+ Iterable<Element> elements = compiler.world.allFunctions.filter(selector);
+ for (Element e in elements) {
+ if (!f(e.implementation)) return;
+ }
+ }
+
+ /**
+ * Update [sideEffects] with the side effects of [callee] being
+ * called with [selector].
+ */
+ void updateSideEffects(SideEffects sideEffects,
+ Selector selector,
+ Element callee) {
+ if (callee.isField()) {
+ if (callee.isInstanceMember()) {
+ if (selector.isSetter()) {
+ sideEffects.setChangesInstanceProperty();
+ } else if (selector.isGetter()) {
+ sideEffects.setDependsOnInstancePropertyStore();
+ } else {
+ sideEffects.setAllSideEffects();
+ sideEffects.setDependsOnSomething();
+ }
+ } else {
+ if (selector.isSetter()) {
+ sideEffects.setChangesStaticProperty();
+ } else if (selector.isGetter()) {
+ sideEffects.setDependsOnStaticPropertyStore();
+ } else {
+ sideEffects.setAllSideEffects();
+ sideEffects.setDependsOnSomething();
+ }
+ }
+ } else if (callee.isGetter() && !selector.isGetter()) {
+ sideEffects.setAllSideEffects();
+ sideEffects.setDependsOnSomething();
+ } else {
+ sideEffects.add(compiler.world.getSideEffectsOfElement(callee));
+ }
+ }
+
+ /**
+ * Returns the type for [nativeBehavior]. See documentation on
+ * [native.NativeBehavior].
+ */
+ T typeOfNativeBehavior(native.NativeBehavior nativeBehavior) {
+ if (nativeBehavior == null) return types.dynamicType;
+ List typesReturned = nativeBehavior.typesReturned;
+ if (typesReturned.isEmpty) return types.dynamicType;
+ T returnType;
+ for (var type in typesReturned) {
+ T mappedType;
+ if (type == native.SpecialType.JsObject) {
+ mappedType = types.nonNullExact(compiler.objectClass.rawType);
+ } else if (type.element == compiler.stringClass) {
+ mappedType = types.stringType;
+ } else if (type.element == compiler.intClass) {
+ mappedType = types.intType;
+ } else if (type.element == compiler.doubleClass) {
+ mappedType = types.doubleType;
+ } else if (type.element == compiler.numClass) {
+ mappedType = types.numType;
+ } else if (type.element == compiler.boolClass) {
+ mappedType = types.boolType;
+ } else if (type.element == compiler.nullClass) {
+ mappedType = types.nullType;
+ } else if (type.isVoid) {
+ mappedType = types.nullType;
+ } else if (type.isDynamic) {
+ return types.dynamicType;
+ } else if (!compiler.world.hasAnySubtype(type.element)) {
+ mappedType = types.nonNullExact(type.element.rawType);
+ } else {
+ ClassElement element = type.element;
+ Set<ClassElement> subtypes = compiler.world.subtypesOf(element);
+ Set<ClassElement> subclasses = compiler.world.subclassesOf(element);
+ if (subclasses != null && subtypes.length == subclasses.length) {
+ mappedType = types.nonNullSubclass(element.rawType);
+ } else {
+ mappedType = types.nonNullSubtype(element.rawType);
+ }
+ }
+ returnType = types.computeLUB(returnType, mappedType);
+ if (returnType == types.dynamicType) {
+ break;
+ }
+ }
+ return returnType;
+ }
+
+ void updateSelectorInTree(Element owner, Node node, Selector selector) {
+ var elements = compiler.enqueuer.resolution.getCachedElements(owner);
+ if (node.asSendSet() != null) {
+ if (selector.isSetter() || selector.isIndexSet()) {
+ elements.setSelector(node, selector);
+ } else if (selector.isGetter() || selector.isIndex()) {
+ elements.setGetterSelectorInComplexSendSet(node, selector);
+ } else {
+ assert(selector.isOperator());
+ elements.setOperatorSelectorInComplexSendSet(node, selector);
+ }
+ } else if (node.asSend() != null) {
+ elements.setSelector(node, selector);
+ } else {
+ assert(node.asForIn() != null);
+ if (selector.asUntyped == compiler.iteratorSelector) {
+ elements.setIteratorSelector(node, selector);
+ } else if (selector.asUntyped == compiler.currentSelector) {
+ elements.setCurrentSelector(node, selector);
+ } else {
+ assert(selector.asUntyped == compiler.moveNextSelector);
+ elements.setMoveNextSelector(node, selector);
+ }
+ }
+ }
+
+ bool isNativeElement(Element element) {
+ if (element.isNative()) return true;
+ return element.isMember()
+ && element.getEnclosingClass().isNative()
+ && element.isField();
+ }
+}
+
+class SimpleTypeInferrerVisitor<T>
+ extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> {
+ T returnType;
+ bool visitingInitializers = false;
+ bool isConstructorRedirect = false;
+ SideEffects sideEffects = new SideEffects.empty();
+ final Element outermostElement;
+ final InferrerEngine<T, TypeSystem<T>> inferrer;
+ final Set<Element> capturedVariables = new Set<Element>();
+
+ SimpleTypeInferrerVisitor.internal(analyzedElement,
+ this.outermostElement,
+ inferrer,
+ compiler,
+ locals)
+ : super(analyzedElement, inferrer, inferrer.types, compiler, locals),
+ this.inferrer = inferrer;
+
+ factory SimpleTypeInferrerVisitor(Element element,
+ Compiler compiler,
+ InferrerEngine<T, TypeSystem<T>> inferrer,
+ [LocalsHandler<T> handler]) {
+ Element outermostElement =
+ element.getOutermostEnclosingMemberOrTopLevel().implementation;
+ assert(outermostElement != null);
+ return new SimpleTypeInferrerVisitor<T>.internal(
+ element, outermostElement, inferrer, compiler, handler);
+ }
+
+ T run() {
+ var node = analyzedElement.parseNode(compiler);
+ if (analyzedElement.isField() && node.asSendSet() == null) {
+ // Eagerly bailout, because computing the closure data only
+ // works for functions and field assignments.
+ return types.nullType;
+ }
+ // Update the locals that are boxed in [locals]. These locals will
+ // be handled specially, in that we are computing their LUB at
+ // each update, and reading them yields the type that was found in a
+ // previous analysis of [outermostElement].
+ ClosureClassMap closureData =
+ compiler.closureToClassMapper.computeClosureToClassMapping(
+ analyzedElement, node, elements);
+ closureData.forEachBoxedVariable((variable, field) {
+ locals.setCapturedAndBoxed(variable, field);
+ });
+ if (analyzedElement.isField()) {
+ return visit(node.asSendSet().arguments.head);
+ }
+
+ FunctionElement function = analyzedElement;
+ FunctionSignature signature = function.computeSignature(compiler);
+ signature.forEachOptionalParameter((element) {
+ Node node = element.parseNode(compiler);
+ Send send = node.asSendSet();
+ T type = (send == null) ? types.nullType : visit(send.arguments.head);
+ inferrer.setDefaultTypeOfParameter(element, type);
+ });
+
+ if (analyzedElement.isNative()) {
+ // Native methods do not have a body, and we currently just say
+ // they return dynamic.
+ return types.dynamicType;
+ }
+
+ if (analyzedElement.isGenerativeConstructor()) {
+ isThisExposed = false;
+ signature.forEachParameter((element) {
+ T parameterType = inferrer.typeOfElement(element);
+ if (element.kind == ElementKind.FIELD_PARAMETER) {
+ if (element.fieldElement.modifiers.isFinal()) {
+ inferrer.recordTypeOfFinalField(
+ node,
+ analyzedElement,
+ element.fieldElement,
+ parameterType);
+ } else {
+ locals.updateField(element.fieldElement, parameterType);
+ inferrer.recordTypeOfNonFinalField(
+ element.parseNode(compiler),
+ element.fieldElement,
+ parameterType);
+ }
+ }
+ locals.update(element, parameterType, node);
+ });
+ if (analyzedElement.isSynthesized) {
+ node = analyzedElement;
+ synthesizeForwardingCall(node, analyzedElement.targetConstructor);
+ } else {
+ visitingInitializers = true;
+ visit(node.initializers);
+ visitingInitializers = false;
+ visit(node.body);
+ }
+ ClassElement cls = analyzedElement.getEnclosingClass();
+ if (!isConstructorRedirect) {
+ // Iterate over all instance fields, and give a null type to
+ // fields that we haven't initialized for sure.
+ cls.forEachInstanceField((_, field) {
+ if (field.modifiers.isFinal()) return;
+ T type = locals.fieldScope.readField(field);
+ if (type == null && field.parseNode(compiler).asSendSet() == null) {
+ inferrer.recordTypeOfNonFinalField(node, field, types.nullType);
+ }
+ });
+ }
+ returnType = types.nonNullExact(cls.rawType);
+ } else {
+ signature.forEachParameter((element) {
+ locals.update(element, inferrer.typeOfElement(element), node);
+ });
+ visit(node.body);
+ if (returnType == null) {
+ // No return in the body.
+ returnType = locals.seenReturnOrThrow
+ ? types.nonNullEmpty() // Body always throws.
+ : types.nullType;
+ } else if (!locals.seenReturnOrThrow) {
+ // We haven't seen returns on all branches. So the method may
+ // also return null.
+ returnType = inferrer.addReturnTypeFor(
+ analyzedElement, returnType, types.nullType);
+ }
+ }
+
+ compiler.world.registerSideEffects(analyzedElement, sideEffects);
+ assert(breaksFor.isEmpty);
+ assert(continuesFor.isEmpty);
+ return returnType;
+ }
+
+ T visitFunctionExpression(FunctionExpression node) {
+ Element element = elements[node];
+ // We don't put the closure in the work queue of the
+ // inferrer, because it will share information with its enclosing
+ // method, like for example the types of local variables.
+ LocalsHandler closureLocals = new LocalsHandler<T>.from(
+ locals, node, useOtherTryBlock: false);
+ SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor<T>(
+ element, compiler, inferrer, closureLocals);
+ visitor.run();
+ inferrer.recordReturnType(element, visitor.returnType);
+
+ // Record the types of captured non-boxed variables. Types of
+ // these variables may already be there, because of an analysis of
+ // a previous closure. Note that analyzing the same closure multiple
+ // times closure will refine the type of those variables, therefore
+ // [:inferrer.typeOf[variable]:] is not necessarilly null, nor the
+ // same as [newType].
+ ClosureClassMap nestedClosureData =
+ compiler.closureToClassMapper.getMappingForNestedFunction(node);
+ nestedClosureData.forEachCapturedVariable((variable, field) {
+ if (!nestedClosureData.isVariableBoxed(variable)) {
+ if (variable == nestedClosureData.thisElement) {
+ inferrer.recordType(field, thisType);
+ }
+ // The type is null for type parameters.
+ if (locals.locals[variable] == null) return;
+ inferrer.recordType(field, locals.locals[variable]);
+ }
+ capturedVariables.add(variable);
+ });
+
+ return types.functionType;
+ }
+
+ T visitLiteralList(LiteralList node) {
+ if (node.isConst()) {
+ // We only set the type once. We don't need to re-visit the children
+ // when re-analyzing the node.
+ return inferrer.concreteTypes.putIfAbsent(node, () {
+ T elementType;
+ int length = 0;
+ for (Node element in node.elements.nodes) {
+ T type = visit(element);
+ elementType = elementType == null
+ ? types.allocatePhi(null, null, type)
+ : types.addPhiInput(null, elementType, type);
+ length++;
+ }
+ elementType = elementType == null
+ ? types.nonNullEmpty()
+ : types.simplifyPhi(null, null, elementType);
+ return types.allocateContainer(
+ types.constListType,
+ node,
+ outermostElement,
+ elementType,
+ length);
+ });
+ } else {
+ node.visitChildren(this);
+ return inferrer.concreteTypes.putIfAbsent(node, () {
+ return types.allocateContainer(
+ types.growableListType,
+ node,
+ outermostElement);
+ });
+ }
+ }
+
+ bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
+
+ void checkIfExposesThis(Selector selector) {
+ if (isThisExposed) return;
+ inferrer.forEachElementMatching(selector, (element) {
+ if (element.isField()) {
+ if (!selector.isSetter()
+ && element.getEnclosingClass() ==
+ outermostElement.getEnclosingClass()
+ && !element.modifiers.isFinal()
+ && locals.fieldScope.readField(element) == null
+ && element.parseNode(compiler).asSendSet() == null) {
+ // If the field is being used before this constructor
+ // actually had a chance to initialize it, say it can be
+ // null.
+ inferrer.recordTypeOfNonFinalField(
+ analyzedElement.parseNode(compiler), element,
+ types.nullType);
+ }
+ // Accessing a field does not expose [:this:].
+ return true;
+ }
+ // TODO(ngeoffray): We could do better here if we knew what we
+ // are calling does not expose this.
+ isThisExposed = true;
+ return false;
+ });
+ }
+
+ bool get inInstanceContext {
+ return (outermostElement.isInstanceMember() && !outermostElement.isField())
+ || outermostElement.isGenerativeConstructor();
+ }
+
+ bool treatAsInstanceMember(Element element) {
+ return (Elements.isUnresolved(element) && inInstanceContext)
+ || (element != null && element.isInstanceMember());
+ }
+
+ T visitSendSet(SendSet node) {
+ Element element = elements[node];
+ if (!Elements.isUnresolved(element) && element.impliesType()) {
+ node.visitChildren(this);
+ return types.dynamicType;
+ }
+
+ Selector getterSelector =
+ elements.getGetterSelectorInComplexSendSet(node);
+ Selector operatorSelector =
+ elements.getOperatorSelectorInComplexSendSet(node);
+ Selector setterSelector = elements.getSelector(node);
+
+ String op = node.assignmentOperator.source.stringValue;
+ bool isIncrementOrDecrement = op == '++' || op == '--';
+
+ T receiverType;
+ bool isCallOnThis = false;
+ if (node.receiver == null) {
+ if (treatAsInstanceMember(element)) {
+ receiverType = thisType;
+ isCallOnThis = true;
+ }
+ } else {
+ receiverType = visit(node.receiver);
+ isCallOnThis = isThisOrSuper(node.receiver);
+ }
+
+ T rhsType;
+ T indexType;
+
+ if (isIncrementOrDecrement) {
+ rhsType = types.intType;
+ if (node.isIndex) indexType = visit(node.arguments.head);
+ } else if (node.isIndex) {
+ indexType = visit(node.arguments.head);
+ rhsType = visit(node.arguments.tail.head);
+ } else {
+ rhsType = visit(node.arguments.head);
+ }
+
+ if (!visitingInitializers && !isThisExposed) {
+ for (Node node in node.arguments) {
+ if (isThisOrSuper(node)) {
+ isThisExposed = true;
+ break;
+ }
+ }
+ if (!isThisExposed && isCallOnThis) {
+ checkIfExposesThis(
+ types.newTypedSelector(receiverType, setterSelector));
+ if (getterSelector != null) {
+ checkIfExposesThis(
+ types.newTypedSelector(receiverType, getterSelector));
+ }
+ }
+ }
+
+ if (node.isIndex) {
+ if (op == '=') {
+ // [: foo[0] = 42 :]
+ handleDynamicSend(
+ node,
+ setterSelector,
+ receiverType,
+ new ArgumentsTypes<T>([indexType, rhsType], null));
+ return rhsType;
+ } else {
+ // [: foo[0] += 42 :] or [: foo[0]++ :].
+ T getterType = handleDynamicSend(
+ node,
+ getterSelector,
+ receiverType,
+ new ArgumentsTypes<T>([indexType], null));
+ T returnType = handleDynamicSend(
+ node,
+ operatorSelector,
+ getterType,
+ new ArgumentsTypes<T>([rhsType], null));
+ handleDynamicSend(
+ node,
+ setterSelector,
+ receiverType,
+ new ArgumentsTypes<T>([indexType, returnType], null));
+
+ if (node.isPostfix) {
+ return getterType;
+ } else {
+ return returnType;
+ }
+ }
+ } else if (op == '=') {
+ return handlePlainAssignment(
+ node, element, setterSelector, receiverType, rhsType,
+ node.arguments.head);
+ } else {
+ // [: foo++ :] or [: foo += 1 :].
+ ArgumentsTypes operatorArguments = new ArgumentsTypes<T>([rhsType], null);
+ T getterType;
+ T newType;
+ if (Elements.isErroneousElement(element)) {
+ getterType = types.dynamicType;
+ newType = types.dynamicType;
+ } else if (Elements.isStaticOrTopLevelField(element)) {
+ Element getterElement = elements[node.selector];
+ getterType =
+ handleStaticSend(node, getterSelector, getterElement, null);
+ newType = handleDynamicSend(
+ node, operatorSelector, getterType, operatorArguments);
+ handleStaticSend(
+ node, setterSelector, element,
+ new ArgumentsTypes<T>([newType], null));
+ } else if (Elements.isUnresolved(element)
+ || element.isSetter()
+ || element.isField()) {
+ getterType = handleDynamicSend(
+ node, getterSelector, receiverType, null);
+ newType = handleDynamicSend(
+ node, operatorSelector, getterType, operatorArguments);
+ handleDynamicSend(node, setterSelector, receiverType,
+ new ArgumentsTypes<T>([newType], null));
+ } else if (Elements.isLocal(element)) {
+ getterType = locals.use(element);
+ newType = handleDynamicSend(
+ node, operatorSelector, getterType, operatorArguments);
+ locals.update(element, newType, node);
+ } else {
+ // Bogus SendSet, for example [: myMethod += 42 :].
+ getterType = types.dynamicType;
+ newType = handleDynamicSend(
+ node, operatorSelector, getterType, operatorArguments);
+ }
+
+ if (node.isPostfix) {
+ return getterType;
+ } else {
+ return newType;
+ }
+ }
+ }
+
+ T handlePlainAssignment(Node node,
+ Element element,
+ Selector setterSelector,
+ T receiverType,
+ T rhsType,
+ Node rhs) {
+ ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null);
+ if (Elements.isErroneousElement(element)) {
+ // Code will always throw.
+ } else if (Elements.isStaticOrTopLevelField(element)) {
+ handleStaticSend(node, setterSelector, element, arguments);
+ } else if (Elements.isUnresolved(element) || element.isSetter()) {
+ handleDynamicSend(
+ node, setterSelector, receiverType, arguments);
+ } else if (element.isField()) {
+ if (element.modifiers.isFinal()) {
+ inferrer.recordTypeOfFinalField(
+ node, outermostElement, element, rhsType);
+ } else {
+ if (analyzedElement.isGenerativeConstructor()) {
+ locals.updateField(element, rhsType);
+ }
+ if (visitingInitializers) {
+ inferrer.recordTypeOfNonFinalField(node, element, rhsType);
+ } else {
+ handleDynamicSend(
+ node, setterSelector, receiverType, arguments);
+ }
+ }
+ } else if (Elements.isLocal(element)) {
+ locals.update(element, rhsType, node);
+ }
+ return rhsType;
+ }
+
+ T visitSuperSend(Send node) {
+ Element element = elements[node];
+ if (Elements.isUnresolved(element)) {
+ return types.dynamicType;
+ }
+ Selector selector = elements.getSelector(node);
+ // TODO(ngeoffray): We could do better here if we knew what we
+ // are calling does not expose this.
+ isThisExposed = true;
+ if (node.isPropertyAccess) {
+ return handleStaticSend(node, selector, element, null);
+ } else if (element.isFunction() || element.isGenerativeConstructor()) {
+ if (!selector.applies(element, compiler)) return types.dynamicType;
+ ArgumentsTypes arguments = analyzeArguments(node.arguments);
+ return handleStaticSend(node, selector, element, arguments);
+ } else {
+ ArgumentsTypes arguments = analyzeArguments(node.arguments);
+ return inferrer.registerCalledClosure(
+ node, selector, inferrer.typeOfElement(element),
+ outermostElement, arguments, sideEffects, inLoop);
+ }
+ }
+
+ T visitStaticSend(Send node) {
+ if (visitingInitializers && Initializers.isConstructorRedirect(node)) {
+ isConstructorRedirect = true;
+ }
+ Element element = elements[node];
+ if (element.isForeign(compiler)) {
+ return handleForeignSend(node);
+ }
+ Selector selector = elements.getSelector(node);
+ ArgumentsTypes arguments = analyzeArguments(node.arguments);
+ if (!selector.applies(element, compiler)) return types.dynamicType;
+
+ T returnType = handleStaticSend(node, selector, element, arguments);
+ if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
+ return inferrer.concreteTypes.putIfAbsent(
+ node, () => types.allocateContainer(
+ types.growableListType, node, outermostElement));
+ } else if (Elements.isFixedListConstructorCall(element, node, compiler)
+ || Elements.isFilledListConstructorCall(element, node, compiler)) {
+ return inferrer.concreteTypes.putIfAbsent(
+ node, () => types.allocateContainer(
+ types.fixedListType, node, outermostElement));
+ } else if (element.isFunction() || element.isConstructor()) {
+ return returnType;
+ } else {
+ assert(element.isField() || element.isGetter());
+ return inferrer.registerCalledClosure(
+ node, selector, inferrer.typeOfElement(element),
+ outermostElement, arguments, sideEffects, inLoop);
+ }
+ }
+
+ T handleForeignSend(Send node) {
+ ArgumentsTypes arguments = analyzeArguments(node.arguments);
+ Selector selector = elements.getSelector(node);
+ SourceString name = selector.name;
+ handleStaticSend(node, selector, elements[node], arguments);
+ if (name == const SourceString('JS')) {
+ native.NativeBehavior nativeBehavior =
+ compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
+ sideEffects.add(nativeBehavior.sideEffects);
+ return inferrer.typeOfNativeBehavior(nativeBehavior);
+ } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')
+ || name == const SourceString('JS_OPERATOR_AS_PREFIX')
+ || name == const SourceString('JS_OBJECT_CLASS_NAME')
+ || name == const SourceString('JS_NULL_CLASS_NAME')) {
+ return types.stringType;
+ } else {
+ sideEffects.setAllSideEffects();
+ return types.dynamicType;
+ }
+ }
+
+ ArgumentsTypes analyzeArguments(Link<Node> arguments) {
+ List<T> positional = [];
+ Map<SourceString, T> named = new Map<SourceString, T>();
+ for (var argument in arguments) {
+ NamedArgument namedArgument = argument.asNamedArgument();
+ if (namedArgument != null) {
+ argument = namedArgument.expression;
+ named[namedArgument.name.source] = argument.accept(this);
+ } else {
+ positional.add(argument.accept(this));
+ }
+ // TODO(ngeoffray): We could do better here if we knew what we
+ // are calling does not expose this.
+ isThisExposed = isThisExposed || argument.isThis();
+ }
+ return new ArgumentsTypes<T>(positional, named);
+ }
+
+ T visitGetterSend(Send node) {
+ Element element = elements[node];
+ Selector selector = elements.getSelector(node);
+ if (Elements.isStaticOrTopLevelField(element)) {
+ return handleStaticSend(node, selector, element, null);
+ } else if (Elements.isInstanceSend(node, elements)) {
+ return visitDynamicSend(node);
+ } else if (Elements.isStaticOrTopLevelFunction(element)) {
+ return handleStaticSend(node, selector, element, null);
+ } else if (Elements.isErroneousElement(element)) {
+ return types.dynamicType;
+ } else if (Elements.isLocal(element)) {
+ assert(locals.use(element) != null);
+ return locals.use(element);
+ } else {
+ assert(element is PrefixElement);
+ return null;
+ }
+ }
+
+ T visitClosureSend(Send node) {
+ assert(node.receiver == null);
+ T closure = node.selector.accept(this);
+ ArgumentsTypes arguments = analyzeArguments(node.arguments);
+ Element element = elements[node];
+ Selector selector = elements.getSelector(node);
+ if (element != null && element.isFunction()) {
+ assert(Elements.isLocal(element));
+ // This only works for function statements. We need a
+ // more sophisticated type system with function types to support
+ // more.
+ return inferrer.registerCalledElement(
+ node, selector, outermostElement, element, arguments,
+ sideEffects, inLoop);
+ } else {
+ return inferrer.registerCalledClosure(
+ node, selector, closure, outermostElement, arguments,
+ sideEffects, inLoop);
+ }
+ }
+
+ T handleStaticSend(Node node,
+ Selector selector,
+ Element element,
+ ArgumentsTypes arguments) {
+ if (Elements.isUnresolved(element)) return types.dynamicType;
+ return inferrer.registerCalledElement(
+ node, selector, outermostElement, element, arguments,
+ sideEffects, inLoop);
+ }
+
+ T handleDynamicSend(Node node,
+ Selector selector,
+ T receiverType,
+ ArgumentsTypes arguments) {
+ assert(receiverType != null);
+ if (selector.mask != receiverType) {
+ selector = (receiverType == types.dynamicType)
+ ? selector.asUntyped
+ : types.newTypedSelector(receiverType, selector);
+ inferrer.updateSelectorInTree(analyzedElement, node, selector);
+ }
+
+ // If the receiver of the call is a local, we may know more about
+ // its type by refining it with the potential targets of the
+ // calls.
+ if (node.asSend() != null) {
+ Node receiver = node.asSend().receiver;
+ if (receiver != null) {
+ Element element = elements[receiver];
+ if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
+ T refinedType = types.refineReceiver(selector, receiverType);
+ locals.update(element, refinedType, node);
+ }
+ }
+ }
+
+ return inferrer.registerCalledSelector(
+ node, selector, receiverType, outermostElement, arguments,
+ sideEffects, inLoop);
+ }
+
+ T visitDynamicSend(Send node) {
+ Element element = elements[node];
+ T receiverType;
+ bool isCallOnThis = false;
+ if (node.receiver == null) {
+ if (treatAsInstanceMember(element)) {
+ isCallOnThis = true;
+ receiverType = thisType;
+ }
+ } else {
+ Node receiver = node.receiver;
+ isCallOnThis = isThisOrSuper(receiver);
+ receiverType = visit(receiver);
+ }
+
+ Selector selector = elements.getSelector(node);
+ if (!isThisExposed && isCallOnThis) {
+ checkIfExposesThis(types.newTypedSelector(receiverType, selector));
+ }
+
+ ArgumentsTypes arguments = node.isPropertyAccess
+ ? null
+ : analyzeArguments(node.arguments);
+ return handleDynamicSend(node, selector, receiverType, arguments);
+ }
+
+ void recordReturnType(T type) {
+ returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type);
+ }
+
+ T synthesizeForwardingCall(Spannable node, FunctionElement element) {
+ element = element.implementation;
+ FunctionElement function = analyzedElement;
+ FunctionSignature signature = function.computeSignature(compiler);
+ FunctionSignature calleeSignature = element.computeSignature(compiler);
+ if (!calleeSignature.isCompatibleWith(signature)) {
+ return types.nonNullEmpty();
+ }
+
+ List<T> unnamed = <T>[];
+ Map<SourceString, T> named = new Map<SourceString, T>();
+ signature.forEachRequiredParameter((Element element) {
+ assert(locals.use(element) != null);
+ unnamed.add(locals.use(element));
+ });
+ signature.forEachOptionalParameter((Element element) {
+ if (signature.optionalParametersAreNamed) {
+ named[element.name] = locals.use(element);
+ } else {
+ unnamed.add(locals.use(element));
+ }
+ });
+ ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named);
+ return inferrer.registerCalledElement(node,
+ null,
+ outermostElement,
+ element,
+ arguments,
+ sideEffects,
+ inLoop);
+ }
+
+ T visitReturn(Return node) {
+ if (node.isRedirectingFactoryBody) {
+ Element element = elements[node.expression];
+ if (Elements.isErroneousElement(element)) {
+ recordReturnType(types.dynamicType);
+ } else {
+ // We don't create a selector for redirecting factories, and
+ // the send is just a property access. Therefore we must
+ // manually create the [ArgumentsTypes] of the call, and
+ // manually register [analyzedElement] as a caller of [element].
+ T mask = synthesizeForwardingCall(node.expression, element);
+ recordReturnType(mask);
+ }
+ } else {
+ Node expression = node.expression;
+ recordReturnType(expression == null
+ ? types.nullType
+ : expression.accept(this));
+ }
+ locals.seenReturnOrThrow = true;
+ }
+
+ T visitForIn(ForIn node) {
+ T expressionType = visit(node.expression);
+ Selector iteratorSelector = elements.getIteratorSelector(node);
+ Selector currentSelector = elements.getCurrentSelector(node);
+ Selector moveNextSelector = elements.getMoveNextSelector(node);
+
+ T iteratorType =
+ handleDynamicSend(node, iteratorSelector, expressionType, null);
+ handleDynamicSend(node, moveNextSelector,
+ iteratorType, new ArgumentsTypes<T>([], null));
+ T currentType =
+ handleDynamicSend(node, currentSelector, iteratorType, null);
+
+ if (node.expression.isThis()) {
+ // Any reasonable implementation of an iterator would expose
+ // this, so we play it safe and assume it will.
+ isThisExposed = true;
+ }
+
+ Node identifier = node.declaredIdentifier;
+ Element element = elements[identifier];
+ Selector selector = elements.getSelector(identifier);
+
+ T receiverType;
+ if (element != null && element.isInstanceMember()) {
+ receiverType = thisType;
+ } else {
+ receiverType = types.dynamicType;
+ }
+
+ handlePlainAssignment(identifier, element, selector,
+ receiverType, currentType,
+ node.expression);
+ return handleLoop(node, () {
+ visit(node.body);
+ });
+ }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
new file mode 100644
index 0000000..fc8e211
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -0,0 +1,871 @@
+// 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 type_graph_inferrer;
+
+import 'dart:collection' show Queue, LinkedHashSet, IterableBase, HashMap;
+import '../dart_types.dart' show DartType, InterfaceType, TypeKind;
+import '../elements/elements.dart';
+import '../tree/tree.dart' show Node;
+import '../types/types.dart' show TypeMask, ContainerTypeMask, TypesInferrer;
+import '../universe/universe.dart' show Selector, TypedSelector, SideEffects;
+import '../dart2jslib.dart' show Compiler, SourceString, TreeElementMapping;
+import 'inferrer_visitor.dart' show TypeSystem, ArgumentsTypes;
+import '../native_handler.dart' as native;
+import '../util/util.dart' show Spannable;
+import 'simple_types_inferrer.dart';
+import '../dart2jslib.dart' show invariant;
+
+part 'type_graph_nodes.dart';
+
+/**
+ * A set of selector names that [List] implements, that we know return
+ * their element type.
+ */
+Set<String> returnsElementTypeSet = new Set<String>.from(
+ const <String>[
+ 'first',
+ 'last',
+ 'single',
+ 'singleWhere',
+ 'elementAt',
+ '[]',
+ 'removeAt',
+ 'removeLast'
+ ]);
+
+bool returnsElementType(Selector selector) {
+ return (selector.mask != null)
+ && selector.mask.isContainer
+ && returnsElementTypeSet.contains(selector.name.slowToString());
+}
+
+class TypeInformationSystem extends TypeSystem<TypeInformation> {
+ final Compiler compiler;
+
+ /// [ElementTypeInformation]s for elements.
+ final Map<Element, TypeInformation> typeInformations =
+ new Map<Element, TypeInformation>();
+
+ /// [ContainerTypeInformation] for allocated containers.
+ final Map<Node, TypeInformation> allocatedContainers =
+ new Map<Node, TypeInformation>();
+
+ /// Cache of [ConcreteTypeInformation].
+ final Map<TypeMask, TypeInformation> concreteTypes =
+ new Map<TypeMask, TypeInformation>();
+
+ /// List of [TypeInformation]s allocated inside method bodies (calls,
+ /// narrowing, phis, and containers).
+ final List<TypeInformation> allocatedTypes = <TypeInformation>[];
+
+ TypeInformationSystem(this.compiler) {
+ nonNullEmptyType = getConcreteTypeFor(const TypeMask.nonNullEmpty());
+ }
+
+ TypeInformation nullTypeCache;
+ TypeInformation get nullType {
+ if (nullTypeCache != null) return nullTypeCache;
+ return nullTypeCache = getConcreteTypeFor(compiler.typesTask.nullType);
+ }
+
+ TypeInformation intTypeCache;
+ TypeInformation get intType {
+ if (intTypeCache != null) return intTypeCache;
+ return intTypeCache = getConcreteTypeFor(compiler.typesTask.intType);
+ }
+
+ TypeInformation doubleTypeCache;
+ TypeInformation get doubleType {
+ if (doubleTypeCache != null) return doubleTypeCache;
+ return doubleTypeCache = getConcreteTypeFor(compiler.typesTask.doubleType);
+ }
+
+ TypeInformation numTypeCache;
+ TypeInformation get numType {
+ if (numTypeCache != null) return numTypeCache;
+ return numTypeCache = getConcreteTypeFor(compiler.typesTask.numType);
+ }
+
+ TypeInformation boolTypeCache;
+ TypeInformation get boolType {
+ if (boolTypeCache != null) return boolTypeCache;
+ return boolTypeCache = getConcreteTypeFor(compiler.typesTask.boolType);
+ }
+
+ TypeInformation functionTypeCache;
+ TypeInformation get functionType {
+ if (functionTypeCache != null) return functionTypeCache;
+ return functionTypeCache =
+ getConcreteTypeFor(compiler.typesTask.functionType);
+ }
+
+ TypeInformation listTypeCache;
+ TypeInformation get listType {
+ if (listTypeCache != null) return listTypeCache;
+ return listTypeCache = getConcreteTypeFor(compiler.typesTask.listType);
+ }
+
+ TypeInformation constListTypeCache;
+ TypeInformation get constListType {
+ if (constListTypeCache != null) return constListTypeCache;
+ return constListTypeCache =
+ getConcreteTypeFor(compiler.typesTask.constListType);
+ }
+
+ TypeInformation fixedListTypeCache;
+ TypeInformation get fixedListType {
+ if (fixedListTypeCache != null) return fixedListTypeCache;
+ return fixedListTypeCache =
+ getConcreteTypeFor(compiler.typesTask.fixedListType);
+ }
+
+ TypeInformation growableListTypeCache;
+ TypeInformation get growableListType {
+ if (growableListTypeCache != null) return growableListTypeCache;
+ return growableListTypeCache =
+ getConcreteTypeFor(compiler.typesTask.growableListType);
+ }
+
+ TypeInformation mapTypeCache;
+ TypeInformation get mapType {
+ if (mapTypeCache != null) return mapTypeCache;
+ return mapTypeCache = getConcreteTypeFor(compiler.typesTask.mapType);
+ }
+
+ TypeInformation constMapTypeCache;
+ TypeInformation get constMapType {
+ if (constMapTypeCache != null) return constMapTypeCache;
+ return constMapTypeCache =
+ getConcreteTypeFor(compiler.typesTask.constMapType);
+ }
+
+ TypeInformation stringTypeCache;
+ TypeInformation get stringType {
+ if (stringTypeCache != null) return stringTypeCache;
+ return stringTypeCache = getConcreteTypeFor(compiler.typesTask.stringType);
+ }
+
+ TypeInformation typeTypeCache;
+ TypeInformation get typeType {
+ if (typeTypeCache != null) return typeTypeCache;
+ return typeTypeCache = getConcreteTypeFor(compiler.typesTask.typeType);
+ }
+
+ TypeInformation dynamicTypeCache;
+ TypeInformation get dynamicType {
+ if (dynamicTypeCache != null) return dynamicTypeCache;
+ return dynamicTypeCache =
+ getConcreteTypeFor(compiler.typesTask.dynamicType);
+ }
+
+ TypeInformation nonNullEmptyType;
+
+ TypeInformation computeLUB(TypeInformation firstType,
+ TypeInformation secondType) {
+ if (firstType == null) return secondType;
+ if (firstType == secondType) return firstType;
+ if (firstType == nonNullEmptyType) return secondType;
+ if (secondType == nonNullEmptyType) return firstType;
+ if (firstType == dynamicType || secondType == dynamicType) {
+ return dynamicType;
+ }
+ return getConcreteTypeFor(
+ firstType.type.union(secondType.type, compiler));
+ }
+
+ TypeInformation refineReceiver(Selector selector, TypeInformation receiver) {
+ if (receiver.type.isExact) return receiver;
+ TypeMask otherType = compiler.world.allFunctions.receiverType(selector);
+ // If this is refining to nullable subtype of `Object` just return
+ // the receiver. We know the narrowing is useless.
+ if (otherType.isNullable && otherType.containsAll(compiler)) {
+ return receiver;
+ }
+ TypeInformation newType = new NarrowTypeInformation(receiver, otherType);
+ allocatedTypes.add(newType);
+ return newType;
+ }
+
+ TypeInformation narrowType(TypeInformation type,
+ DartType annotation,
+ {bool isNullable: true}) {
+ if (annotation.treatAsDynamic) return type;
+ if (annotation.isVoid) return nullType;
+ if (annotation.element == compiler.objectClass) return type;
+ TypeMask otherType;
+ if (annotation.kind == TypeKind.TYPEDEF
+ || annotation.kind == TypeKind.FUNCTION) {
+ otherType = functionType.type;
+ } else if (annotation.kind == TypeKind.TYPE_VARIABLE) {
+ // TODO(ngeoffray): Narrow to bound.
+ return type;
+ } else {
+ assert(annotation.kind == TypeKind.INTERFACE);
+ otherType = new TypeMask.nonNullSubtype(annotation);
+ }
+ if (isNullable) otherType = otherType.nullable();
+ if (type.type.isExact) {
+ return type;
+ } else {
+ TypeInformation newType = new NarrowTypeInformation(type, otherType);
+ allocatedTypes.add(newType);
+ return newType;
+ }
+ }
+
+ ElementTypeInformation getInferredTypeOf(Element element) {
+ element = element.implementation;
+ return typeInformations.putIfAbsent(element, () {
+ return new ElementTypeInformation(element);
+ });
+ }
+
+ ConcreteTypeInformation getConcreteTypeFor(TypeMask mask) {
+ return concreteTypes.putIfAbsent(mask, () {
+ return new ConcreteTypeInformation(mask);
+ });
+ }
+
+ TypeInformation nonNullSubtype(DartType type) {
+ return getConcreteTypeFor(new TypeMask.nonNullSubtype(type));
+ }
+
+ TypeInformation nonNullSubclass(DartType type) {
+ return getConcreteTypeFor(new TypeMask.nonNullSubclass(type));
+ }
+
+ TypeInformation nonNullExact(DartType type) {
+ return getConcreteTypeFor(new TypeMask.nonNullExact(type));
+ }
+
+ TypeInformation nonNullEmpty() {
+ return nonNullEmptyType;
+ }
+
+ TypeInformation allocateContainer(TypeInformation type,
+ Node node,
+ Element enclosing,
+ [TypeInformation elementType, int length]) {
+ ContainerTypeMask mask = new ContainerTypeMask(type.type, node, enclosing);
+ mask.elementType = elementType == null ? null : elementType.type;
+ mask.length = length;
+ TypeInformation element =
+ new ElementInContainerTypeInformation(elementType, mask);
+ allocatedTypes.add(element);
+ return allocatedContainers[node] =
+ new ContainerTypeInformation(mask, element);
+ }
+
+ Selector newTypedSelector(TypeInformation info, Selector selector) {
+ // Only type the selector if [info] is concrete, because the other
+ // kinds of [TypeInformation] have the empty type at this point of
+ // analysis.
+ return info.isConcrete
+ ? new TypedSelector(info.type, selector)
+ : selector;
+ }
+
+ TypeInformation allocateDiamondPhi(TypeInformation firstInput,
+ TypeInformation secondInput) {
+ PhiElementTypeInformation result =
+ new PhiElementTypeInformation(null, false, null);
+ result.addAssignment(firstInput);
+ result.addAssignment(secondInput);
+ allocatedTypes.add(result);
+ return result;
+ }
+
+ PhiElementTypeInformation allocatePhi(Node node,
+ Element element,
+ inputType) {
+ // Check if [inputType] is a phi for a local updated in
+ // the try/catch block [node]. If it is, no need to allocate a new
+ // phi.
+ if (inputType is PhiElementTypeInformation
+ && inputType.branchNode == node) {
+ return inputType;
+ }
+ PhiElementTypeInformation result =
+ new PhiElementTypeInformation(node, true, element);
+ allocatedTypes.add(result);
+ result.addAssignment(inputType);
+ return result;
+ }
+
+ TypeInformation simplifyPhi(Node node,
+ Element element,
+ PhiElementTypeInformation phiType) {
+ if (phiType.assignments.length == 1) return phiType.assignments.first;
+ return phiType;
+ }
+
+ PhiElementTypeInformation addPhiInput(Element element,
+ PhiElementTypeInformation phiType,
+ TypeInformation newType) {
+ phiType.addAssignment(newType);
+ return phiType;
+ }
+
+ TypeMask computeTypeMask(Iterable<TypeInformation> assignments) {
+ TypeMask newType = const TypeMask.nonNullEmpty();
+ for (var info in assignments) {
+ newType = newType.union(info.type, compiler);
+ }
+ return newType.containsAll(compiler) ? dynamicType.type : newType;
+ }
+}
+
+/**
+ * A work queue for the inferrer. It filters out nodes on
+ * which we gave up on inferencing, as well as ensures through
+ * [TypeInformation.inQueue] that a node is in the queue only once at
+ * a time.
+ */
+class WorkQueue {
+ final Queue<TypeInformation> queue = new Queue<TypeInformation>();
+
+ void add(TypeInformation element) {
+ if (element.abandonInferencing) return;
+ if (element.inQueue) return;
+ queue.addLast(element);
+ element.inQueue = true;
+ }
+
+ void addAll(Iterable<TypeInformation> all) {
+ all.forEach(add);
+ }
+
+ TypeInformation remove() {
+ TypeInformation element = queue.removeFirst();
+ element.inQueue = false;
+ return element;
+ }
+
+ bool get isEmpty => queue.isEmpty;
+
+ int get length => queue.length;
+}
+
+/**
+ * An inferencing engine that computes a call graph of
+ * [TypeInformation] nodes by visiting the AST of the application, and
+ * then does the inferencing on the graph.
+ *
+ * The inferencing is currently done in three steps:
+ *
+ * 1) Compute the call graph.
+ * 2) Refine all nodes in a way that avoids cycles.
+ * 3) Refine all nodes.
+ *
+ */
+class TypeGraphInferrerEngine
+ extends InferrerEngine<TypeInformation, TypeInformationSystem> {
+ final Map<Element, TypeInformation> defaultTypeOfParameter =
+ new Map<Element, TypeInformation>();
+ final List<CallSiteTypeInformation> allocatedCalls =
+ <CallSiteTypeInformation>[];
+ final WorkQueue workQueue = new WorkQueue();
+
+ /// The maximum number of times we allow a node in the graph to
+ /// change types. If a node reaches that limit, we give up
+ /// inferencing on it and give it the dynamic type.
+ final int MAX_CHANGE_COUNT = 5;
+
+ int overallRefineCount = 0;
+
+ TypeGraphInferrerEngine(Compiler compiler)
+ : super(compiler, new TypeInformationSystem(compiler));
+
+ void runOverAllElements() {
+ if (compiler.disableTypeInference) return;
+ int addedInGraph = 0;
+ compiler.progress.reset();
+
+ sortResolvedElements().forEach((Element element) {
+ if (compiler.progress.elapsedMilliseconds > 500) {
+ compiler.log('Added $addedInGraph elements in inferencing graph.');
+ compiler.progress.reset();
+ }
+ // Force the creation of the [ElementTypeInformation] to ensure it is
+ // in the graph.
+ types.getInferredTypeOf(element);
+
+ SimpleTypeInferrerVisitor visitor =
+ new SimpleTypeInferrerVisitor(element, compiler, this);
+ TypeInformation type;
+ compiler.withCurrentElement(element, () {
+ type = visitor.run();
+ });
+ addedInGraph++;
+
+ if (element.isField()) {
+ Node node = element.parseNode(compiler);
+ if (element.modifiers.isFinal() || element.modifiers.isConst()) {
+ // If [element] is final and has an initializer, we record
+ // the inferred type.
+ if (node.asSendSet() != null) {
+ recordType(element, type);
+ } else if (!element.isInstanceMember()) {
+ recordType(element, types.nullType);
+ }
+ } else if (node.asSendSet() == null) {
+ // Only update types of static fields if there is no
+ // assignment. Instance fields are dealt with in the constructor.
+ if (Elements.isStaticOrTopLevelField(element)) {
+ recordTypeOfNonFinalField(node, element, type);
+ }
+ } else {
+ recordTypeOfNonFinalField(node, element, type);
+ }
+ if (Elements.isStaticOrTopLevelField(element)
+ && node.asSendSet() != null
+ && !element.modifiers.isConst()) {
+ var argument = node.asSendSet().arguments.head;
+ // TODO(13429): We could do better here by using the
+ // constant handler to figure out if it's a lazy field or not.
+ if (argument.asSend() != null
+ || (argument.asNewExpression() != null && !argument.isConst())) {
+ recordType(element, types.nullType);
+ }
+ }
+ } else {
+ recordReturnType(element, type);
+ }
+ });
+ compiler.log('Added $addedInGraph elements in inferencing graph.');
+
+ buildWorkQueue();
+ refine();
+
+ compiler.log('Inferred $overallRefineCount types.');
+
+ if (compiler.enableTypeAssertions) {
+ // Undo the narrowing of parameters types. Parameters are being
+ // checked by the method, and we can therefore only trust their
+ // type after the checks. It is okay for the inferrer to rely on
+ // the type annotations, but the backend should has to
+ // insert the checks.
+ types.typeInformations.forEach((Element element,
+ ElementTypeInformation info) {
+ if (element.isParameter() || element.isFieldParameter()) {
+ if (info.abandonInferencing) {
+ info.type = types.dynamicType.type;
+ } else {
+ info.type = types.computeTypeMask(info.assignments);
+ }
+ }
+ });
+ }
+
+ processLoopInformation();
+ }
+
+ void processLoopInformation() {
+ allocatedCalls.forEach((info) {
+ if (!info.inLoop) return;
+ if (info is StaticCallSiteTypeInformation) {
+ compiler.world.addFunctionCalledInLoop(info.calledElement);
+ } else if (info.selector.mask != null
+ && !info.selector.mask.containsAll(compiler)) {
+ // For instance methods, we only register a selector called in a
+ // loop if it is a typed selector, to avoid marking too many
+ // methods as being called from within a loop. This cuts down
+ // on the code bloat.
+ info.targets.forEach(compiler.world.addFunctionCalledInLoop);
+ }
+ });
+ }
+
+ void refine() {
+ while (!workQueue.isEmpty) {
+ if (compiler.progress.elapsedMilliseconds > 500) {
+ compiler.log('Inferred $overallRefineCount types.');
+ compiler.progress.reset();
+ }
+ TypeInformation info = workQueue.remove();
+ TypeMask oldType = info.type;
+ TypeMask newType = info.refine(this);
+ if ((info.type = newType) != oldType) {
+ overallRefineCount++;
+ info.refineCount++;
+ if (info.refineCount > MAX_CHANGE_COUNT) {
+ info.giveUp(this);
+ }
+ workQueue.addAll(info.users);
+ }
+ }
+ }
+
+ void buildWorkQueue() {
+ workQueue.addAll(types.typeInformations.values);
+ workQueue.addAll(types.allocatedTypes);
+ workQueue.addAll(allocatedCalls);
+ }
+
+ /**
+ * Update the assignments to parameters in the graph. [remove] tells
+ * wheter assignments must be added or removed. If [init] is true,
+ * parameters are added to the work queue.
+ */
+ void updateParameterAssignments(TypeInformation caller,
+ Element callee,
+ ArgumentsTypes arguments,
+ Selector selector,
+ {bool remove, bool init: false}) {
+ if (callee.name == Compiler.NO_SUCH_METHOD) return;
+ if (callee.isField()) {
+ if (selector.isSetter()) {
+ ElementTypeInformation info = types.getInferredTypeOf(callee);
+ if (remove) {
+ info.removeAssignment(arguments.positional[0]);
+ } else {
+ info.addAssignment(arguments.positional[0]);
+ }
+ if (!init) workQueue.add(info);
+ }
+ } else if (callee.isGetter()) {
+ return;
+ } else if (selector != null && selector.isGetter()) {
+ if (!remove) {
+ FunctionElement function = callee.implementation;
+ FunctionSignature signature = function.computeSignature(compiler);
+ signature.forEachParameter((Element parameter) {
+ ElementTypeInformation info = types.getInferredTypeOf(parameter);
+ info.giveUp(this);
+ if (!init) workQueue.addAll(info.users);
+ });
+ }
+ } else {
+ FunctionElement function = callee.implementation;
+ FunctionSignature signature = function.computeSignature(compiler);
+ int parameterIndex = 0;
+ bool visitingRequiredParameter = true;
+ signature.forEachParameter((Element parameter) {
+ if (parameter == signature.firstOptionalParameter) {
+ visitingRequiredParameter = false;
+ }
+ TypeInformation type = visitingRequiredParameter
+ ? arguments.positional[parameterIndex]
+ : signature.optionalParametersAreNamed
+ ? arguments.named[parameter.name]
+ : parameterIndex < arguments.positional.length
+ ? arguments.positional[parameterIndex]
+ : null;
+ if (type == null) type = getDefaultTypeOfParameter(parameter);
+ TypeInformation info = types.getInferredTypeOf(parameter);
+ if (remove) {
+ info.removeAssignment(type);
+ } else {
+ info.addAssignment(type);
+ }
+ parameterIndex++;
+ if (!init) workQueue.add(info);
+ });
+ }
+ }
+
+ void setDefaultTypeOfParameter(Element parameter, TypeInformation type) {
+ assert(parameter.enclosingElement.isImplementation);
+ TypeInformation existing = defaultTypeOfParameter[parameter];
+ defaultTypeOfParameter[parameter] = type;
+ TypeInformation info = types.getInferredTypeOf(parameter);
+ if (!info.abandonInferencing && existing != null && existing != type) {
+ // Replace references to [existing] to use [type] instead.
+ if (parameter.enclosingElement.isInstanceMember()) {
+ ParameterAssignments assignments = info.assignments;
+ int count = assignments.assignments[existing];
+ if (count == null) return;
+ type.addUser(info);
+ assignments.assignments[type] = count;
+ assignments.assignments.remove(existing);
+ } else {
+ List<TypeInformation> assignments = info.assignments;
+ for (int i = 0; i < assignments.length; i++) {
+ if (assignments[i] == existing) {
+ info.assignments[i] = type;
+ type.addUser(info);
+ }
+ }
+ }
+ }
+ }
+
+ TypeInformation getDefaultTypeOfParameter(Element parameter) {
+ return defaultTypeOfParameter.putIfAbsent(parameter, () {
+ return new ConcreteTypeInformation(types.dynamicType.type);
+ });
+ }
+
+ TypeInformation typeOfElement(Element element) {
+ if (element is FunctionElement) return types.functionType;
+ return types.getInferredTypeOf(element);
+ }
+
+ TypeInformation returnTypeOfElement(Element element) {
+ if (element is !FunctionElement) return types.dynamicType;
+ return types.getInferredTypeOf(element);
+ }
+
+ void recordTypeOfFinalField(Spannable node,
+ Element analyzed,
+ Element element,
+ TypeInformation type) {
+ types.getInferredTypeOf(element).addAssignment(type);
+ }
+
+ void recordTypeOfNonFinalField(Spannable node,
+ Element element,
+ TypeInformation type) {
+ types.getInferredTypeOf(element).addAssignment(type);
+ }
+
+ bool recordType(Element element, TypeInformation type) {
+ types.getInferredTypeOf(element).addAssignment(type);
+ return false;
+ }
+
+ void recordReturnType(Element element, TypeInformation type) {
+ TypeInformation info = types.getInferredTypeOf(element);
+ if (element.name == const SourceString('==')) {
+ info.addAssignment(types.boolType);
+ }
+ // TODO(ngeoffray): Clean up. We do these checks because
+ // [SimpleTypesInferrer] deals with two different inferrers.
+ if (type == null) return;
+ if (info.assignments.isEmpty) info.addAssignment(type);
+ }
+
+ TypeInformation addReturnTypeFor(Element element,
+ TypeInformation unused,
+ TypeInformation newType) {
+ TypeInformation type = types.getInferredTypeOf(element);
+ // TODO(ngeoffray): Clean up. We do this check because
+ // [SimpleTypesInferrer] deals with two different inferrers.
+ if (element.isGenerativeConstructor()) return type;
+ type.addAssignment(newType);
+ return type;
+ }
+
+ TypeInformation registerCalledElement(Spannable node,
+ Selector selector,
+ Element caller,
+ Element callee,
+ ArgumentsTypes arguments,
+ SideEffects sideEffects,
+ bool inLoop) {
+ CallSiteTypeInformation info = new StaticCallSiteTypeInformation(
+ node, caller, callee, selector, arguments, inLoop);
+ info.addToGraph(this);
+ allocatedCalls.add(info);
+ updateSideEffects(sideEffects, selector, callee);
+ return info;
+ }
+
+ TypeInformation registerCalledSelector(Node node,
+ Selector selector,
+ TypeInformation receiverType,
+ Element caller,
+ ArgumentsTypes arguments,
+ SideEffects sideEffects,
+ bool inLoop) {
+ if (selector.isClosureCall()) {
+ return registerCalledClosure(
+ node, selector, receiverType, caller, arguments, sideEffects, inLoop);
+ }
+
+ compiler.world.allFunctions.filter(selector).forEach((callee) {
+ updateSideEffects(sideEffects, selector, callee);
+ });
+
+ CallSiteTypeInformation info = new DynamicCallSiteTypeInformation(
+ node, caller, selector, receiverType, arguments, inLoop);
+
+ info.addToGraph(this);
+ allocatedCalls.add(info);
+ return info;
+ }
+
+ TypeInformation registerCalledClosure(Node node,
+ Selector selector,
+ TypeInformation closure,
+ Element caller,
+ ArgumentsTypes arguments,
+ SideEffects sideEffects,
+ bool inLoop) {
+ sideEffects.setDependsOnSomething();
+ sideEffects.setAllSideEffects();
+ CallSiteTypeInformation info = new ClosureCallSiteTypeInformation(
+ node, caller, selector, closure, arguments, inLoop);
+ info.addToGraph(this);
+ allocatedCalls.add(info);
+ return info;
+ }
+
+ // Sorts the resolved elements by size. We do this for this inferrer
+ // to get the same results for [ContainerTracer] compared to the
+ // [SimpleTypesInferrer].
+ Iterable<Element> sortResolvedElements() {
+ int max = 0;
+ Map<int, Set<Element>> methodSizes = new Map<int, Set<Element>>();
+ compiler.enqueuer.resolution.resolvedElements.forEach(
+ (Element element, TreeElementMapping mapping) {
+ element = element.implementation;
+ if (element.impliesType()) return;
+ assert(invariant(element,
+ element.isField() ||
+ element.isFunction() ||
+ element.isGenerativeConstructor() ||
+ element.isGetter() ||
+ element.isSetter(),
+ message: 'Unexpected element kind: ${element.kind}'));
+ // TODO(ngeoffray): Not sure why the resolver would put a null
+ // mapping.
+ if (mapping == null) return;
+ if (element.isAbstract(compiler)) return;
+ // Put the other operators in buckets by length, later to be added in
+ // length order.
+ int length = mapping.selectors.length;
+ max = length > max ? length : max;
+ Set<Element> set = methodSizes.putIfAbsent(
+ length, () => new LinkedHashSet<Element>());
+ set.add(element);
+ });
+
+ List<Element> result = <Element>[];
+
+ for (int i = 0; i <= max; i++) {
+ Set<Element> set = methodSizes[i];
+ if (set != null) {
+ result.addAll(set);
+ }
+ }
+ return result;
+ }
+
+ void clear() {
+ allocatedCalls.clear();
+ defaultTypeOfParameter.clear();
+ types.typeInformations.values.forEach((info) => info.clear());
+ types.allocatedTypes.clear();
+ types.concreteTypes.clear();
+ }
+
+ Iterable<Element> getCallersOf(Element element) {
+ if (compiler.disableTypeInference) {
+ throw new UnsupportedError(
+ "Cannot query the type inferrer when type inference is disabled.");
+ }
+ return types.getInferredTypeOf(element).callers.keys;
+ }
+
+ /**
+ * Returns the type of [element] when being called with [selector].
+ */
+ TypeInformation typeOfElementWithSelector(Element element,
+ Selector selector) {
+ if (element.name == Compiler.NO_SUCH_METHOD
+ && selector.name != element.name) {
+ // An invocation can resolve to a [noSuchMethod], in which case
+ // we get the return type of [noSuchMethod].
+ return returnTypeOfElement(element);
+ } else if (selector.isGetter()) {
+ if (element.isFunction()) {
+ // [functionType] is null if the inferrer did not run.
+ return types.functionType == null
+ ? types.dynamicType
+ : types.functionType;
+ } else if (element.isField()) {
+ return typeOfElement(element);
+ } else if (Elements.isUnresolved(element)) {
+ return types.dynamicType;
+ } else {
+ assert(element.isGetter());
+ return returnTypeOfElement(element);
+ }
+ } else if (element.isGetter() || element.isField()) {
+ assert(selector.isCall() || selector.isSetter());
+ return types.dynamicType;
+ } else {
+ return returnTypeOfElement(element);
+ }
+ }
+}
+
+class TypeGraphInferrer implements TypesInferrer {
+ TypeGraphInferrerEngine inferrer;
+ final Compiler compiler;
+ TypeGraphInferrer(Compiler this.compiler);
+
+ String get name => 'Graph inferrer';
+
+ void analyzeMain(_) {
+ inferrer = new TypeGraphInferrerEngine(compiler);
+ inferrer.runOverAllElements();
+ }
+
+ TypeMask getReturnTypeOfElement(Element element) {
+ if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
+ // Currently, closure calls return dynamic.
+ if (element is! FunctionElement) return compiler.typesTask.dynamicType;
+ return inferrer.types.getInferredTypeOf(element).type;
+ }
+
+ TypeMask getTypeOfElement(Element element) {
+ if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
+ // The inferrer stores the return type for a function, so we have to
+ // be careful to not return it here.
+ if (element is FunctionElement) return compiler.typesTask.functionType;
+ return inferrer.types.getInferredTypeOf(element).type;
+ }
+
+ TypeMask getTypeOfNode(Element owner, Node node) {
+ if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
+ return inferrer.types.allocatedContainers[node].type;
+ }
+
+ TypeMask getTypeOfSelector(Selector selector) {
+ if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
+ // Bailout for closure calls. We're not tracking types of
+ // closures.
+ if (selector.isClosureCall()) return compiler.typesTask.dynamicType;
+ if (selector.isSetter() || selector.isIndexSet()) {
+ return compiler.typesTask.dynamicType;
+ }
+ if (returnsElementType(selector)) {
+ ContainerTypeMask mask = selector.mask;
+ TypeMask elementType = mask.elementType;
+ return elementType == null ? compiler.typesTask.dynamicType : elementType;
+ }
+
+ TypeMask result = const TypeMask.nonNullEmpty();
+ Iterable<Element> elements = compiler.world.allFunctions.filter(selector);
+ for (Element element in elements) {
+ TypeMask type =
+ inferrer.typeOfElementWithSelector(element, selector).type;
+ result = result.union(type, compiler);
+ }
+ return result;
+ }
+
+ Iterable<TypeMask> get containerTypes {
+ if (compiler.disableTypeInference) {
+ throw new UnsupportedError(
+ "Cannot query the type inferrer when type inference is disabled.");
+ }
+ return inferrer.types.allocatedContainers.values.map((info) => info.type);
+ }
+
+ Iterable<Element> getCallersOf(Element element) {
+ if (compiler.disableTypeInference) {
+ throw new UnsupportedError(
+ "Cannot query the type inferrer when type inference is disabled.");
+ }
+ return inferrer.getCallersOf(element);
+ }
+
+ void clear() {
+ inferrer.clear();
+ }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
new file mode 100644
index 0000000..fc7bfb5
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -0,0 +1,661 @@
+// 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.
+
+part of type_graph_inferrer;
+
+/**
+ * Common class for all nodes in the graph. The current nodes are:
+ *
+ * - Concrete types
+ * - Elements
+ * - Call sites
+ * - Narrowing instructions
+ * - Phi instructions
+ * - Containers (for lists)
+ * - Type of the element in a container
+ *
+ * A node has a set of assignments and users. Assignments are used to
+ * compute the type of the node ([TypeInformation.refine]). Users are
+ * added to the inferrer's work queue when the type of the node
+ * changes.
+ */
+abstract class TypeInformation {
+ var /* List|Set */ users;
+ var /* List|ParameterAssignments */ assignments;
+
+ /// The type the inferrer has found for this [TypeInformation].
+ /// Initially empty.
+ TypeMask type = const TypeMask.nonNullEmpty();
+
+ /// We give up on inferencing for special elements, as well as for
+ /// complicated cyclic dependencies.
+ bool abandonInferencing = false;
+
+ /// Number of times this [TypeInformation] has changed type.
+ int refineCount = 0;
+
+ /// Whether this [TypeInformation] is currently in the inferrer's
+ /// work queue.
+ bool inQueue = false;
+
+ // TypeInformations are unique.
+ static int staticHashCode = 0;
+ final int hashCode = staticHashCode++;
+
+ bool get isConcrete => false;
+
+ TypeInformation([users, assignments])
+ : users = (users == null) ? new Set<TypeInformation>() : users,
+ assignments = (assignments == null) ? <TypeInformation>[] : assignments;
+
+
+ void addUser(TypeInformation user) {
+ assert(!user.isConcrete);
+ users.add(user);
+ }
+
+ void removeUser(TypeInformation user) {
+ assert(!user.isConcrete);
+ users.remove(user);
+ }
+
+ void addAssignment(TypeInformation assignment) {
+ if (abandonInferencing) return;
+ // Cheap one-level cycle detection.
+ if (assignment == this) return;
+ assignments.add(assignment);
+ assignment.addUser(this);
+ }
+
+ void removeAssignment(TypeInformation assignment) {
+ if (!abandonInferencing) {
+ assignments.remove(assignment);
+ }
+ // We can have multiple assignments of the same [TypeInformation].
+ if (!assignments.contains(assignment)) {
+ assignment.removeUser(this);
+ }
+ }
+
+ TypeMask refine(TypeGraphInferrerEngine inferrer) {
+ return type;
+ }
+
+ void giveUp(TypeGraphInferrerEngine inferrer) {
+ abandonInferencing = true;
+ type = inferrer.types.dynamicType.type;
+ assignments = const <TypeInformation>[];
+ }
+
+ void clear() {
+ assignments = const <TypeInformation>[];
+ users = const <TypeInformation>[];
+ }
+}
+
+/**
+ * Parameters of instance functions behave differently than other
+ * elements because the inferrer may remove assignments. This happens
+ * when the receiver of a dynamic call site can be refined
+ * to a type where we know more about which instance method is being
+ * called.
+ */
+class ParameterAssignments extends IterableBase<TypeInformation> {
+ final Map<TypeInformation, int> assignments =
+ new HashMap<TypeInformation, int>();
+
+ void remove(TypeInformation info) {
+ int existing = assignments[info];
+ if (existing == null) return;
+ if (existing == 1) {
+ assignments.remove(info);
+ } else {
+ assignments[info] = existing - 1;
+ }
+ }
+
+ void add(TypeInformation info) {
+ int existing = assignments[info];
+ if (existing == null) {
+ assignments[info] = 1;
+ } else {
+ assignments[info] = existing + 1;
+ }
+ }
+
+ Iterator<TypeInformation> get iterator => assignments.keys.iterator;
+ Iterable<TypeInformation> where(Function f) => assignments.keys.where(f);
+
+ bool contains(TypeInformation info) => assignments.containsKey(info);
+
+ String toString() => assignments.keys.toList().toString();
+}
+
+/**
+ * A node representing a resolved element of the program. The kind of
+ * elements that need an [ElementTypeRepresentation] are:
+ *
+ * - Functions (including getters and setters)
+ * - Constructors (factory or generative)
+ * - Fields
+ * - Parameters
+ * - Local variables mutated in closures
+ *
+ * The [ElementTypeInformation] of a function and a constructor is its
+ * return type.
+ *
+ * Note that a few elements of these kinds must be treated specially,
+ * and they are dealt in [ElementTypeInformation.handleSpecialCase]:
+ *
+ * - Parameters of closures, [noSuchMethod] and [call] instance
+ * methods: we currently do not infer types for those.
+ *
+ * - Fields and parameters being assigned by synthesized calls done by
+ * the backend: we do not know what types the backend will use.
+ *
+ * - Native functions and fields: because native methods contain no Dart
+ * code, and native fields do not have Dart assignments, we just
+ * trust their type annotation.
+ *
+ */
+class ElementTypeInformation extends TypeInformation {
+ final Element element;
+ final Map<Element, Set<Spannable>> callers =
+ new Map<Element, Set<Spannable>>();
+
+ ElementTypeInformation.internal(this.element, assignments)
+ : super(null, assignments);
+
+ factory ElementTypeInformation(Element element) {
+ var assignments = null;
+ if (element.enclosingElement.isInstanceMember()
+ && (element.isParameter() || element.isFieldParameter())) {
+ assignments = new ParameterAssignments();
+ }
+ return new ElementTypeInformation.internal(element, assignments);
+ }
+
+ void addCall(Element caller, Spannable node) {
+ callers.putIfAbsent(caller, () => new Set<Spannable>()).add(node);
+ }
+
+ void removeCall(Element caller, Spannable node) {
+ Set<Spannable> calls = callers[caller];
+ if (calls == null) return;
+ calls.remove(node);
+ if (calls.isEmpty) {
+ callers.remove(caller);
+ }
+ }
+
+ TypeMask handleSpecialCases(TypeGraphInferrerEngine inferrer) {
+ if (abandonInferencing) {
+ return type;
+ }
+ if (element.isParameter()) {
+ Element enclosing = element.enclosingElement;
+ if (Elements.isLocal(enclosing)) {
+ // Do not infer types for parameters of closures.
+ giveUp(inferrer);
+ return type;
+ } else if (enclosing.isInstanceMember()
+ && (enclosing.name == Compiler.NO_SUCH_METHOD
+ || enclosing.name == Compiler.CALL_OPERATOR_NAME)) {
+ // Do not infer types for parameters of [noSuchMethod] and
+ // [call] instance methods.
+ giveUp(inferrer);
+ return type;
+ }
+ }
+ if (element.isField()
+ || element.isParameter()
+ || element.isFieldParameter()) {
+ if (!inferrer.compiler.backend.canBeUsedForGlobalOptimizations(element)) {
+ // Do not infer types for fields and parameters being assigned
+ // by synthesized calls.
+ giveUp(inferrer);
+ return type;
+ }
+ }
+ if (inferrer.isNativeElement(element)) {
+ // Use the type annotation as the type for native elements. We
+ // also give up on inferring to make sure this element never
+ // goes in the work queue.
+ giveUp(inferrer);
+ if (element.isField()) {
+ InterfaceType rawType = element.computeType(inferrer.compiler).asRaw();
+ return rawType.treatAsDynamic
+ ? inferrer.types.dynamicType.type
+ : new TypeMask.subtype(rawType);
+ } else {
+ assert(element.isFunction()
+ || element.isGetter()
+ || element.isSetter());
+ var elementType = element.computeType(inferrer.compiler);
+ if (elementType.kind != TypeKind.FUNCTION) {
+ return type;
+ } else {
+ return inferrer.typeOfNativeBehavior(
+ native.NativeBehavior.ofMethod(element, inferrer.compiler)).type;
+ }
+ }
+ }
+ return null;
+ }
+
+ TypeMask potentiallyNarrowType(TypeMask mask,
+ TypeGraphInferrerEngine inferrer) {
+ Compiler compiler = inferrer.compiler;
+ if (!compiler.trustTypeAnnotations && !compiler.enableTypeAssertions) {
+ return mask;
+ }
+ if (element.isGenerativeConstructor() || element.isSetter()) return mask;
+ var type = element.computeType(compiler);
+ if (element.isFunction()
+ || element.isGetter()
+ || element.isFactoryConstructor()) {
+ type = type.returnType;
+ }
+ return new TypeMaskSystem(compiler).narrowType(mask, type);
+ }
+
+ TypeMask refine(TypeGraphInferrerEngine inferrer) {
+ TypeMask special = handleSpecialCases(inferrer);
+ if (special != null) return potentiallyNarrowType(special, inferrer);
+ return potentiallyNarrowType(
+ inferrer.types.computeTypeMask(assignments), inferrer);
+ }
+
+ String toString() => 'Element $element $type';
+}
+
+/**
+ * A [CallSiteTypeInformation] is a call found in the AST, or a
+ * synthesized call for implicit calls in Dart (such as forwarding
+ * factories). The [call] field is a [Node] for the former, and an
+ * [Element] for the latter.
+ *
+ * In the inferrer graph, [CallSiteTypeInformation] nodes do not have
+ * any assignment. They rely on the [caller] field for static calls,
+ * and [selector] and [receiver] fields for dynamic calls.
+ */
+abstract class CallSiteTypeInformation extends TypeInformation {
+ final Spannable call;
+ final Element caller;
+ final Selector selector;
+ final ArgumentsTypes arguments;
+ final bool inLoop;
+
+ CallSiteTypeInformation(
+ this.call,
+ this.caller,
+ this.selector,
+ this.arguments,
+ this.inLoop) : super(null, const <TypeInformation>[]);
+
+ String toString() => 'Call site $call $type';
+
+ /// Add [this] to the graph being computed by [engine].
+ void addToGraph(TypeGraphInferrerEngine engine);
+
+ /// Return an iterable over the targets of this call.
+ Iterable<Element> get callees;
+}
+
+class StaticCallSiteTypeInformation extends CallSiteTypeInformation {
+ final Element calledElement;
+
+ StaticCallSiteTypeInformation(
+ Spannable call,
+ Element enclosing,
+ this.calledElement,
+ Selector selector,
+ ArgumentsTypes arguments,
+ bool inLoop) : super(call, enclosing, selector, arguments, inLoop);
+
+ void addToGraph(TypeGraphInferrerEngine inferrer) {
+ ElementTypeInformation callee =
+ inferrer.types.getInferredTypeOf(calledElement);
+ callee.addCall(caller, call);
+ callee.addUser(this);
+ if (arguments != null) {
+ arguments.forEach((info) => info.addUser(this));
+ }
+ inferrer.updateParameterAssignments(
+ this, calledElement, arguments, selector, remove: false, init: true);
+ }
+
+ bool get isSynthesized {
+ // Some calls do not have a corresponding node, for example
+ // fowarding factory constructors, or synthesized super
+ // constructor calls. We synthesize these calls but do
+ // not create a selector for them.
+ return selector == null;
+ }
+
+ TypeMask refine(TypeGraphInferrerEngine inferrer) {
+ if (isSynthesized) {
+ assert(arguments != null);
+ return inferrer.types.getInferredTypeOf(calledElement).type;
+ } else {
+ return inferrer.typeOfElementWithSelector(calledElement, selector).type;
+ }
+ }
+
+ Iterable<Element> get callees => [calledElement.implementation];
+}
+
+class DynamicCallSiteTypeInformation extends CallSiteTypeInformation {
+ final TypeInformation receiver;
+ /// Cached targets of this call.
+ Iterable<Element> targets;
+
+ DynamicCallSiteTypeInformation(
+ Spannable call,
+ Element enclosing,
+ Selector selector,
+ this.receiver,
+ ArgumentsTypes arguments,
+ bool inLoop) : super(call, enclosing, selector, arguments, inLoop);
+
+ void addToGraph(TypeGraphInferrerEngine inferrer) {
+ assert(receiver != null);
+ Selector typedSelector = computeTypedSelector(inferrer);
+ targets = inferrer.compiler.world.allFunctions.filter(typedSelector);
+ receiver.addUser(this);
+ if (arguments != null) {
+ arguments.forEach((info) => info.addUser(this));
+ }
+ for (Element element in targets) {
+ ElementTypeInformation callee = inferrer.types.getInferredTypeOf(element);
+ callee.addCall(caller, call);
+ callee.addUser(this);
+ inferrer.updateParameterAssignments(
+ this, element, arguments, typedSelector, remove: false, init: true);
+ }
+ }
+
+ Iterable<Element> get callees => targets.map((e) => e.implementation);
+
+ Selector computeTypedSelector(TypeGraphInferrerEngine inferrer) {
+ TypeMask receiverType = receiver.type;
+ if (selector.mask != receiverType) {
+ return receiverType == inferrer.compiler.typesTask.dynamicType
+ ? selector.asUntyped
+ : new TypedSelector(receiverType, selector);
+ } else {
+ return selector;
+ }
+ }
+
+ bool hasOnePositionalArgumentWithType(TypeMask type) {
+ return arguments.named.isEmpty
+ && arguments.positional.length == 1
+ && arguments.positional[0].type == type;
+ }
+
+ /**
+ * We optimize certain operations on the [int] class because we know
+ * more about their return type than the actual Dart code. For
+ * example, we know int + int returns an int. The Dart code for
+ * [int.operator+] only says it returns a [num].
+ */
+ TypeInformation handleIntrisifiedSelector(Selector selector,
+ TypeGraphInferrerEngine inferrer) {
+ if (!inferrer.compiler.backend.intImplementation.isResolved) return null;
+ TypeMask intType = inferrer.compiler.typesTask.intType;
+ TypeMask emptyType = const TypeMask.nonNullEmpty();
+ if (selector.mask != intType) return null;
+ if (!selector.isCall() && !selector.isOperator()) return null;
+ if (!arguments.named.isEmpty) return null;
+ if (arguments.positional.length > 1) return null;
+
+ SourceString name = selector.name;
+ if (name == const SourceString('*')
+ || name == const SourceString('+')
+ || name == const SourceString('%')
+ || name == const SourceString('remainder')) {
+ if (hasOnePositionalArgumentWithType(intType)) {
+ return inferrer.types.intType;
+ } else if (hasOnePositionalArgumentWithType(emptyType)) {
+ return inferrer.types.nonNullEmptyType;
+ } else {
+ return null;
+ }
+ } else if (name == const SourceString('-')) {
+ if (arguments.hasNoArguments()) return inferrer.types.intType;
+ if (hasOnePositionalArgumentWithType(intType)) {
+ return inferrer.types.intType;
+ } else if (hasOnePositionalArgumentWithType(emptyType)) {
+ return inferrer.types.nonNullEmptyType;
+ }
+ return null;
+ } else if (name == const SourceString('abs')) {
+ return arguments.hasNoArguments() ? inferrer.types.intType : null;
+ }
+ return null;
+ }
+
+ TypeMask refine(TypeGraphInferrerEngine inferrer) {
+ Iterable<Element> oldTargets = targets;
+ Selector typedSelector = computeTypedSelector(inferrer);
+ inferrer.updateSelectorInTree(caller, call, typedSelector);
+ targets = inferrer.compiler.world.allFunctions.filter(typedSelector);
+
+ // Walk over the found targets, and compute the joined union type mask
+ // for all these targets.
+ TypeMask newType = inferrer.types.computeTypeMask(targets.map((element) {
+ if (!oldTargets.contains(element)) {
+ ElementTypeInformation callee =
+ inferrer.types.getInferredTypeOf(element);
+ callee.addCall(caller, call);
+ callee.addUser(this);
+ inferrer.updateParameterAssignments(
+ this, element, arguments, typedSelector, remove: false);
+ }
+
+ if (returnsElementType(typedSelector)) {
+ // Find the [ElementInContainerTypeInformation] node and tell
+ // that this node is a user of it. Later, when the element
+ // type changes, this node will be notified.
+ ContainerTypeMask mask = receiver.type;
+ ContainerTypeInformation container =
+ inferrer.types.allocatedContainers[mask.allocationNode];
+ ElementInContainerTypeInformation element = container.elementType;
+ if (!element.users.contains(element)) {
+ element.addUser(this);
+ }
+ return element;
+ } else {
+ TypeInformation info =
+ handleIntrisifiedSelector(typedSelector, inferrer);
+ if (info != null) return info;
+ return inferrer.typeOfElementWithSelector(element, typedSelector);
+ }
+ }));
+
+ // Walk over the old targets, and remove calls that cannot happen
+ // anymore.
+ oldTargets.forEach((element) {
+ if (!targets.contains(element)) {
+ ElementTypeInformation callee =
+ inferrer.types.getInferredTypeOf(element);
+ callee.removeCall(caller, call);
+ callee.removeUser(this);
+ inferrer.updateParameterAssignments(
+ this, element, arguments, typedSelector, remove: true);
+ }
+ });
+ return newType;
+ }
+
+ void giveUp(TypeGraphInferrerEngine inferrer) {
+ inferrer.updateSelectorInTree(caller, call, selector);
+ Iterable<Element> oldTargets = targets;
+ targets = inferrer.compiler.world.allFunctions.filter(selector);
+ for (Element element in targets) {
+ if (!oldTargets.contains(element)) {
+ ElementTypeInformation callee =
+ inferrer.types.getInferredTypeOf(element);
+ callee.addCall(caller, call);
+ inferrer.updateParameterAssignments(
+ this, element, arguments, selector, remove: false);
+ }
+ }
+ super.giveUp(inferrer);
+ }
+
+ String toString() => 'Call site $call ${receiver.type} $type';
+}
+
+class ClosureCallSiteTypeInformation extends CallSiteTypeInformation {
+ final TypeInformation closure;
+
+ ClosureCallSiteTypeInformation(
+ Spannable call,
+ Element enclosing,
+ Selector selector,
+ this.closure,
+ ArgumentsTypes arguments,
+ bool inLoop) : super(call, enclosing, selector, arguments, inLoop);
+
+ void addToGraph(TypeGraphInferrerEngine inferrer) {
+ arguments.forEach((info) => info.addUser(this));
+ }
+
+ TypeMask refine(TypeGraphInferrerEngine inferrer) {
+ return inferrer.types.dynamicType.type;
+ }
+
+ Iterable<Element> get callees {
+ throw new UnsupportedError("Cannot compute callees of a closure.");
+ }
+
+ String toString() => 'Closure call $call on $closure';
+}
+
+/**
+ * A [ConcreteTypeInformation] represents a type that needed
+ * to be materialized during the creation of the graph. For example,
+ * literals, [:this:] or [:super:] need a [ConcreteTypeInformation].
+ *
+ * [ConcreteTypeInformation] nodes have no assignment. Also, to save
+ * on memory, we do not add users to [ConcreteTypeInformation] nodes,
+ * because we know such node will never be refined to a different
+ * type.
+ */
+class ConcreteTypeInformation extends TypeInformation {
+ ConcreteTypeInformation(TypeMask type)
+ : super(const <TypeInformation>[], const <TypeInformation>[]) {
+ this.type = type;
+ }
+
+ bool get isConcrete => true;
+
+ void addUser(TypeInformation user) {
+ // Nothing to do, a concrete type does not get updated so never
+ // needs to notify its users.
+ }
+
+ void removeUser(TypeInformation user) {
+ }
+
+ void addAssignment(TypeInformation assignment) {
+ }
+
+ void removeAssignment(TypeInformation assignment) {
+ assert(false);
+ }
+
+ String toString() => 'Type $type';
+}
+
+/**
+ * A [NarrowTypeInformation] narrows a [TypeInformation] to a type,
+ * represented in [typeAnnotation].
+ *
+ * A [NarrowTypeInformation] node has only one assignment: the
+ * [TypeInformation] it narrows.
+ *
+ * [NarrowTypeInformation] nodes are created for:
+ *
+ * - Code after `is` and `as` checks, where we have more information
+ * on the type of the right hand side of the expression.
+ *
+ * - Code after a dynamic call, where we have more information on the
+ * type of the receiver: it can only be of a class that holds a
+ * potential target of this dynamic call.
+ *
+ * - In checked mode, after a type annotation, we have more
+ * information on the type of a local.
+ */
+class NarrowTypeInformation extends TypeInformation {
+ final TypeMask typeAnnotation;
+
+ NarrowTypeInformation(narrowedType, this.typeAnnotation) {
+ addAssignment(narrowedType);
+ }
+
+ TypeMask refine(TypeGraphInferrerEngine inferrer) {
+ return assignments[0].type.intersection(typeAnnotation, inferrer.compiler);
+ }
+
+ String toString() => 'Narrow ${assignments.first} to $typeAnnotation $type';
+}
+
+/**
+ * A [ContainerTypeInformation] is a [ConcreteTypeInformation] created
+ * for each `List` instantiations.
+ */
+class ContainerTypeInformation extends ConcreteTypeInformation {
+ final TypeInformation elementType;
+
+ ContainerTypeInformation(containerType, this.elementType)
+ : super(containerType);
+
+ void addUser(TypeInformation user) {
+ elementType.addUser(user);
+ }
+
+ String toString() => 'Container type $type';
+}
+
+/**
+ * An [ElementInContainerTypeInformation] holds the common type of the
+ * elements in a [ContainerTypeInformation].
+ */
+class ElementInContainerTypeInformation extends TypeInformation {
+ final ContainerTypeMask container;
+
+ ElementInContainerTypeInformation(elementType, this.container) {
+ // [elementType] is not null for const lists.
+ if (elementType != null) addAssignment(elementType);
+ }
+
+ TypeMask refine(TypeGraphInferrerEngine inferrer) {
+ if (assignments.isEmpty) return inferrer.types.dynamicType.type;
+ return container.elementType =
+ inferrer.types.computeTypeMask(assignments);
+ }
+
+ String toString() => 'Element in container $type';
+}
+
+/**
+ * A [PhiElementTypeInformation] is an union of
+ * [ElementTypeInformation], that is local to a method.
+ */
+class PhiElementTypeInformation extends TypeInformation {
+ final Node branchNode;
+ final bool isLoopPhi;
+ final Element element;
+
+ PhiElementTypeInformation(this.branchNode, this.isLoopPhi, this.element);
+
+ TypeMask refine(TypeGraphInferrerEngine inferrer) {
+ return inferrer.types.computeTypeMask(assignments);
+ }
+
+ String toString() => 'Phi $element $type';
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js/builder.dart b/sdk/lib/_internal/compiler/implementation/js/builder.dart
index b0424c6..36433e8 100644
--- a/sdk/lib/_internal/compiler/implementation/js/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/builder.dart
@@ -129,6 +129,14 @@
throw new ArgumentError('expression should be an empty Map');
}
return new ObjectInitializer([]);
+ } else if (expression is List) {
+ var values = new List<ArrayElement>(expression.length);
+ int index = 0;
+ for (var entry in expression) {
+ values[index] = new ArrayElement(index, toExpression(entry));
+ index++;
+ }
+ return new ArrayInitializer(values.length, values);
} else {
throw new ArgumentError('expression should be an Expression, '
'a String, a num, a bool, or a Map');
diff --git a/sdk/lib/_internal/compiler/implementation/js/printer.dart b/sdk/lib/_internal/compiler/implementation/js/printer.dart
index cf61768..a21e713 100644
--- a/sdk/lib/_internal/compiler/implementation/js/printer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/printer.dart
@@ -104,18 +104,26 @@
}
}
- void recordSourcePosition(var position) {
- if (position != null) {
- outBuffer.setSourceLocation(position);
+ void beginSourceRange(Node node) {
+ if (node.sourcePosition != null) {
+ outBuffer.beginMappedRange();
+ outBuffer.setSourceLocation(node.sourcePosition);
+ }
+ }
+
+ void endSourceRange(Node node) {
+ if (node.endSourcePosition != null) {
+ outBuffer.setSourceLocation(node.endSourcePosition);
+ }
+ if (node.sourcePosition != null) {
+ outBuffer.endMappedRange();
}
}
visit(Node node) {
- if (node.sourcePosition != null) outBuffer.beginMappedRange();
- recordSourcePosition(node.sourcePosition);
+ beginSourceRange(node);
node.accept(this);
- recordSourcePosition(node.endSourcePosition);
- if (node.sourcePosition != null) outBuffer.endMappedRange();
+ endSourceRange(node);
}
visitCommaSeparated(List<Node> nodes, int hasRequiredType,
@@ -165,8 +173,10 @@
void blockOutWithoutBraces(Node node) {
if (node is Block) {
+ beginSourceRange(node);
Block block = node;
block.statements.forEach(blockOutWithoutBraces);
+ endSourceRange(node);
} else {
visit(node);
}
@@ -174,6 +184,7 @@
void blockOut(Block node, bool shouldIndent, bool needsNewline) {
if (shouldIndent) indent();
+ beginSourceRange(node);
out("{");
lineOut();
indentLevel++;
@@ -181,6 +192,7 @@
indentLevel--;
indent();
out("}");
+ endSourceRange(node);
if (needsNewline) lineOut();
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index cbdb7ab..b2cd1d9 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -1577,6 +1577,9 @@
/// Called when [:const Symbol(name):] is seen.
void registerConstSymbol(String name, TreeElements elements) {
symbolsUsed.add(name);
+ if (name.endsWith('=')) {
+ symbolsUsed.add(name.substring(0, name.length - 1));
+ }
}
/// Called when [:new Symbol(...):] is seen.
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 180542a..a284cbe 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -859,70 +859,6 @@
fun);
}
- jsAst.Fun get finishIsolateConstructorFunction_NO_CSP {
- String isolate = namer.isolateName;
- // We replace the old Isolate function with a new one that initializes
- // all its field with the initial (and often final) value of all globals.
- // This has two advantages:
- // 1. the properties are in the object itself (thus avoiding to go through
- // the prototype when looking up globals.
- // 2. a new isolate goes through a (usually well optimized) constructor
- // function of the form: "function() { this.x = ...; this.y = ...; }".
- //
- // Example: If [isolateProperties] is an object containing: x = 3 and
- // A = function A() { /* constructor of class A. */ }, then we generate:
- // str = "{
- // var isolateProperties = Isolate.$isolateProperties;
- // this.x = isolateProperties.x;
- // this.A = isolateProperties.A;
- // }";
- // which is then dynamically evaluated:
- // var newIsolate = new Function(str);
- //
- // We also copy over old values like the prototype, and the
- // isolateProperties themselves.
-
- List copyFinishClasses = [];
- if (needsDefineClass) {
- copyFinishClasses.add(
- js('newIsolate.$finishClassesProperty = '
- ' oldIsolate.$finishClassesProperty'));
- }
-
- // function(oldIsolate) {
- return js.fun('oldIsolate', [
- js('var isolateProperties = oldIsolate.${namer.isolatePropertiesName}'),
-
- js('var isolatePrototype = oldIsolate.prototype'),
- js('var str = "{\\n"'),
- js('str += "var properties = '
- 'arguments.callee.${namer.isolatePropertiesName};\\n"'),
- js('var hasOwnProperty = Object.prototype.hasOwnProperty'),
-
- // for (var staticName in isolateProperties) {
- js.forIn('staticName', 'isolateProperties', [
- js.if_('hasOwnProperty.call(isolateProperties, staticName)', [
- js('str += ("this." + staticName + "= properties." + staticName + '
- '";\\n")')
- ])
- ]),
-
- js('str += "}\\n"'),
-
- js('var newIsolate = new Function(str)'),
- js('newIsolate.prototype = isolatePrototype'),
- js('isolatePrototype.constructor = newIsolate'),
- js('newIsolate.${namer.isolatePropertiesName} = isolateProperties'),
- // TODO(ahe): Only copy makeConstantList when it is used.
- js('newIsolate.makeConstantList = oldIsolate.makeConstantList'),
- ]..addAll(copyFinishClasses)
- ..addAll([
-
- // return newIsolate;
- js.return_('newIsolate')
- ]));
- }
-
jsAst.Fun get finishIsolateConstructorFunction {
// We replace the old Isolate function with a new one that initializes
// all its fields with the initial (and often final) value of all globals.
@@ -1198,8 +1134,10 @@
// canonicalized, we would still need this cache: a typed selector
// on A and a typed selector on B could yield the same stub.
Set<String> generatedStubNames = new Set<String>();
- if (compiler.enabledFunctionApply
- && member.name == namer.closureInvocationSelectorName) {
+ bool isClosureInvocation =
+ member.name == namer.closureInvocationSelectorName;
+ if (backend.isNeededForReflection(member) ||
+ (compiler.enabledFunctionApply && isClosureInvocation)) {
// If [Function.apply] is called, we pessimistically compile all
// possible stubs for this closure.
FunctionSignature signature = member.computeSignature(compiler);
@@ -1209,7 +1147,7 @@
for (Selector selector in selectors) {
addParameterStub(member, selector, defineStub, generatedStubNames);
}
- if (signature.optionalParametersAreNamed) {
+ if (signature.optionalParametersAreNamed && isClosureInvocation) {
addCatchAllParameterStub(member, signature, defineStub);
}
} else {
@@ -1224,8 +1162,8 @@
Set<Selector> computeSeenNamedSelectors(FunctionElement element) {
Set<Selector> selectors = compiler.codegenWorld.invokedNames[element.name];
- if (selectors == null) return null;
Set<Selector> result = new Set<Selector>();
+ if (selectors == null) return result;
for (Selector selector in selectors) {
if (!selector.applies(element, compiler)) continue;
result.add(selector);
@@ -1329,6 +1267,11 @@
var reflectable =
js(backend.isAccessibleByReflection(member) ? '1' : '0');
builder.addProperty('+$reflectionName', reflectable);
+ jsAst.Node defaultValues = reifyDefaultArguments(member);
+ if (defaultValues != null) {
+ String unmangledName = member.name.slowToString();
+ builder.addProperty('*$unmangledName', defaultValues);
+ }
}
code = backend.generatedBailoutCode[member];
if (code != null) {
@@ -1337,7 +1280,7 @@
FunctionElement function = member;
FunctionSignature parameters = function.computeSignature(compiler);
if (!parameters.optionalParameters.isEmpty) {
- addParameterStubs(member, builder.addProperty);
+ addParameterStubs(function, builder.addProperty);
}
} else if (!member.isField()) {
compiler.internalError('unexpected kind: "${member.kind}"',
@@ -1420,9 +1363,19 @@
requiredParameterCount,
names);
namedArguments = namedParametersAsReflectionNames(selector);
+ } else {
+ // Named parameters are handled differently by mirrors. For unnamed
+ // parameters, they are actually required if invoked
+ // reflectively. Also, if you have a method c(x) and c([x]) they both
+ // get the same mangled name, so they must have the same reflection
+ // name.
+ requiredParameterCount += optionalParameterCount;
+ optionalParameterCount = 0;
}
}
String suffix =
+ // TODO(ahe): We probably don't need optionalParameterCount in the
+ // reflection name.
'$name:$requiredParameterCount:$optionalParameterCount'
'$namedArguments';
return (isConstructor) ? 'new $suffix' : suffix;
@@ -1440,9 +1393,9 @@
}
String namedParametersAsReflectionNames(Selector selector) {
- if (selector.orderedNamedArguments.isEmpty) return '';
- String names =
- selector.orderedNamedArguments.map((x) => x.slowToString()).join(':');
+ if (selector.getOrderedNamedArguments().isEmpty) return '';
+ String names = selector.getOrderedNamedArguments().map(
+ (x) => x.slowToString()).join(':');
return ':$names';
}
@@ -1516,19 +1469,18 @@
builder.addProperty(operatorSignature, encoding);
}
- void generateSubstitution(Element other, {bool emitNull: false}) {
+ void generateSubstitution(ClassElement cls, {bool emitNull: false}) {
+ if (cls.typeVariables.isEmpty) return;
RuntimeTypes rti = backend.rti;
jsAst.Expression expression;
- bool needsNativeCheck = nativeEmitter.requiresNativeIsCheck(other);
- if (other.kind == ElementKind.CLASS) {
- expression = rti.getSupertypeSubstitution(
- classElement, other, alwaysGenerateFunction: true);
- if (expression == null && (emitNull || needsNativeCheck)) {
- expression = new jsAst.LiteralNull();
- }
+ bool needsNativeCheck = nativeEmitter.requiresNativeIsCheck(cls);
+ expression = rti.getSupertypeSubstitution(
+ classElement, cls, alwaysGenerateFunction: true);
+ if (expression == null && (emitNull || needsNativeCheck)) {
+ expression = new jsAst.LiteralNull();
}
if (expression != null) {
- builder.addProperty(namer.substitutionName(other), expression);
+ builder.addProperty(namer.substitutionName(cls), expression);
}
}
@@ -2088,6 +2040,21 @@
builder.addProperty("@", metadata);
}
+ if (backend.isNeededForReflection(classElement)) {
+ Link typeVars = classElement.typeVariables;
+ List properties = [];
+ for (TypeVariableType typeVar in typeVars) {
+ properties.add(js.string(typeVar.name.slowToString()));
+ properties.add(js.toExpression(reifyType(typeVar.element.bound)));
+ }
+
+ ClassElement superclass = classElement.superclass;
+ bool hasSuper = superclass != null;
+ if ((!properties.isEmpty && !hasSuper) ||
+ (hasSuper && superclass.typeVariables != typeVars)) {
+ builder.addProperty('<>', new jsAst.ArrayInitializer.from(properties));
+ }
+ }
List<CodeBuffer> classBuffers = elementBuffers[classElement];
if (classBuffers == null) {
classBuffers = [];
@@ -2433,6 +2400,12 @@
if (reflectionName != null) {
var reflectable = backend.isAccessibleByReflection(element) ? 1 : 0;
buffer.write(',$n$n"+$reflectionName":${_}$reflectable');
+ jsAst.Node defaultValues = reifyDefaultArguments(element);
+ if (defaultValues != null) {
+ String unmangledName = element.name.slowToString();
+ buffer.write(',$n$n"*$unmangledName":${_}');
+ buffer.write(jsAst.prettyPrint(defaultValues, compiler));
+ }
}
jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
if (bailoutCode != null) {
@@ -3745,6 +3718,20 @@
});
}
+ jsAst.Node reifyDefaultArguments(FunctionElement function) {
+ FunctionSignature signature = function.computeSignature(compiler);
+ if (signature.optionalParameterCount == 0) return null;
+ List<int> defaultValues = <int>[];
+ for (Element element in signature.orderedOptionalParameters) {
+ Constant value =
+ compiler.constantHandler.initialVariableValues[element];
+ String stringRepresentation = (value == null) ? "null"
+ : jsAst.prettyPrint(constantReference(value), compiler).getText();
+ defaultValues.add(addGlobalMetadata(stringRepresentation));
+ }
+ return js.toExpression(defaultValues);
+ }
+
int reifyMetadata(MetadataAnnotation annotation) {
Constant value = annotation.value;
if (value == null) {
@@ -3827,26 +3814,6 @@
buffer.write('];$n');
}
- void emitConvertToFastObjectFunction_NO_CSP() {
- mainBuffer.add(r'''
-function convertToFastObject(properties) {
- function makeConstructor() {
- var str = "{\n";
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- for (var property in properties) {
- if (hasOwnProperty.call(properties, property)) {
- str += "this." + property + "= properties." + property + ";\n";
- }
- }
- str += "}\n";
- return new Function("properties", str);
- };
- var constructor = makeConstructor();
- return makeConstructor.prototype = new constructor(properties);
-}
-''');
- }
-
void emitConvertToFastObjectFunction() {
// Create an instance that uses 'properties' as prototype. This should make
// 'properties' a fast object.
@@ -4179,15 +4146,19 @@
buildPrecompiledFunction();
emitInitFunction(mainBuffer);
if (!areAnyElementsDeferred) {
- mainBuffer.add('})()$n');
+ mainBuffer.add('})()\n');
+ } else {
+ mainBuffer.add('\n');
}
compiler.assembledCode = mainBuffer.getText();
- outputSourceMap(mainBuffer, compiler.assembledCode, '');
+ outputSourceMap(compiler.assembledCode, '');
mainBuffer.write(
- jsAst.prettyPrint(precompiledFunctionAst, compiler).getText());
+ jsAst.prettyPrint(
+ precompiledFunctionAst, compiler,
+ allowVariableMinification: false).getText());
- compiler.outputProvider('precompiled', 'js')
+ compiler.outputProvider('', 'precompiled.js')
..add(mainBuffer.getText())
..close();
@@ -4293,7 +4264,7 @@
compiler.outputProvider('part', 'js')
..add(code)
..close();
- outputSourceMap(buffer, compiler.assembledCode, 'part');
+ outputSourceMap(compiler.assembledCode, 'part');
}
String buildGeneratedBy() {
@@ -4309,7 +4280,7 @@
return sourceMapBuilder.build(compiledFile);
}
- void outputSourceMap(CodeBuffer buffer, String code, String name) {
+ void outputSourceMap(String code, String name) {
if (!generateSourceMap) return;
SourceFile compiledFile = new SourceFile(null, compiler.assembledCode);
String sourceMap = buildSourceMap(mainBuffer, compiledFile);
@@ -4337,6 +4308,9 @@
String getReflectionDataParser() {
String metadataField = '"${namer.metadataField}"';
String reflectableField = namer.reflectableField;
+ String defaultValuesField = namer.defaultValuesField;
+ String methodsWithOptionalArgumentsField =
+ namer.methodsWithOptionalArgumentsField;
return '''
(function (reflectionData) {
'''
@@ -4395,6 +4369,13 @@
} else if (firstChar === "@") {
property = property.substring(1);
${namer.CURRENT_ISOLATE}[property][$metadataField] = element;
+ } else if (firstChar === "*") {
+ globalObject[previousProperty].$defaultValuesField = element;
+ var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
+ if (!optionalMethods) {
+ descriptor.$methodsWithOptionalArgumentsField = optionalMethods = {}
+ }
+ optionalMethods[property] = previousProperty;
} else if (typeof element === "function") {
globalObject[previousProperty = property] = element;
functions.push(property);
@@ -4414,6 +4395,13 @@
'''element[previousProp].$reflectableField = 1;
} else if (firstChar === "@" && prop !== "@") {
newDesc[prop.substring(1)][$metadataField] = element[prop];
+ } else if (firstChar === "*") {
+ newDesc[previousProp].$defaultValuesField = element[prop];
+ var optionalMethods = newDesc.$methodsWithOptionalArgumentsField;
+ if (!optionalMethods) {
+ newDesc.$methodsWithOptionalArgumentsField = optionalMethods={}
+ }
+ optionalMethods[prop] = previousProp;
} else {
newDesc[previousProp = prop] = element[prop];
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 10c423d..141cd89 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -219,6 +219,9 @@
final String metadataField = '@';
final String callCatchAllName = r'call$catchAll';
final String reflectableField = r'$reflectable';
+ final String defaultValuesField = r'$defaultValues';
+ final String methodsWithOptionalArgumentsField =
+ r'$methodsWithOptionalArguments';
/**
* Map from top-level or static elements to their unique identifiers provided
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 9ac6cfd..be9e3b7 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -538,8 +538,7 @@
}
if (!identical(e.kind, ElementKind.PREFIX)) {
compiler.withCurrentElement(e, () {
- compiler.reportWarning(new Identifier(e.position()),
- 'duplicated definition');
+ compiler.reportWarning(e, 'duplicated definition');
});
compiler.reportFatalError(
import.prefix,
@@ -553,8 +552,7 @@
prefixElement.imported.putIfAbsent(element.name, () => element);
if (!identical(existing, element)) {
compiler.withCurrentElement(existing, () {
- compiler.reportWarning(new Identifier(existing.position()),
- 'duplicated import');
+ compiler.reportWarning(existing, 'duplicated import');
});
compiler.withCurrentElement(element, () {
compiler.reportFatalError(
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 4135d0c..1fd0b73 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -1750,6 +1750,31 @@
}
return type;
}
+
+ Element defineElement(Node node, Element element,
+ {bool doAddToScope: true}) {
+ compiler.ensure(element != null);
+ mapping[node] = element;
+ if (doAddToScope) {
+ Element existing = scope.add(element);
+ if (existing != element) {
+ reportDuplicateDefinition(node, element, existing);
+ }
+ }
+ return element;
+ }
+
+ void reportDuplicateDefinition(/*Node|SourceString*/ name,
+ Spannable definition,
+ Spannable existing) {
+ compiler.reportError(
+ definition,
+ MessageKind.DUPLICATE_DEFINITION, {'name': name});
+ compiler.reportMessage(
+ compiler.spanFromSpannable(existing),
+ MessageKind.EXISTING_DEFINITION.error({'name': name}),
+ Diagnostic.INFO);
+ }
}
/**
@@ -1942,24 +1967,6 @@
return null;
}
- Element defineElement(Node node, Element element,
- {bool doAddToScope: true}) {
- compiler.ensure(element != null);
- mapping[node] = element;
- if (doAddToScope) {
- Element existing = scope.add(element);
- if (existing != element) {
- compiler.reportError(
- node, MessageKind.DUPLICATE_DEFINITION, {'name': node});
- compiler.reportMessage(
- compiler.spanFromSpannable(existing),
- MessageKind.EXISTING_DEFINITION.error({'name': node}),
- Diagnostic.INFO);
- }
- }
- return element;
- }
-
bool isNamedConstructor(Send node) => node.receiver != null;
Selector getRedirectingThisOrSuperConstructorSelector(Send node) {
@@ -2337,14 +2344,10 @@
if (namedArgument != null) {
SourceString source = namedArgument.name.source;
if (seenNamedArguments.containsKey(source)) {
- compiler.reportError(
+ reportDuplicateDefinition(
+ source,
argument,
- MessageKind.DUPLICATE_DEFINITION,
- {'name': source});
- compiler.reportMessage(
- compiler.spanFromSpannable(seenNamedArguments[source]),
- MessageKind.EXISTING_DEFINITION.error({'name': source}),
- Diagnostic.INFO);
+ seenNamedArguments[source]);
} else {
seenNamedArguments[source] = namedArgument;
}
@@ -2727,6 +2730,27 @@
} else {
visitor.variables.type = compiler.types.dynamicType;
}
+
+ Modifiers modifiers = node.modifiers;
+ void reportExtraModifier(String modifier) {
+ Node modifierNode;
+ for (var nodes = modifiers.nodes; !nodes.isEmpty; nodes = nodes.tail) {
+ if (modifier == nodes.head.asIdentifier().source.stringValue) {
+ modifierNode = nodes.head;
+ break;
+ }
+ }
+ assert(modifierNode != null);
+ compiler.reportError(modifierNode, MessageKind.EXTRANEOUS_MODIFIER,
+ {'modifier': modifier});
+ }
+ if (modifiers.isFinal() && (modifiers.isConst() || modifiers.isVar())) {
+ reportExtraModifier('final');
+ }
+ if (modifiers.isVar() && (modifiers.isConst() || node.type != null)) {
+ reportExtraModifier('var');
+ }
+
visitor.visit(node.definitions);
}
@@ -3356,12 +3380,17 @@
scope = new TypeDeclarationScope(scope, element);
resolveTypeVariableBounds(node.typeParameters);
- element.functionSignature = SignatureResolver.analyze(
+ FunctionSignature signature = SignatureResolver.analyze(
compiler, node.formals, node.returnType, element,
defaultValuesAllowed: false);
+ element.functionSignature = signature;
- element.alias = compiler.computeFunctionType(
- element, element.functionSignature);
+ scope = new MethodScope(scope, element);
+ signature.forEachParameter((Element element) {
+ defineElement(element.parseNode(compiler), element);
+ });
+
+ element.alias = compiler.computeFunctionType(element, signature);
void checkCyclicReference() {
var visitor = new TypedefCyclicVisitor(compiler, element);
@@ -4002,6 +4031,9 @@
if (node.modifiers.isConst()) {
error(node, MessageKind.FORMAL_DECLARED_CONST);
}
+ if (node.modifiers.isStatic()) {
+ error(node, MessageKind.FORMAL_DECLARED_STATIC);
+ }
if (currentDefinitions != null) {
cancel(node, 'function type parameters not supported');
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 9f0826b..6123f69 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -1267,13 +1267,19 @@
}
}
- // Don't inline if the return type was inferred to be non-null empty. This
- // means that the function always throws an exception.
- TypeMask returnType =
- compiler.typesTask.getGuaranteedReturnTypeOfElement(element);
- if (returnType != null && returnType.isEmpty && !returnType.isNullable) {
- isReachable = false;
- return false;
+ // A generative constructor body is not seen by global analysis,
+ // so we should not query for its type.
+ if (!element.isGenerativeConstructorBody()) {
+ // Don't inline if the return type was inferred to be non-null empty.
+ // This means that the function always throws an exception.
+ TypeMask returnType =
+ compiler.typesTask.getGuaranteedReturnTypeOfElement(element);
+ if (returnType != null
+ && returnType.isEmpty
+ && !returnType.isNullable) {
+ isReachable = false;
+ return false;
+ }
}
return true;
@@ -3277,7 +3283,7 @@
List<HInstruction> arguments) {
SourceString name = selector.name;
- ClassElement cls = currentElement.getEnclosingClass();
+ ClassElement cls = currentNonClosureClass;
Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
if (element.enclosingElement.declaration != compiler.objectClass) {
// Register the call as dynamic if [noSuchMethod] on the super
@@ -3286,8 +3292,11 @@
// [JSInvocationMirror._invokeOn].
compiler.enqueuer.codegen.registerSelectorUse(selector);
}
+ String publicName = name.slowToString();
+ if (selector.isSetter()) publicName += '=';
+
Constant nameConstant = constantSystem.createString(
- new DartString.literal(name.slowToString()), node);
+ new DartString.literal(publicName), node);
String internalName = backend.namer.invocationName(selector);
Constant internalNameConstant =
@@ -3345,15 +3354,19 @@
if (node.isPropertyAccess) {
push(buildInvokeSuper(selector, element, inputs));
} else if (element.isFunction() || element.isGenerativeConstructor()) {
- // TODO(5347): Try to avoid the need for calling [implementation] before
- // calling [addStaticSendArgumentsToList].
- FunctionElement function = element.implementation;
- bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
- function, inputs);
- if (!succeeded) {
+ if (selector.applies(element, compiler)) {
+ // TODO(5347): Try to avoid the need for calling [implementation] before
+ // calling [addStaticSendArgumentsToList].
+ FunctionElement function = element.implementation;
+ bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
+ function, inputs);
+ assert(succeeded);
+ push(buildInvokeSuper(selector, element, inputs));
+ } else if (element.isGenerativeConstructor()) {
generateWrongArgumentCountError(node, element, node.arguments);
} else {
- push(buildInvokeSuper(selector, element, inputs));
+ addGenericSendArgumentsToList(node.arguments, inputs);
+ generateSuperNoSuchMethodSend(node, selector, inputs);
}
} else {
HInstruction target = buildInvokeSuper(selector, element, inputs);
@@ -3929,8 +3942,13 @@
selector,
inputs,
isSetter: selector.isSetter() || selector.isIndexSet());
- instruction.instructionType =
- new HType.inferredReturnTypeForElement(element, compiler);
+ if (!element.isGetter() && selector.isGetter()) {
+ instruction.instructionType =
+ new HType.inferredTypeForElement(element, compiler);
+ } else {
+ instruction.instructionType =
+ new HType.inferredReturnTypeForElement(element, compiler);
+ }
instruction.sideEffects = compiler.world.getSideEffectsOfElement(element);
return instruction;
}
@@ -4004,7 +4022,8 @@
}
}
Selector setterSelector = elements.getSelector(node);
- if (Elements.isUnresolved(element)) {
+ if (Elements.isUnresolved(element)
+ || !setterSelector.applies(element, compiler)) {
generateSuperNoSuchMethodSend(
node, setterSelector, setterInputs);
pop();
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index f072081..2c22260 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -15,15 +15,11 @@
NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter;
- js.Fun buildJavaScriptFunction(FunctionElement element,
- List<js.Parameter> parameters,
- js.Block body) {
- js.Fun result = new js.Fun(parameters, body);
- // TODO(johnniwinther): remove the 'element.patch' hack.
- Element sourceElement = element.patch == null ? element : element.patch;
- SourceFile sourceFile = sourceElement.getCompilationUnit().script.file;
- Node expression =
- element.implementation.parseNode(backend.compiler);
+ js.Node attachPosition(js.Node node, Element element) {
+ // TODO(sra): Attaching positions might be cleaner if the source position
+ // was on a wrapping node.
+ SourceFile sourceFile = sourceFileOfElement(element);
+ Node expression = element.implementation.parseNode(backend.compiler);
Token beginToken;
Token endToken;
if (expression == null) {
@@ -36,12 +32,27 @@
// TODO(podivilov): find the right sourceFile here and remove offset checks
// below.
if (beginToken.charOffset < sourceFile.text.length) {
- result.sourcePosition = new SourceFileLocation(sourceFile, beginToken);
+ node.sourcePosition = new SourceFileLocation(sourceFile, beginToken);
}
if (endToken.charOffset < sourceFile.text.length) {
- result.endSourcePosition = new SourceFileLocation(sourceFile, endToken);
+ node.endSourcePosition = new SourceFileLocation(sourceFile, endToken);
}
- return result;
+ return node;
+ }
+
+ SourceFile sourceFileOfElement(Element element) {
+ // TODO(johnniwinther): remove the 'element.patch' hack.
+ FunctionElement functionElement = element.asFunctionElement();
+ if (functionElement != null && functionElement.patch != null) {
+ element = functionElement.patch;
+ }
+ return element.getCompilationUnit().script.file;
+ }
+
+ js.Fun buildJavaScriptFunction(FunctionElement element,
+ List<js.Parameter> parameters,
+ js.Block body) {
+ return attachPosition(new js.Fun(parameters, body), element);
}
CodeBuffer prettyPrint(js.Node node) {
@@ -63,7 +74,8 @@
SsaOptimizedCodeGenerator codegen =
new SsaOptimizedCodeGenerator(backend, work);
codegen.visitGraph(graph);
- return new js.Fun(codegen.parameters, codegen.body);
+ return new js.Fun(codegen.parameters,
+ attachPosition(codegen.body, work.element));
});
}
@@ -2449,7 +2461,12 @@
HInstruction input = node.checkedInput;
TypeMask receiver = input.instructionType.computeMask(compiler);
TypeMask mask = node.instructionType.computeMask(compiler);
- bool turnIntoNullCheck = mask.nullable() == receiver;
+ // Figure out if it is beneficial to turn this into a null check.
+ // V8 generally prefers 'typeof' checks, but for integers and
+ // indexable primitives we cannot compile this test into a single
+ // typeof check so the null check is cheaper.
+ bool turnIntoNullCheck = (mask.nullable() == receiver)
+ && (node.isInteger() || node.isIndexablePrimitive(compiler));
js.Expression test;
if (turnIntoNullCheck) {
use(input);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index 88ce60b..98e5a73 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -52,6 +52,18 @@
bool visitInstruction(HInstruction instruction) => false;
+ bool visitInvoke(HInvoke invoke) {
+ if (!invoke.isInterceptedCall) return false;
+ var interceptor = invoke.inputs[0];
+ if (interceptor is! HInterceptor) return false;
+ HInstruction constant = tryComputeConstantInterceptor(
+ invoke.inputs[1], interceptor.interceptedClasses);
+ if (constant != null) {
+ invoke.changeUse(interceptor, constant);
+ }
+ return false;
+ }
+
bool canUseSelfForInterceptor(HType receiverType,
Set<ClassElement> interceptedClasses) {
JavaScriptBackend backend = compiler.backend;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
index 9c5f1a9..8526f63 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
@@ -40,10 +40,6 @@
return null;
}
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return false;
- }
-
Operation operation(ConstantSystem constantSystem) => null;
static InvokeDynamicSpecializer lookupSpecializer(Selector selector) {
@@ -127,10 +123,6 @@
}
return null;
}
-
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return true;
- }
}
class IndexSpecializer extends InvokeDynamicSpecializer {
@@ -167,10 +159,6 @@
index.instructionType = type;
return index;
}
-
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return true;
- }
}
class BitNotSpecializer extends InvokeDynamicSpecializer {
@@ -206,10 +194,6 @@
if (input.isNumber()) return new HBitNot(input, instruction.selector);
return null;
}
-
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return true;
- }
}
class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
@@ -246,10 +230,6 @@
if (input.isNumber()) return new HNegate(input, instruction.selector);
return null;
}
-
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return true;
- }
}
abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
@@ -315,10 +295,6 @@
return null;
}
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return true;
- }
-
HInstruction newBuiltinVariant(HInvokeDynamic instruction);
}
@@ -373,13 +349,9 @@
}
HInstruction newBuiltinVariant(HInvokeDynamic instruction) {
- // Modulo cannot be mapped to the native operator (different semantics).
+ // Modulo cannot be mapped to the native operator (different semantics).
return null;
}
-
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return false;
- }
}
class MultiplySpecializer extends BinaryArithmeticSpecializer {
@@ -419,10 +391,6 @@
// Truncating divide does not have a JS equivalent.
return null;
}
-
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return false;
- }
}
abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
@@ -482,10 +450,6 @@
int count = intConstant.value;
return count >= 0 && count <= 31;
}
-
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return argumentLessThan32(instruction.inputs[2]);
- }
}
class ShiftRightSpecializer extends BinaryBitOpSpecializer {
@@ -499,10 +463,6 @@
BinaryOperation operation(ConstantSystem constantSystem) {
return constantSystem.shiftRight;
}
-
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return true;
- }
}
class BitOrSpecializer extends BinaryBitOpSpecializer {
@@ -582,10 +542,6 @@
return null;
}
- bool hasBuiltinVariant(HInvokeDynamic instruction, Compiler compiler) {
- return true;
- }
-
HInstruction newBuiltinVariant(HInvokeDynamic instruction);
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 15d48d1..8c723df 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -969,6 +969,8 @@
assert(isValid());
}
+ /// Do a in-place change of [from] to [to]. Warning: this function
+ /// does not update [inputs] and [usedBy]. Use [changeUse] instead.
void rewriteInput(HInstruction from, HInstruction to) {
for (int i = 0; i < inputs.length; i++) {
if (identical(inputs[i], from)) inputs[i] = to;
@@ -1300,7 +1302,7 @@
// We know it's a selector call if it follows the interceptor
// calling convention, which adds the actual receiver as a
// parameter to the call.
- return inputs.length - 2 == selector.argumentCount;
+ return (selector != null) && (inputs.length - 2 == selector.argumentCount);
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index 44c01e8..d86610e 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -179,7 +179,11 @@
String temporaryId(HInstruction instruction) {
String prefix;
HType type = instruction.instructionType;
- if (type.isExtendableArray(compiler)) {
+ if (type == HType.NULL) {
+ prefix = 'u';
+ } else if (type == HType.CONFLICTING) {
+ prefix = 'c';
+ } else if (type.isExtendableArray(compiler)) {
prefix = 'e';
} else if (type.isFixedArray(compiler)) {
prefix = 'f';
@@ -201,10 +205,6 @@
prefix = 'n';
} else if (type == HType.UNKNOWN) {
prefix = 'v';
- } else if (type == HType.CONFLICTING) {
- prefix = 'c';
- } else if (type == HType.NULL) {
- prefix = 'u';
} else {
prefix = 'U';
}
@@ -366,9 +366,7 @@
String visitInvokeSuper(HInvokeSuper invoke) {
String target = invoke.element.name.slowToString();
- int offset = HInvoke.ARGUMENTS_OFFSET + 1;
- List arguments = invoke.inputs.sublist(offset);
- return visitGenericInvoke("Invoke super", target, arguments);
+ return visitGenericInvoke("Invoke super", target, invoke.inputs);
}
String visitInvokeConstructorBody(HInvokeConstructorBody invoke) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 2afc618..8271832 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -337,11 +337,6 @@
}
HType visitTypeConversion(HTypeConversion check) {
- // The following checks are inserted by our optimizers, so we
- // want to optimize them even more.
- if (check.isArgumentTypeCheck || check.isReceiverTypeCheck) {
- return visitCheck(check);
- }
return HType.UNKNOWN;
}
@@ -402,7 +397,10 @@
HType computeDesiredTypeForInput(HInstruction user, HInstruction input) {
this.input = input;
- HType desired = user.accept(this);
+ // We simplify the desired type to avoid requesting the type of an
+ // instantiation node, for example [ContainerTypeMask].
+ HType desired = user.accept(this).simplify(compiler);
+ assert(!desired.computeMask(compiler).isContainer);
this.input = null;
return desired;
}
diff --git a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
index ba3f01d..3e8db07 100644
--- a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
@@ -104,13 +104,13 @@
if (!options.scanOnly) parser.parseUnit(token);
} on ParserError catch (ex) {
if (options.throwOnError) {
- throw;
+ rethrow;
} else {
print(ex);
}
} catch (ex) {
print('Error in file: $filename');
- throw;
+ rethrow;
}
if (options.buildAst) {
MyNodeListener l = listener;
@@ -172,7 +172,7 @@
try {
file.closeSync();
} catch (ex) {
- if (!threw) throw;
+ if (!threw) rethrow;
}
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 61191fc..1af2669 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -195,7 +195,7 @@
reportTypeInfo(Spannable node, MessageKind kind, [Map arguments = const {}]) {
compiler.reportDiagnostic(compiler.spanFromSpannable(node),
- 'Info: ${kind.message(arguments)}', api.Diagnostic.INFO);
+ '${kind.message(arguments)}', api.Diagnostic.INFO);
}
// TODO(karlklose): remove these functions.
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index 9dda20d..622e1a2 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -501,10 +501,6 @@
throw new UnsupportedError("");
}
- bool get isElement {
- throw new UnsupportedError("");
- }
-
bool containsOnlyInt(Compiler compiler) {
throw new UnsupportedError("");
}
diff --git a/sdk/lib/_internal/compiler/implementation/types/element_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/element_type_mask.dart
deleted file mode 100644
index 75e2345..0000000
--- a/sdk/lib/_internal/compiler/implementation/types/element_type_mask.dart
+++ /dev/null
@@ -1,56 +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.
-
-part of types;
-
-/**
- * A [TypeMask] specific to an element: the return type for a
- * function, or the type for a field.
- */
-class ElementTypeMask extends ForwardingTypeMask {
- final Element element;
- // Callback function to fetch the actual inferred type of the
- // element. It is used when a user wants to know about the type this
- // [ForwardingTypeMask] forwards to.
- final Function fetchForwardTo;
- final bool isNullable;
-
- ElementTypeMask(
- this.fetchForwardTo, this.element, {this.isNullable: true});
-
- bool get isElement => true;
-
- TypeMask get forwardTo {
- TypeMask forward = fetchForwardTo(element);
- return isNullable ? forward.nullable() : forward.nonNullable();
- }
-
- bool operator==(other) {
- if (other is! ElementTypeMask) return false;
- return element == other.element && isNullable == other.isNullable;
- }
-
- int get hashCode => computeHashCode(element, isNullable);
-
- bool equalsDisregardNull(other) {
- if (other is! ElementTypeMask) return false;
- return element == other.element;
- }
-
- TypeMask nullable() {
- return isNullable
- ? this
- : new ElementTypeMask(fetchForwardTo, element, isNullable: true);
- }
-
- TypeMask nonNullable() {
- return isNullable
- ? new ElementTypeMask(fetchForwardTo, element, isNullable: false)
- : this;
- }
-
- String toString() {
- return 'Type for element $element';
- }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
index 81ee4b3..03cd53a 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -64,7 +64,6 @@
bool get isUnion => false;
bool get isContainer => false;
bool get isForwarding => false;
- bool get isElement => false;
// TODO(kasperl): Get rid of these. They should not be a visible
// part of the implementation because they make it hard to add
diff --git a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
index a8aebb6..c077d5f 100644
--- a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
@@ -21,7 +21,6 @@
bool get isUnion => false;
bool get isContainer => false;
bool get isForwarding => true;
- bool get isElement => false;
bool containsOnlyInt(Compiler compiler) {
return forwardTo.containsOnlyInt(compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
deleted file mode 100644
index acacbe2..0000000
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ /dev/null
@@ -1,2364 +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.
-
-library simple_types_inferrer;
-
-import 'dart:collection' show Queue, LinkedHashSet;
-
-import '../closure.dart' show ClosureClassMap, ClosureScope;
-import '../dart_types.dart'
- show DartType, InterfaceType, FunctionType, TypeKind;
-import '../elements/elements.dart';
-import '../native_handler.dart' as native;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link, Spannable;
-import 'types.dart'
- show TypesInferrer, FlatTypeMask, TypeMask, ContainerTypeMask,
- ElementTypeMask, TypeSystem, MinimalInferrerEngine;
-import 'inferrer_visitor.dart';
-
-// BUG(8802): There's a bug in the analyzer that makes the re-export
-// of Selector from dart2jslib.dart fail. For now, we work around that
-// by importing universe.dart explicitly and disabling the re-export.
-import '../dart2jslib.dart' hide Selector, TypedSelector;
-import '../universe/universe.dart' show Selector, SideEffects, TypedSelector;
-
-/**
- * An implementation of [TypeSystem] for [TypeMask].
- */
-class TypeMaskSystem implements TypeSystem<TypeMask> {
- final Compiler compiler;
- TypeMaskSystem(this.compiler);
-
- TypeMask narrowType(TypeMask type,
- DartType annotation,
- {bool isNullable: true}) {
- if (annotation.treatAsDynamic) return type;
- if (annotation.isVoid) return nullType;
- if (annotation.element == compiler.objectClass) return type;
- TypeMask otherType;
- if (annotation.kind == TypeKind.TYPEDEF
- || annotation.kind == TypeKind.FUNCTION) {
- otherType = functionType;
- } else if (annotation.kind == TypeKind.TYPE_VARIABLE) {
- // TODO(ngeoffray): Narrow to bound.
- return type;
- } else {
- assert(annotation.kind == TypeKind.INTERFACE);
- otherType = new TypeMask.nonNullSubtype(annotation);
- }
- if (isNullable) otherType = otherType.nullable();
- if (type == null) return otherType;
- return type.intersection(otherType, compiler);
- }
-
- TypeMask computeLUB(TypeMask firstType, TypeMask secondType) {
- if (firstType == null) {
- return secondType;
- } else if (secondType == dynamicType || firstType == dynamicType) {
- return dynamicType;
- } else if (firstType == secondType) {
- return firstType;
- } else {
- TypeMask union = firstType.union(secondType, compiler);
- // TODO(kasperl): If the union isn't nullable it seems wasteful
- // to use dynamic. Fix that.
- return union.containsAll(compiler) ? dynamicType : union;
- }
- }
-
- TypeMask allocateDiamondPhi(TypeMask firstType, TypeMask secondType) {
- return computeLUB(firstType, secondType);
- }
-
- TypeMask get dynamicType => compiler.typesTask.dynamicType;
- TypeMask get nullType => compiler.typesTask.nullType;
- TypeMask get intType => compiler.typesTask.intType;
- TypeMask get doubleType => compiler.typesTask.doubleType;
- TypeMask get numType => compiler.typesTask.numType;
- TypeMask get boolType => compiler.typesTask.boolType;
- TypeMask get functionType => compiler.typesTask.functionType;
- TypeMask get listType => compiler.typesTask.listType;
- TypeMask get constListType => compiler.typesTask.constListType;
- TypeMask get fixedListType => compiler.typesTask.fixedListType;
- TypeMask get growableListType => compiler.typesTask.growableListType;
- TypeMask get mapType => compiler.typesTask.mapType;
- TypeMask get constMapType => compiler.typesTask.constMapType;
- TypeMask get stringType => compiler.typesTask.stringType;
- TypeMask get typeType => compiler.typesTask.typeType;
-
- TypeMask nonNullSubtype(DartType type) => new TypeMask.nonNullSubtype(type);
- TypeMask nonNullSubclass(DartType type) => new TypeMask.nonNullSubclass(type);
- TypeMask nonNullExact(DartType type) => new TypeMask.nonNullExact(type);
- TypeMask nonNullEmpty() => new TypeMask.nonNullEmpty();
-
- TypeMask allocateContainer(TypeMask type,
- Node node,
- Element enclosing,
- [TypeMask elementType, int length]) {
- ContainerTypeMask mask = new ContainerTypeMask(type, node, enclosing);
- mask.elementType = elementType;
- mask.length = length;
- return mask;
- }
-
- Selector newTypedSelector(TypeMask receiver, Selector selector) {
- return new TypedSelector(receiver, selector);
- }
-
- TypeMask addPhiInput(Element element, TypeMask phiType, TypeMask newType) {
- return computeLUB(phiType, newType);
- }
-
- TypeMask allocatePhi(Node node, Element element, TypeMask inputType) {
- return inputType;
- }
-
- TypeMask simplifyPhi(Node node, Element element, TypeMask phiType) {
- return phiType;
- }
-
- TypeMask refineReceiver(Selector selector, TypeMask receiverType) {
- // If the receiver is based on an element, we let the type
- // inferrer handle it. Otherwise, we might prevent it from finding
- // one-level cycles in the inference graph.
- if (receiverType.isElement) return receiverType;
- TypeMask newType = compiler.world.allFunctions.receiverType(selector);
- return receiverType.intersection(newType, compiler);
- }
-}
-
-/**
- * A work queue that ensures there are no duplicates, and adds and
- * removes in FIFO.
- */
-class WorkSet<E extends Element> {
- final Queue<E> queue = new Queue<E>();
- final Set<E> elementsInQueue = new Set<E>();
-
- void add(E element) {
- element = element.implementation;
- if (elementsInQueue.contains(element)) return;
- queue.addLast(element);
- elementsInQueue.add(element);
- }
-
- E remove() {
- E element = queue.removeFirst();
- elementsInQueue.remove(element);
- return element;
- }
-
- bool get isEmpty => queue.isEmpty;
-
- int get length => queue.length;
-}
-
-/**
- * A [TypeInformation] object contains information from the inferrer
- * on a specific [Element].
- */
-abstract class TypeInformation {
- /**
- * Assignments on the element and the types inferred at
- * these assignments.
- */
- Map<Spannable, TypeMask> get assignments => null;
-
- /**
- * Callers of an element.
- */
- Map<Element, Set<Spannable>> get callers => null;
-
- /**
- * Number of times the element has been processed.
- */
- int get analyzeCount => 0;
- void set analyzeCount(value) {}
-
- TypeMask get type => null;
- void set type(value) {}
-
- TypeMask get returnType => null;
- void set returnType(value) {}
-
- void addCaller(Element caller, Spannable node) {
- if (callers.containsKey(caller)) {
- callers[caller].add(node);
- } else {
- callers[caller] = new Set<Spannable>()..add(node);
- }
- }
-
- void removeCall(Element caller, Spannable node) {
- if (!callers.containsKey(caller)) return;
- Set<Spannable> calls = callers[caller];
- calls.remove(node);
- if (calls.isEmpty) {
- callers.remove(caller);
- }
- }
-
- void addAssignment(Spannable node, TypeMask mask) {
- assignments[node] = mask;
- }
-
- void clear();
-}
-
-class FunctionTypeInformation extends TypeInformation {
- Map<Element, Set<Spannable>> callers = new Map<Element, Set<Spannable>>();
- TypeMask returnType;
- int analyzeCount = 0;
- bool canBeClosurized = false;
-
- void clear() {
- callers = null;
- }
-}
-
-class ParameterTypeInformation extends TypeInformation {
- Map<Spannable, TypeMask> assignments = new Map<Spannable, TypeMask>();
- TypeMask type;
- TypeMask defaultType;
-
- void clear() {
- assignments = null;
- }
-}
-
-class FieldTypeInformation extends TypeInformation {
- TypeMask type;
- Map<Element, Set<Spannable>> callers = new Map<Element, Set<Spannable>>();
- Map<Spannable, TypeMask> assignments = new Map<Spannable, TypeMask>();
- int analyzeCount = 0;
-
- void clear() {
- assignments = null;
- callers = null;
- }
-}
-
-/**
- * A class for knowing when can we compute a type for final fields.
- */
-class ClassTypeInformation {
- /**
- * The number of generative constructors that need to be visited
- * before we can take any decision on the type of the fields.
- * Given that all generative constructors must be analyzed before
- * re-analyzing one, we know that once [constructorsToVisitCount]
- * reaches to 0, all generative constructors have been analyzed.
- */
- int constructorsToVisitCount;
-
- ClassTypeInformation(this.constructorsToVisitCount);
-
- /**
- * Records that [constructor] has been analyzed. If not at 0,
- * decrement [constructorsToVisitCount].
- */
- void onGenerativeConstructorAnalyzed(Element constructor) {
- if (constructorsToVisitCount != 0) constructorsToVisitCount--;
- }
-
- /**
- * Returns whether all generative constructors of the class have
- * been analyzed.
- */
- bool get isDone => constructorsToVisitCount == 0;
-}
-
-final OPTIMISTIC = 0;
-final RETRY = 1;
-final PESSIMISTIC = 2;
-
-class SimpleTypesInferrer extends TypesInferrer {
- InternalSimpleTypesInferrer internal;
- final Compiler compiler;
- final TypeMaskSystem types;
-
- SimpleTypesInferrer(Compiler compiler) :
- compiler = compiler,
- types = new TypeMaskSystem(compiler) {
- internal = new InternalSimpleTypesInferrer(this, OPTIMISTIC);
- }
-
- TypeMask getReturnTypeOfElement(Element element) {
- if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
- return internal.getReturnTypeOfElement(element.implementation);
- }
-
- TypeMask getTypeOfElement(Element element) {
- if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
- return internal.getTypeOfElement(element.implementation);
- }
-
- TypeMask getTypeOfNode(Element owner, Node node) {
- if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
- return internal.getTypeOfNode(owner, node);
- }
-
- TypeMask getTypeOfSelector(Selector selector) {
- if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
- return internal.getTypeOfSelector(selector);
- }
-
- Iterable<Element> getCallersOf(Element element) {
- if (compiler.disableTypeInference) throw "Don't use me";
- return internal.getCallersOf(element.implementation);
- }
-
- Iterable<TypeMask> get containerTypes => internal.containerTypes;
-
- bool analyzeMain(Element element) {
- if (compiler.disableTypeInference) return true;
- bool result = internal.analyzeMain(element);
- if (internal.optimismState == OPTIMISTIC) return result;
- assert(internal.optimismState == RETRY);
-
- // Discard the inferrer and start again with a pessimistic one.
- internal = new InternalSimpleTypesInferrer(this, PESSIMISTIC);
- return internal.analyzeMain(element);
- }
-
- void clear() {
- internal.clear();
- }
-}
-
-/**
- * Common super class used by [SimpleTypeInferrerVisitor] to propagate
- * type information about visited nodes, as well as to request type
- * information of elements.
- */
-abstract class InferrerEngine<T, V extends TypeSystem>
- implements MinimalInferrerEngine<T> {
- final Compiler compiler;
- final V types;
- final Map<Node, T> concreteTypes = new Map<Node, T>();
-
- InferrerEngine(this.compiler, this.types);
-
- /**
- * Requests updates of all parameters types of [function].
- */
- void updateAllParametersOf(FunctionElement function);
-
- /**
- * Records the default type of parameter [parameter].
- */
- void setDefaultTypeOfParameter(Element parameter, T type);
-
- /**
- * Returns the type of [element].
- */
- T typeOfElement(Element element);
-
- /**
- * Returns the return type of [element].
- */
- T returnTypeOfElement(Element element);
-
- /**
- * Records that [node] sets final field [element] to be of type [type].
- *
- * [nodeHolder] is the element holder of [node].
- *
- * [constraint] is a constraint, as described in
- * [InternalSimpleTypesInferrer].
- */
- void recordTypeOfFinalField(Node node,
- Element nodeHolder,
- Element field,
- T type,
- CallSite constraint);
-
- /**
- * Records that [node] sets non-final field [element] to be of type
- * [type].
- *
- * [constraint] is a field assignment constraint, as described in
- * [InternalSimpleTypesInferrer].
- */
- void recordTypeOfNonFinalField(Spannable node,
- Element field,
- T type,
- CallSite constraint);
-
- /**
- * Notifies that the visitor is done visiting generative constructor
- * [element].
- */
- void onGenerativeConstructorAnalyzed(Element element);
-
- /**
- * Records that [element] is of type [type]. Returns whether the
- * type is useful for the inferrer.
- */
- bool recordType(Element element, T type);
-
- /**
- * Records that the return type [element] is of type [type].
- */
- void recordReturnType(Element element, T type);
-
- /**
- * Registers that [caller] calls [callee] at location [node], with
- * [selector], and [arguments]. Note that [selector] is null for
- * forwarding constructors.
- *
- * [constraint] is a field assignment constraint, as described in
- * [InternalSimpleTypesInferrer].
- *
- * [sideEffects] will be updated to incorporate [callee]'s side
- * effects.
- *
- * [inLoop] tells whether the call happens in a loop.
- */
- T registerCalledElement(Spannable node,
- Selector selector,
- Element caller,
- Element callee,
- ArgumentsTypes<T> arguments,
- CallSite constraint,
- SideEffects sideEffects,
- bool inLoop);
-
- /**
- * Registers that [caller] calls [selector] with [receiverType] as
- * receiver, and [arguments].
- *
- * [constraint] is a field assignment constraint, as described in
- * [InternalSimpleTypesInferrer].
- *
- * [sideEffects] will be updated to incorporate [callee]'s side
- * effects.
- *
- * [inLoop] tells whether the call happens in a loop.
- */
- T registerCalledSelector(Node node,
- Selector selector,
- T receiverType,
- Element caller,
- ArgumentsTypes<T> arguments,
- CallSite constraint,
- SideEffects sideEffects,
- bool inLoop);
-
- /**
- * Returns the callers of [elements].
- */
- Iterable<Element> getCallersOf(Element element);
-
- /**
- * Notifies to the inferrer that [analyzedElement] can have return
- * type [newType]. [currentType] is the type the [InferrerVisitor]
- * currently found.
- *
- * Returns the new type for [analyzedElement].
- */
- T addReturnTypeFor(Element analyzedElement, T currentType, T newType);
-
- /**
- * Applies [f] to all elements in the universe that match
- * [selector]. If [f] returns false, aborts the iteration.
- */
- void forEachElementMatching(Selector selector, bool f(Element element)) {
- Iterable<Element> elements = compiler.world.allFunctions.filter(selector);
- for (Element e in elements) {
- if (!f(e.implementation)) return;
- }
- }
-
- /**
- * Update [sideEffects] with the side effects of [callee] being
- * called with [selector].
- */
- void updateSideEffects(SideEffects sideEffects,
- Selector selector,
- Element callee) {
- if (callee.isField()) {
- if (callee.isInstanceMember()) {
- if (selector.isSetter()) {
- sideEffects.setChangesInstanceProperty();
- } else if (selector.isGetter()) {
- sideEffects.setDependsOnInstancePropertyStore();
- } else {
- sideEffects.setAllSideEffects();
- sideEffects.setDependsOnSomething();
- }
- } else {
- if (selector.isSetter()) {
- sideEffects.setChangesStaticProperty();
- } else if (selector.isGetter()) {
- sideEffects.setDependsOnStaticPropertyStore();
- } else {
- sideEffects.setAllSideEffects();
- sideEffects.setDependsOnSomething();
- }
- }
- } else if (callee.isGetter() && !selector.isGetter()) {
- sideEffects.setAllSideEffects();
- sideEffects.setDependsOnSomething();
- } else {
- sideEffects.add(compiler.world.getSideEffectsOfElement(callee));
- }
- }
-
- /**
- * Returns the type for [nativeBehavior]. See documentation on
- * [native.NativeBehavior].
- */
- T typeOfNativeBehavior(native.NativeBehavior nativeBehavior) {
- if (nativeBehavior == null) return types.dynamicType;
- List typesReturned = nativeBehavior.typesReturned;
- if (typesReturned.isEmpty) return types.dynamicType;
- T returnType;
- for (var type in typesReturned) {
- T mappedType;
- if (type == native.SpecialType.JsObject) {
- mappedType = types.nonNullExact(compiler.objectClass.rawType);
- } else if (type.element == compiler.stringClass) {
- mappedType = types.stringType;
- } else if (type.element == compiler.intClass) {
- mappedType = types.intType;
- } else if (type.element == compiler.doubleClass) {
- mappedType = types.doubleType;
- } else if (type.element == compiler.numClass) {
- mappedType = types.numType;
- } else if (type.element == compiler.boolClass) {
- mappedType = types.boolType;
- } else if (type.element == compiler.nullClass) {
- mappedType = types.nullType;
- } else if (type.isVoid) {
- mappedType = types.nullType;
- } else if (type.isDynamic) {
- return types.dynamicType;
- } else if (!compiler.world.hasAnySubtype(type.element)) {
- mappedType = types.nonNullExact(type.element.rawType);
- } else {
- ClassElement element = type.element;
- Set<ClassElement> subtypes = compiler.world.subtypesOf(element);
- Set<ClassElement> subclasses = compiler.world.subclassesOf(element);
- if (subclasses != null && subtypes.length == subclasses.length) {
- mappedType = types.nonNullSubclass(element.rawType);
- } else {
- mappedType = types.nonNullSubtype(element.rawType);
- }
- }
- returnType = types.computeLUB(returnType, mappedType);
- if (returnType == types.dynamicType) {
- break;
- }
- }
- return returnType;
- }
-
- /**
- * Returns the type of [element] when being called with [selector].
- */
- T typeOfElementWithSelector(Element element, Selector selector) {
- if (element.name == Compiler.NO_SUCH_METHOD
- && selector.name != element.name) {
- // An invocation can resolve to a [noSuchMethod], in which case
- // we get the return type of [noSuchMethod].
- return returnTypeOfElement(element);
- } else if (selector.isGetter()) {
- if (element.isFunction()) {
- // [functionType] is null if the inferrer did not run.
- return types.functionType == null
- ? types.dynamicType
- : types.functionType;
- } else if (element.isField()) {
- return typeOfElement(element);
- } else if (Elements.isUnresolved(element)) {
- return types.dynamicType;
- } else {
- assert(element.isGetter());
- return returnTypeOfElement(element);
- }
- } else if (element.isGetter() || element.isField()) {
- assert(selector.isCall() || selector.isSetter());
- return types.dynamicType;
- } else {
- return returnTypeOfElement(element);
- }
- }
-
- void updateSelectorInTree(Element owner, Node node, Selector selector) {
- var elements = compiler.enqueuer.resolution.getCachedElements(owner);
- if (node.asSendSet() != null) {
- if (selector.isSetter() || selector.isIndexSet()) {
- elements.setSelector(node, selector);
- } else if (selector.isGetter() || selector.isIndex()) {
- elements.setGetterSelectorInComplexSendSet(node, selector);
- } else {
- assert(selector.isOperator());
- elements.setOperatorSelectorInComplexSendSet(node, selector);
- }
- } else if (node.asSend() != null) {
- elements.setSelector(node, selector);
- } else {
- assert(node.asForIn() != null);
- if (selector.asUntyped == compiler.iteratorSelector) {
- elements.setIteratorSelector(node, selector);
- } else if (selector.asUntyped == compiler.currentSelector) {
- elements.setCurrentSelector(node, selector);
- } else {
- assert(selector.asUntyped == compiler.moveNextSelector);
- elements.setMoveNextSelector(node, selector);
- }
- }
- }
-
- bool isNativeElement(Element element) {
- if (element.isNative()) return true;
- return element.isMember()
- && element.getEnclosingClass().isNative()
- && element.isField();
- }
-}
-
-class InternalSimpleTypesInferrer
- extends InferrerEngine<TypeMask, TypeMaskSystem>
- implements TypesInferrer {
- /**
- * Maps a class to a [ClassTypeInformation] to help collect type
- * information of final fields.
- */
- Map<ClassElement, ClassTypeInformation> classInfoForFinalFields =
- new Map<ClassElement, ClassTypeInformation>();
-
- /**
- * Maps an element to its corresponding [TypeInformation].
- */
- final Map<Element, TypeInformation> typeInfo =
- new Map<Element, TypeInformation>();
-
- /**
- * Maps a node to its type. Currently used for computing element
- * types of lists.
- */
- final Map<Node, TypeMask> concreteTypes = new Map<Node, TypeMask>();
-
- Iterable<TypeMask> get containerTypes => concreteTypes.values;
-
- /**
- * A map of constraints on a setter. When computing the type
- * of a field, these [Node] are initially discarded, and once the
- * type is computed, we make sure these constraints are satisfied
- * for that type. For example:
- *
- * [: field++ ], or [: field += 42 :], the constraint is on the
- * operator+, and we make sure that a typed selector with the found
- * type returns that type.
- *
- * [: field = other.field :], the constraint in on the [:field]
- * getter selector, and we make sure that the getter selector
- * returns that type.
- *
- */
- Map<Spannable, CallSite> setterConstraints = new Map<Spannable, CallSite>();
-
- /**
- * The work list of the inferrer.
- */
- WorkSet<Element> workSet = new WorkSet<Element>();
-
- /**
- * Heuristic for avoiding too many re-analysis of an element.
- */
- final int MAX_ANALYSIS_COUNT_PER_ELEMENT = 5;
-
- int optimismState;
-
- bool isDynamicType(TypeMask type) => identical(type, types.dynamicType);
-
- /**
- * These are methods that are expected to return only bool. We optimistically
- * assume that they do this. If we later find a contradiction, we have to
- * restart the simple types inferrer, because it normally goes from less
- * optimistic to more optimistic as it refines its type information. Without
- * this optimization, method names that are mutually recursive in the tail
- * position will be typed as dynamic.
- */
- // TODO(erikcorry): Autogenerate the alphanumeric names in this set.
- Set<SourceString> PREDICATES = new Set<SourceString>.from([
- const SourceString('=='),
- const SourceString('<='),
- const SourceString('>='),
- const SourceString('>'),
- const SourceString('<'),
- const SourceString('moveNext')]);
-
- bool shouldOptimisticallyOptimizeToBool(Element element) {
- return element == compiler.identicalFunction.implementation
- || (element.isFunction()
- && element.isInstanceMember()
- && PREDICATES.contains(element.name));
- }
-
- // Times the computation of re-analysis of methods.
- final Stopwatch recomputeWatch = new Stopwatch();
- // Number of re-analysis.
- int recompiles = 0;
-
- /**
- * Set to [true] when the analysis has analyzed all elements in the
- * world.
- */
- bool hasAnalyzedAll = false;
-
- /**
- * The number of elements in the world.
- */
- int numberOfElementsToAnalyze;
-
- /**
- * The number of analysis already done.
- */
- int analyzed = 0;
-
- InternalSimpleTypesInferrer(SimpleTypesInferrer inferrer, this.optimismState)
- : super(inferrer.compiler, inferrer.types);
-
- /**
- * Main entry point of the inferrer. Analyzes all elements that the resolver
- * found as reachable. Returns whether it succeeded.
- */
- bool analyzeMain(Element element) {
- buildWorkQueue();
- compiler.progress.reset();
- int maxReanalysis = (numberOfElementsToAnalyze * 1.5).toInt();
- do {
- if (compiler.progress.elapsedMilliseconds > 500) {
- compiler.log('Inferred $analyzed methods.');
- compiler.progress.reset();
- }
- element = workSet.remove();
- if (element.isErroneous()) continue;
-
- bool wasAnalyzed = typeInformationOf(element).analyzeCount != 0;
- if (wasAnalyzed) {
- recompiles++;
- if (recompiles >= maxReanalysis) {
- compiler.log('Ran out of budget for inferring.');
- break;
- }
- if (compiler.verbose) recomputeWatch.start();
- }
- bool changed =
- compiler.withCurrentElement(element, () => analyze(element));
- if (optimismState == RETRY) return true; // Abort.
- analyzed++;
- if (wasAnalyzed && compiler.verbose) {
- recomputeWatch.stop();
- }
- checkAnalyzedAll();
- if (changed) {
- // If something changed during the analysis of [element], put back
- // callers of it in the work list.
- enqueueCallersOf(element);
- }
- } while (!workSet.isEmpty);
- dump();
- return true;
- }
-
- TypeInformation typeInformationOf(Element element) {
- return typeInfo.putIfAbsent(element, () {
- if (element.isParameter() || element.isFieldParameter()) {
- return new ParameterTypeInformation();
- } else if (element.isField() || element.isVariable()) {
- return new FieldTypeInformation();
- } else {
- assert(element is FunctionElement);
- return new FunctionTypeInformation();
- }
- });
- }
-
- /**
- * Query method after the analysis to know the type of [element].
- */
- TypeMask getReturnTypeOfElement(Element element) {
- return getNonNullType(typeInformationOf(element).returnType);
- }
-
- TypeMask getTypeOfElement(Element element) {
- return getNonNullType(typeInformationOf(element).type);
- }
-
- TypeMask getTypeOfSelector(Selector selector) {
- return getNonNullType(returnTypeOfSelector(selector));
- }
-
- bool isTypeValuable(TypeMask returnType) {
- return !isDynamicType(returnType);
- }
-
- TypeMask getNonNullType(TypeMask returnType) {
- return returnType != null ? returnType : types.dynamicType;
- }
-
- Iterable<Element> getCallersOf(Element element) {
- return typeInformationOf(element).callers.keys;
- }
-
- /**
- * Query method after the analysis to know the type of [node],
- * defined in the context of [owner].
- */
- TypeMask getTypeOfNode(Element owner, Node node) {
- return getNonNullType(concreteTypes[node]);
- }
-
- void checkAnalyzedAll() {
- if (hasAnalyzedAll) return;
- if (analyzed < numberOfElementsToAnalyze) return;
- hasAnalyzedAll = true;
-
- // If we have analyzed all the world, we know all assigments to
- // fields and parameters, and can therefore infer a type for them.
- typeInfo.forEach((element, TypeInformation info) {
- if (element.isParameter() || element.isFieldParameter()) {
- if (updateParameterType(element)) {
- enqueueAgain(element.enclosingElement);
- }
- } else if (element.isField()
- && !(element.modifiers.isFinal()
- || element.modifiers.isConst())) {
- updateNonFinalFieldType(element);
- } else if (element.isVariable()) {
- updateNonFinalFieldType(element);
- }
- });
- }
-
- /**
- * Enqueues [e] in the work queue if it is valuable.
- */
- void enqueueAgain(Element e) {
- assert(isNotClosure(e));
- int count = typeInformationOf(e).analyzeCount;
- if (count != null && count > MAX_ANALYSIS_COUNT_PER_ELEMENT) return;
- workSet.add(e);
- }
-
- void enqueueCallersOf(Element element) {
- assert(isNotClosure(element));
- typeInformationOf(element).callers.keys.forEach(enqueueAgain);
- }
-
- /**
- * Builds the initial work queue by adding all resolved elements in
- * the work queue, ordered by the number of selectors they use. This
- * order is benficial for the analysis of return types, but we may
- * have to refine it once we analyze parameter types too.
- */
- void buildWorkQueue() {
- int max = 0;
- Map<int, Set<Element>> methodSizes = new Map<int, Set<Element>>();
- compiler.enqueuer.resolution.resolvedElements.forEach(
- (Element element, TreeElementMapping mapping) {
- if (element.impliesType()) return;
- assert(invariant(element,
- element.isField() ||
- element.isFunction() ||
- element.isGenerativeConstructor() ||
- element.isGetter() ||
- element.isSetter(),
- message: 'Unexpected element kind: ${element.kind}'));
- // TODO(ngeoffray): Not sure why the resolver would put a null
- // mapping.
- if (mapping == null) return;
- if (element.isAbstract(compiler)) return;
- // Add the relational operators, ==, !=, <, etc., before any
- // others, as well as the identical function.
- if (shouldOptimisticallyOptimizeToBool(element)) {
- workSet.add(element);
- // Optimistically assume that they return bool. We may need to back
- // out of this.
- if (optimismState == OPTIMISTIC) {
- FunctionTypeInformation info =
- typeInformationOf(element.implementation);
- info.returnType = types.boolType;
- }
- } else {
- // Put the other operators in buckets by length, later to be added in
- // length order.
- int length = mapping.selectors.length;
- max = length > max ? length : max;
- Set<Element> set = methodSizes.putIfAbsent(
- length, () => new LinkedHashSet<Element>());
- set.add(element);
- }
- });
-
- // This iteration assumes the [WorkSet] is FIFO.
- for (int i = 0; i <= max; i++) {
- Set<Element> set = methodSizes[i];
- if (set != null) {
- set.forEach((e) { workSet.add(e); });
- }
- }
- numberOfElementsToAnalyze = workSet.length;
-
- // Build the [classInfoForFinalFields] map by iterating over all
- // seen classes and counting the number of their generative
- // constructors.
- // We iterate over the seen classes and not the instantiated ones,
- // because we also need to analyze the final fields of super
- // classes that are not instantiated.
- compiler.enqueuer.resolution.seenClasses.forEach((ClassElement cls) {
- int constructorCount = 0;
- cls.forEachMember((_, member) {
- if (member.isGenerativeConstructor()
- && compiler.enqueuer.resolution.isProcessed(member)) {
- constructorCount++;
- }
- });
- classInfoForFinalFields[cls.implementation] =
- new ClassTypeInformation(constructorCount);
- });
- }
-
- // TODO(ngeoffray): Get rid of this method. Unit tests don't always
- // ensure these classes are resolved.
- rawTypeOf(ClassElement cls) {
- cls.ensureResolved(compiler);
- assert(cls.rawType != null);
- return cls.rawType;
- }
-
- dump() {
- int interestingTypes = 0;
- typeInfo.forEach((element, TypeInformation info) {
- TypeMask type = info.type;
- TypeMask returnType = info.returnType;
- if (type != null && type != types.nullType && !isDynamicType(type)) {
- interestingTypes++;
- }
- if (returnType != null
- && returnType != types.nullType
- && !isDynamicType(returnType)) {
- interestingTypes++;
- }
- });
-
- compiler.log('Type inferrer re-analyzed methods $recompiles times '
- 'in ${recomputeWatch.elapsedMilliseconds} ms.');
- compiler.log('Type inferrer found $interestingTypes interesting '
- 'types.');
- }
-
- /**
- * Clear data structures that are not used after the analysis.
- */
- void clear() {
- classInfoForFinalFields = null;
- setterConstraints = null;
- workSet = null;
- typeInfo.forEach((_, info) { info.clear(); });
- }
-
- bool analyze(Element element) {
- SimpleTypeInferrerVisitor visitor =
- new SimpleTypeInferrerVisitor<TypeMask>(element, compiler, this);
- TypeMask returnType = visitor.run();
- typeInformationOf(element).analyzeCount++;
- if (element.isGenerativeConstructor()) {
- // We always know the return type of a generative constructor.
- return false; // Nothing changed.
- } else if (element.isField()) {
- Node node = element.parseNode(compiler);
- if (element.modifiers.isFinal() || element.modifiers.isConst()) {
- // If [element] is final and has an initializer, we record
- // the inferred type.
- if (node.asSendSet() != null) {
- return recordType(element, returnType);
- }
- return false;
- } else if (node.asSendSet() == null) {
- // Only update types of static fields if there is no
- // assignment. Instance fields are dealt with in the constructor.
- if (Elements.isStaticOrTopLevelField(element)) {
- recordTypeOfNonFinalField(node, element, returnType, null);
- }
- return false;
- } else {
- recordTypeOfNonFinalField(node, element, returnType, null);
- // [recordTypeOfNonFinalField] takes care of re-enqueuing
- // users of the field.
- return false;
- }
- } else {
- return recordReturnType(element, returnType);
- }
- }
-
- bool recordType(Element analyzedElement, TypeMask type) {
- if (isNativeElement(analyzedElement)) return false;
- if (!compiler.backend.canBeUsedForGlobalOptimizations(analyzedElement)) {
- return false;
- }
- assert(type != null);
- assert(analyzedElement.isField()
- || analyzedElement.isParameter()
- || analyzedElement.isFieldParameter());
- TypeMask newType = checkTypeAnnotation(analyzedElement, type);
- TypeMask existing = typeInformationOf(analyzedElement).type;
- typeInformationOf(analyzedElement).type = newType;
- // If the type is useful, say it has changed.
- return existing != newType
- && !isDynamicType(newType)
- && newType != types.nullType;
- }
-
- /**
- * Records [returnType] as the return type of [analyzedElement].
- * Returns whether the new type is worth recompiling the callers of
- * [analyzedElement].
- */
- bool recordReturnType(Element analyzedElement, TypeMask returnType) {
- if (isNativeElement(analyzedElement)) return false;
- assert(analyzedElement.implementation == analyzedElement);
- TypeMask existing = typeInformationOf(analyzedElement).returnType;
- if (optimismState == OPTIMISTIC
- && shouldOptimisticallyOptimizeToBool(analyzedElement)
- && returnType != existing) {
- // One of the functions turned out not to return what we expected.
- // This means we need to restart the analysis.
- optimismState = RETRY;
- }
- TypeMask newType = checkTypeAnnotation(analyzedElement, returnType);
- if (analyzedElement.name == const SourceString('==')) {
- // TODO(ngeoffray): Should this be done at the call site?
- // When the argument passed in is null, we know we return a
- // bool.
- FunctionElement function = analyzedElement;
- function.computeSignature(compiler).forEachParameter((Element parameter) {
- if (typeOfElement(parameter).isNullable){
- newType = types.computeLUB(newType, types.boolType);
- }
- });
- }
- FunctionTypeInformation info = typeInformationOf(analyzedElement);
- info.returnType = newType;
- // If the return type is useful, say it has changed.
- return existing != newType
- && !isDynamicType(newType)
- && newType != types.nullType;
- }
-
- TypeMask checkTypeAnnotation(Element analyzedElement, TypeMask newType) {
- if (compiler.trustTypeAnnotations
- // Parameters are being checked by the method, and we can
- // therefore only trust their type after the checks.
- || (compiler.enableTypeAssertions &&
- !analyzedElement.isParameter() &&
- !analyzedElement.isFieldParameter())) {
- var annotation = analyzedElement.computeType(compiler);
- if (analyzedElement.isGetter()
- || analyzedElement.isFunction()
- || analyzedElement.isConstructor()
- || analyzedElement.isSetter()) {
- assert(annotation is FunctionType);
- annotation = annotation.returnType;
- }
- newType = types.narrowType(newType, annotation);
- }
- return newType;
- }
-
- TypeMask fetchReturnType(Element element) {
- TypeMask returnType = returnTypeOfElement(element);
- return returnType is ElementTypeMask ? types.dynamicType : returnType;
- }
-
- TypeMask fetchType(Element element) {
- TypeMask type = typeOfElement(element);
- return type is ElementTypeMask ? types.dynamicType : type;
- }
-
- /**
- * Returns the return type of [element]. Returns [:dynamic:] if
- * [element] has not been analyzed yet.
- */
- TypeMask returnTypeOfElement(Element element) {
- element = element.implementation;
- TypeInformation info = typeInformationOf(element);
- if (element.isGenerativeConstructor()) {
- return info.returnType == null
- ? info.returnType = new TypeMask.nonNullExact(
- rawTypeOf(element.getEnclosingClass()))
- : info.returnType;
- } else if (element.isNative()) {
- if (info.returnType == null) {
- var elementType = element.computeType(compiler);
- if (elementType.kind != TypeKind.FUNCTION) {
- info.returnType = types.dynamicType;
- } else {
- info.returnType = typeOfNativeBehavior(
- native.NativeBehavior.ofMethod(element, compiler));
- }
- }
- return info.returnType;
- }
- TypeMask returnType = info.returnType;
- if (returnType == null) {
- if ((compiler.trustTypeAnnotations || compiler.enableTypeAssertions)
- && (element.isFunction()
- || element.isGetter()
- || element.isFactoryConstructor())) {
- FunctionType functionType = element.computeType(compiler);
- returnType = types.narrowType(
- types.dynamicType, functionType.returnType);
- } else {
- returnType = info.returnType =
- new ElementTypeMask(fetchReturnType, element);
- }
- }
- return returnType;
- }
-
- /**
- * Returns the type of [element]. Returns [:dynamic:] if
- * [element] has not been analyzed yet.
- */
- TypeMask typeOfElement(Element element) {
- element = element.implementation;
- TypeInformation info = typeInformationOf(element);
- TypeMask type = info.type;
- if (isNativeElement(element) && element.isField()) {
- if (type == null) {
- InterfaceType rawType = element.computeType(compiler).asRaw();
- info.type = type = rawType.treatAsDynamic
- ? types.dynamicType
- : new TypeMask.subtype(rawType);
- }
- assert(type != null);
- return type;
- }
- if (type == null) {
- if ((compiler.trustTypeAnnotations
- && (element.isField()
- || element.isParameter()
- || element.isVariable()))
- // Parameters are being checked by the method, and we can
- // therefore only trust their type after the checks.
- || (compiler.enableTypeAssertions
- && (element.isField() || element.isVariable()))) {
- type = types.narrowType(
- types.dynamicType, element.computeType(compiler));
- } else {
- type = info.type = new ElementTypeMask(fetchType, element);
- }
- }
- return type;
- }
-
- /**
- * Returns the union of the types of all elements that match
- * the called [selector].
- */
- TypeMask returnTypeOfSelector(Selector selector) {
- // Bailout for closure calls. We're not tracking types of
- // closures.
- if (selector.isClosureCall()) return types.dynamicType;
- if (selector.isSetter() || selector.isIndexSet()) return types.dynamicType;
-
- TypeMask result;
- forEachElementMatching(selector, (Element element) {
- assert(element.isImplementation);
- TypeMask type = typeOfElementWithSelector(element, selector);
- result = types.computeLUB(result, type);
- return isTypeValuable(result);
- });
- if (result == null) {
- result = new TypeMask.nonNullEmpty();
- }
- return result;
- }
-
- TypeMask typeOfElementWithSelector(Element element, Selector selector) {
- if (selector.isIndex()
- && selector.mask != null
- && selector.mask.isContainer
- && element.name == selector.name) {
- ContainerTypeMask mask = selector.mask;
- TypeMask elementType = mask.elementType;
- return elementType == null ? types.dynamicType : elementType;
- } else {
- return super.typeOfElementWithSelector(element, selector);
- }
- }
-
- bool isNotClosure(Element element) {
- if (!element.isFunction()) return true;
- // If the outermost enclosing element of [element] is [element]
- // itself, we know it cannot be a closure.
- Element outermost = element.getOutermostEnclosingMemberOrTopLevel();
- return outermost.declaration == element.declaration;
- }
-
- void addCaller(Element caller, Element callee, Spannable node) {
- assert(caller.isImplementation);
- assert(callee.isImplementation);
- assert(isNotClosure(caller));
- typeInformationOf(callee).addCaller(caller, node);
- }
-
- bool addArguments(Spannable node,
- FunctionElement element,
- ArgumentsTypes arguments) {
- FunctionTypeInformation info = typeInformationOf(element);
- if (info.canBeClosurized) return false;
- // A [noSuchMethod] method can be the target of any call, with
- // any number of arguments. For simplicity, we just do not
- // infer any parameter types for [noSuchMethod].
- if (element.name == Compiler.NO_SUCH_METHOD) return false;
-
- FunctionSignature signature = element.computeSignature(compiler);
- int parameterIndex = 0;
- bool changed = false;
- bool visitingOptionalParameter = false;
- signature.forEachParameter((Element parameter) {
- if (parameter == signature.firstOptionalParameter) {
- visitingOptionalParameter = true;
- }
- TypeMask type;
- ParameterTypeInformation info = typeInformationOf(parameter);
- if (!visitingOptionalParameter) {
- type = arguments.positional[parameterIndex];
- } else {
- if (signature.optionalParametersAreNamed) {
- type = arguments.named[parameter.name];
- if (type == null) type = info.defaultType;
- } else if (parameterIndex < arguments.positional.length) {
- type = arguments.positional[parameterIndex];
- } else {
- type = info.defaultType;
- }
- }
- TypeMask oldType = info.assignments[node];
- info.addAssignment(node, type);
- changed = changed || (oldType != type);
- parameterIndex++;
- });
- return changed;
- }
-
- bool updateParameterType(Element parameter) {
- Element function = parameter.enclosingElement;
- FunctionTypeInformation functionInfo = typeInformationOf(function);
- if (functionInfo.canBeClosurized) return false;
- if (!isNotClosure(parameter.enclosingElement)) return false;
-
- ParameterTypeInformation info = typeInformationOf(parameter);
- TypeMask elementType;
- info.assignments.forEach((Spannable node, TypeMask mask) {
- if (mask == null) {
- // Now that we know we have analyzed the function holding
- // [parameter], we have a default type for that [parameter].
- mask = info.defaultType;
- info.addAssignment(node, mask);
- }
- elementType = computeLubFor(elementType, mask, parameter);
- });
- if (elementType == null) {
- elementType = types.dynamicType;
- }
- return recordType(parameter, elementType);
- }
-
- void updateAllParametersOf(FunctionElement function) {
- if (!hasAnalyzedAll) return;
- function.computeSignature(compiler).forEachParameter((Element parameter) {
- updateParameterType(parameter);
- });
- }
-
- /**
- * Registers that [caller] calls [callee] with the given
- * [arguments]. [constraint] is a setter constraint (see
- * [setterConstraints] documentation).
- */
- TypeMask registerCalledElement(Spannable node,
- Selector selector,
- Element caller,
- Element callee,
- ArgumentsTypes arguments,
- CallSite constraint,
- SideEffects sideEffects,
- bool inLoop) {
- updateSideEffects(sideEffects, selector, callee);
-
- // Bailout for closure calls. We're not tracking types of
- // arguments for closures.
- if (callee.isInstanceMember() && selector.isClosureCall()) {
- return types.dynamicType;
- }
- if (inLoop) {
- // For instance methods, we only register a selector called in a
- // loop if it is a typed selector, to avoid marking too many
- // methods as being called from within a loop. This cuts down
- // on the code bloat.
- // TODO(ngeoffray): We should move the filtering on the selector
- // in the backend. It is not the inferrer role to do this kind
- // of optimization.
- if (Elements.isStaticOrTopLevel(callee) || selector.mask != null) {
- compiler.world.addFunctionCalledInLoop(callee);
- }
- }
-
- assert(isNotClosure(caller));
- callee = callee.implementation;
- addCaller(caller, callee, node);
-
- if (selector != null && selector.isSetter() && callee.isField()) {
- recordTypeOfNonFinalField(
- node,
- callee,
- arguments.positional[0],
- constraint);
- return arguments.positional[0];
- } else if (selector != null && selector.isGetter()) {
- assert(arguments == null);
- if (callee.isFunction()) {
- FunctionTypeInformation functionInfo = typeInformationOf(callee);
- functionInfo.canBeClosurized = true;
- return types.functionType;
- }
- return callee.isGetter()
- ? returnTypeOfElement(callee)
- : typeOfElement(callee);
- } else if (callee.isField() || callee.isGetter()) {
- // We're not tracking closure calls.
- return types.dynamicType;
- }
- FunctionElement function = callee;
- if (function.computeSignature(compiler).parameterCount == 0) {
- return returnTypeOfElement(callee);
- }
-
- assert(arguments != null);
- bool isUseful = addArguments(node, callee, arguments);
- if (hasAnalyzedAll && isUseful) {
- enqueueAgain(callee);
- }
- return returnTypeOfElement(callee);
- }
-
- void unregisterCalledElement(Node node,
- Selector selector,
- Element caller,
- Element callee) {
- typeInformationOf(callee).removeCall(caller, node);
- if (callee.isField()) {
- if (selector.isSetter()) {
- Map<Spannable, TypeMask> assignments =
- typeInformationOf(callee).assignments;
- if (assignments == null || !assignments.containsKey(node)) return;
- assignments.remove(node);
- if (hasAnalyzedAll) updateNonFinalFieldType(callee);
- }
- } else if (callee.isGetter()) {
- return;
- } else {
- FunctionElement element = callee;
- element.computeSignature(compiler).forEachParameter((Element parameter) {
- Map<Spannable, TypeMask> assignments =
- typeInformationOf(parameter).assignments;
- if (assignments == null || !assignments.containsKey(node)) return;
- assignments.remove(node);
- if (hasAnalyzedAll) enqueueAgain(callee);
- });
- }
- }
-
- TypeMask addReturnTypeFor(Element element,
- TypeMask existing,
- TypeMask newType) {
- return computeLubFor(existing, newType, element);
- }
-
- TypeMask computeLubFor(TypeMask firstType,
- TypeMask secondType,
- Element element) {
- if (secondType.isElement) {
- ElementTypeMask mask = secondType;
- if (element == mask.element) {
- // Simple constraint of the abstract form [: foo = foo :], for
- // example a recursive function passing the same parameter.
- return firstType;
- }
- }
- return types.computeLUB(firstType, secondType);
- }
-
- TypeMask handleIntrisifiedSelector(Selector selector,
- ArgumentsTypes arguments) {
- // If [:compiler.intClass:] has not been resolved, there are no int values
- // in the program.
- if (!compiler.intClass.isResolved) return null;
- TypeMask intType = types.intType;
- if (selector.mask != intType) return null;
- if (!selector.isCall() && !selector.isOperator()) return null;
- if (!arguments.named.isEmpty) return null;
- if (arguments.positional.length > 1) return null;
-
- SourceString name = selector.name;
- if (name == const SourceString('*')
- || name == const SourceString('+')
- || name == const SourceString('%')
- || name == const SourceString('remainder')) {
- return arguments.hasOnePositionalArgumentWithType(intType)
- ? intType
- : null;
- } else if (name == const SourceString('-')) {
- if (arguments.hasNoArguments()) return intType;
- if (arguments.hasOnePositionalArgumentWithType(intType)) return intType;
- return null;
- } else if (name == const SourceString('abs')) {
- return arguments.hasNoArguments() ? intType : null;
- }
- return null;
- }
-
- /**
- * Registers that [caller] calls an element matching [selector]
- * with the given [arguments].
- */
- TypeMask registerCalledSelector(Node node,
- Selector selector,
- TypeMask receiverType,
- Element caller,
- ArgumentsTypes arguments,
- CallSite constraint,
- SideEffects sideEffects,
- bool inLoop) {
- TypeMask result;
- Iterable<Element> untypedTargets =
- compiler.world.allFunctions.filter(selector.asUntyped);
- Iterable<Element> typedTargets =
- compiler.world.allFunctions.filter(selector);
- for (Element element in untypedTargets) {
- element = element.implementation;
- if (!typedTargets.contains(element.declaration)) {
- unregisterCalledElement(node, selector, caller, element);
- } else {
- registerCalledElement(
- node, selector, caller, element, arguments,
- constraint, sideEffects, inLoop);
- // We cannot use the type returned by [registerCalledElement]
- // here because it does not handle [noSuchMethod]
- // targets, unlike [typeOfElementWithSelector].
- if (!selector.isSetter()) {
- TypeMask type = handleIntrisifiedSelector(selector, arguments);
- if (type == null) type = typeOfElementWithSelector(element, selector);
- result = types.computeLUB(result, type);
- }
- }
- }
-
- if (result == null) {
- result = types.dynamicType;
- }
- return result;
- }
-
- /**
- * Records an assignment to [element] with the given
- * [argumentType].
- */
- void recordTypeOfNonFinalField(Spannable node,
- Element element,
- TypeMask argumentType,
- CallSite constraint) {
- TypeInformation info = typeInformationOf(element);
- info.addAssignment(node, argumentType);
- bool changed = info.type != argumentType;
- if (constraint != null && constraint != setterConstraints[node]) {
- changed = true;
- setterConstraints[node] = constraint;
- }
- // If we have analyzed all elements, we can update the type of the
- // field right away.
- if (hasAnalyzedAll && changed) {
- updateNonFinalFieldType(element);
- }
- }
-
- TypeMask computeTypeWithConstraints(Element element,
- Map<Spannable, TypeMask> assignments) {
- List<CallSite> constraints = <CallSite>[];
- TypeMask elementType;
- assignments.forEach((Spannable node, TypeMask mask) {
- CallSite constraint = setterConstraints[node];
- if (constraint != null) {
- // If this update has a constraint, we collect it and don't
- // use its type.
- constraints.add(constraint);
- } else {
- elementType = computeLubFor(elementType, mask, element);
- }
- });
-
- if (!constraints.isEmpty && !isDynamicType(elementType)) {
- // Now that we have found a type, we go over the collected
- // constraints, and make sure they apply to the found type. We
- // update [typeOf] to make sure [returnTypeOfSelector] knows the field
- // type.
- TypeInformation info = typeInformationOf(element);
- TypeMask existing = info.type;
- info.type = elementType;
-
- for (CallSite constraint in constraints) {
- Selector selector = constraint.selector;
- TypeMask type;
- if (selector.isOperator()) {
- // If the constraint is on an operator, we type the receiver
- // to be the field.
- if (elementType != null) {
- selector = types.newTypedSelector(elementType, selector);
- }
- type = handleIntrisifiedSelector(selector, constraint.arguments);
- if (type == null) type = returnTypeOfSelector(selector);
- } else {
- // Otherwise the constraint is on the form [: field = other.field :].
- assert(selector.isGetter());
- type = returnTypeOfSelector(selector);
- }
- elementType = types.computeLUB(elementType, type);
- }
- info.type = existing;
- }
- if (elementType == null) {
- elementType = new TypeMask.nonNullEmpty();
- }
- return elementType;
- }
-
- /**
- * Computes the type of [element], based on all assignments we have
- * collected on that [element]. This method can only be called after
- * we have analyzed all elements in the world.
- */
- void updateNonFinalFieldType(Element element) {
- if (isNativeElement(element)) return;
- assert(hasAnalyzedAll);
-
- TypeInformation info = typeInformationOf(element);
- Map<Spannable, TypeMask> assignments = info.assignments;
- if (assignments.isEmpty) return;
-
- TypeMask fieldType = computeTypeWithConstraints(element, assignments);
-
- // If the type of [element] has changed, re-analyze its users.
- if (recordType(element, fieldType)) {
- enqueueCallersOf(element);
- }
- }
-
- /**
- * Records in [classInfoForFinalFields] that [constructor] has
- * inferred [type] for the final [field].
- */
- void recordTypeOfFinalField(Node node,
- Element constructor,
- Element field,
- TypeMask type,
- CallSite constraint) {
- if (constraint != null) {
- setterConstraints[node] = constraint;
- }
- // If the field is being set at its declaration site, it is not
- // being tracked in the [classInfoForFinalFields] map.
- if (constructor == field) return;
- assert(field.modifiers.isFinal() || field.modifiers.isConst());
- TypeInformation info = typeInformationOf(field);
- info.addAssignment(node, type);
- }
-
- /**
- * Records that we are done analyzing [constructor]. If all
- * generative constructors of its enclosing class have already been
- * analyzed, this method updates the types of final fields.
- */
- void onGenerativeConstructorAnalyzed(Element constructor) {
- ClassElement cls = constructor.getEnclosingClass();
- ClassTypeInformation info = classInfoForFinalFields[cls.implementation];
- info.onGenerativeConstructorAnalyzed(constructor);
- if (info.isDone) {
- updateFinalFieldsType(info, constructor.getEnclosingClass());
- }
- }
-
- /**
- * Updates types of final fields listed in [info].
- */
- void updateFinalFieldsType(ClassTypeInformation info, ClassElement cls) {
- assert(info.isDone);
- cls.forEachInstanceField((_, Element field) {
- if (isNativeElement(field)) return;
- if (!field.modifiers.isFinal()) return;
- // If the field is being set at its declaration site, it is not
- // being tracked in the [classInfoForFinalFields] map.
- if (field.parseNode(compiler).asSendSet() != null) return;
- TypeInformation info = typeInformationOf(field);
- TypeMask fieldType = computeTypeWithConstraints(field, info.assignments);
- if (recordType(field, fieldType)) {
- enqueueCallersOf(field);
- }
- });
- }
-
- void setDefaultTypeOfParameter(Element parameter, TypeMask type) {
- ParameterTypeInformation info = typeInformationOf(parameter);
- info.defaultType = type;
- }
-}
-
-class SimpleTypeInferrerVisitor<T>
- extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> {
- T returnType;
- bool visitingInitializers = false;
- bool isConstructorRedirect = false;
- SideEffects sideEffects = new SideEffects.empty();
- final Element outermostElement;
- final InferrerEngine<T, TypeSystem<T>> inferrer;
- final Set<Element> capturedVariables = new Set<Element>();
-
- SimpleTypeInferrerVisitor.internal(analyzedElement,
- this.outermostElement,
- inferrer,
- compiler,
- locals)
- : super(analyzedElement, inferrer, inferrer.types, compiler, locals),
- this.inferrer = inferrer;
-
- factory SimpleTypeInferrerVisitor(Element element,
- Compiler compiler,
- InferrerEngine<T, TypeSystem<T>> inferrer,
- [LocalsHandler<T> handler]) {
- Element outermostElement =
- element.getOutermostEnclosingMemberOrTopLevel().implementation;
- assert(outermostElement != null);
- return new SimpleTypeInferrerVisitor<T>.internal(
- element, outermostElement, inferrer, compiler, handler);
- }
-
- T run() {
- var node = analyzedElement.parseNode(compiler);
- if (analyzedElement.isField() && node.asSendSet() == null) {
- // Eagerly bailout, because computing the closure data only
- // works for functions and field assignments.
- return types.nullType;
- }
- // Update the locals that are boxed in [locals]. These locals will
- // be handled specially, in that we are computing their LUB at
- // each update, and reading them yields the type that was found in a
- // previous analysis of [outermostElement].
- ClosureClassMap closureData =
- compiler.closureToClassMapper.computeClosureToClassMapping(
- analyzedElement, node, elements);
- closureData.forEachBoxedVariable((variable, field) {
- locals.setCapturedAndBoxed(variable, field);
- });
- if (analyzedElement.isField()) {
- return visit(node.asSendSet().arguments.head);
- }
-
- FunctionElement function = analyzedElement;
- inferrer.updateAllParametersOf(function);
- FunctionSignature signature = function.computeSignature(compiler);
- signature.forEachOptionalParameter((element) {
- Node node = element.parseNode(compiler);
- Send send = node.asSendSet();
- T type = (send == null) ? types.nullType : visit(send.arguments.head);
- inferrer.setDefaultTypeOfParameter(element, type);
- });
-
- if (analyzedElement.isNative()) {
- // Native methods do not have a body, and we currently just say
- // they return dynamic.
- return types.dynamicType;
- }
-
- if (analyzedElement.isGenerativeConstructor()) {
- isThisExposed = false;
- signature.forEachParameter((element) {
- T parameterType = inferrer.typeOfElement(element);
- if (element.kind == ElementKind.FIELD_PARAMETER) {
- if (element.fieldElement.modifiers.isFinal()) {
- inferrer.recordTypeOfFinalField(
- node,
- analyzedElement,
- element.fieldElement,
- parameterType,
- null);
- } else {
- locals.updateField(element.fieldElement, parameterType);
- inferrer.recordTypeOfNonFinalField(
- element.parseNode(compiler),
- element.fieldElement,
- parameterType,
- null);
- }
- }
- locals.update(element, parameterType, node);
- });
- if (analyzedElement.isSynthesized) {
- node = analyzedElement;
- synthesizeForwardingCall(node, analyzedElement.targetConstructor);
- } else {
- visitingInitializers = true;
- visit(node.initializers);
- visitingInitializers = false;
- visit(node.body);
- }
- ClassElement cls = analyzedElement.getEnclosingClass();
- if (!isConstructorRedirect) {
- // Iterate over all instance fields, and give a null type to
- // fields that we haven't initialized for sure.
- cls.forEachInstanceField((_, field) {
- if (field.modifiers.isFinal()) return;
- T type = locals.fieldScope.readField(field);
- if (type == null && field.parseNode(compiler).asSendSet() == null) {
- inferrer.recordTypeOfNonFinalField(
- node, field, types.nullType, null);
- }
- });
- }
- inferrer.onGenerativeConstructorAnalyzed(analyzedElement);
- returnType = types.nonNullExact(cls.rawType);
- } else {
- signature.forEachParameter((element) {
- locals.update(element, inferrer.typeOfElement(element), node);
- });
- visit(node.body);
- if (returnType == null) {
- // No return in the body.
- returnType = locals.seenReturnOrThrow
- ? types.nonNullEmpty() // Body always throws.
- : types.nullType;
- } else if (!locals.seenReturnOrThrow) {
- // We haven't seen returns on all branches. So the method may
- // also return null.
- returnType = inferrer.addReturnTypeFor(
- analyzedElement, returnType, types.nullType);
- }
- }
-
- compiler.world.registerSideEffects(analyzedElement, sideEffects);
- assert(breaksFor.isEmpty);
- assert(continuesFor.isEmpty);
- return returnType;
- }
-
- T visitFunctionExpression(FunctionExpression node) {
- Element element = elements[node];
- // We don't put the closure in the work queue of the
- // inferrer, because it will share information with its enclosing
- // method, like for example the types of local variables.
- LocalsHandler closureLocals = new LocalsHandler<T>.from(
- locals, node, useOtherTryBlock: false);
- SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor<T>(
- element, compiler, inferrer, closureLocals);
- visitor.run();
- inferrer.recordReturnType(element, visitor.returnType);
-
- // Record the types of captured non-boxed variables. Types of
- // these variables may already be there, because of an analysis of
- // a previous closure. Note that analyzing the same closure multiple
- // times closure will refine the type of those variables, therefore
- // [:inferrer.typeOf[variable]:] is not necessarilly null, nor the
- // same as [newType].
- ClosureClassMap nestedClosureData =
- compiler.closureToClassMapper.getMappingForNestedFunction(node);
- nestedClosureData.forEachCapturedVariable((variable, field) {
- if (!nestedClosureData.isVariableBoxed(variable)) {
- if (variable == nestedClosureData.thisElement) {
- inferrer.recordType(field, thisType);
- }
- // The type is null for type parameters.
- if (locals.locals[variable] == null) return;
- inferrer.recordType(field, locals.locals[variable]);
- }
- capturedVariables.add(variable);
- });
-
- return types.functionType;
- }
-
- T visitLiteralList(LiteralList node) {
- if (node.isConst()) {
- // We only set the type once. We don't need to re-visit the children
- // when re-analyzing the node.
- return inferrer.concreteTypes.putIfAbsent(node, () {
- T elementType;
- int length = 0;
- for (Node element in node.elements.nodes) {
- T type = visit(element);
- elementType = elementType == null
- ? types.allocatePhi(null, null, type)
- : types.addPhiInput(null, elementType, type);
- length++;
- }
- elementType = elementType == null
- ? types.nonNullEmpty()
- : types.simplifyPhi(null, null, elementType);
- return types.allocateContainer(
- types.constListType,
- node,
- outermostElement,
- elementType,
- length);
- });
- } else {
- node.visitChildren(this);
- return inferrer.concreteTypes.putIfAbsent(node, () {
- return types.allocateContainer(
- types.growableListType,
- node,
- outermostElement);
- });
- }
- }
-
- bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
-
- void checkIfExposesThis(Selector selector) {
- if (isThisExposed) return;
- inferrer.forEachElementMatching(selector, (element) {
- if (element.isField()) {
- if (!selector.isSetter()
- && element.getEnclosingClass() ==
- outermostElement.getEnclosingClass()
- && !element.modifiers.isFinal()
- && locals.fieldScope.readField(element) == null
- && element.parseNode(compiler).asSendSet() == null) {
- // If the field is being used before this constructor
- // actually had a chance to initialize it, say it can be
- // null.
- inferrer.recordTypeOfNonFinalField(
- analyzedElement.parseNode(compiler), element,
- types.nullType, null);
- }
- // Accessing a field does not expose [:this:].
- return true;
- }
- // TODO(ngeoffray): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = true;
- return false;
- });
- }
-
- bool get inInstanceContext {
- return (outermostElement.isInstanceMember() && !outermostElement.isField())
- || outermostElement.isGenerativeConstructor();
- }
-
- bool treatAsInstanceMember(Element element) {
- return (Elements.isUnresolved(element) && inInstanceContext)
- || (element != null && element.isInstanceMember());
- }
-
- T visitSendSet(SendSet node) {
- Element element = elements[node];
- if (!Elements.isUnresolved(element) && element.impliesType()) {
- node.visitChildren(this);
- return types.dynamicType;
- }
-
- Selector getterSelector =
- elements.getGetterSelectorInComplexSendSet(node);
- Selector operatorSelector =
- elements.getOperatorSelectorInComplexSendSet(node);
- Selector setterSelector = elements.getSelector(node);
-
- String op = node.assignmentOperator.source.stringValue;
- bool isIncrementOrDecrement = op == '++' || op == '--';
-
- T receiverType;
- bool isCallOnThis = false;
- if (node.receiver == null) {
- if (treatAsInstanceMember(element)) {
- receiverType = thisType;
- isCallOnThis = true;
- }
- } else {
- receiverType = visit(node.receiver);
- isCallOnThis = isThisOrSuper(node.receiver);
- }
-
- T rhsType;
- T indexType;
-
- if (isIncrementOrDecrement) {
- rhsType = types.intType;
- if (node.isIndex) indexType = visit(node.arguments.head);
- } else if (node.isIndex) {
- indexType = visit(node.arguments.head);
- rhsType = visit(node.arguments.tail.head);
- } else {
- rhsType = visit(node.arguments.head);
- }
-
- if (!visitingInitializers && !isThisExposed) {
- for (Node node in node.arguments) {
- if (isThisOrSuper(node)) {
- isThisExposed = true;
- break;
- }
- }
- if (!isThisExposed && isCallOnThis) {
- checkIfExposesThis(
- types.newTypedSelector(receiverType, setterSelector));
- if (getterSelector != null) {
- checkIfExposesThis(
- types.newTypedSelector(receiverType, getterSelector));
- }
- }
- }
-
- if (node.isIndex) {
- if (op == '=') {
- // [: foo[0] = 42 :]
- handleDynamicSend(
- node,
- setterSelector,
- receiverType,
- new ArgumentsTypes<T>([indexType, rhsType], null));
- return rhsType;
- } else {
- // [: foo[0] += 42 :] or [: foo[0]++ :].
- T getterType = handleDynamicSend(
- node,
- getterSelector,
- receiverType,
- new ArgumentsTypes<T>([indexType], null));
- T returnType = handleDynamicSend(
- node,
- operatorSelector,
- getterType,
- new ArgumentsTypes<T>([rhsType], null));
- handleDynamicSend(
- node,
- setterSelector,
- receiverType,
- new ArgumentsTypes<T>([indexType, returnType], null));
-
- if (node.isPostfix) {
- return getterType;
- } else {
- return returnType;
- }
- }
- } else if (op == '=') {
- return handlePlainAssignment(
- node, element, setterSelector, receiverType, rhsType,
- node.arguments.head);
- } else {
- // [: foo++ :] or [: foo += 1 :].
- ArgumentsTypes operatorArguments = new ArgumentsTypes<T>([rhsType], null);
- CallSite constraint;
- if (!Elements.isLocal(element)) {
- // Record a constraint of the form [: field++ :], or [: field += 42 :].
- constraint = new CallSite(operatorSelector, operatorArguments);
- }
- T getterType;
- T newType;
- if (Elements.isErroneousElement(element)) {
- getterType = types.dynamicType;
- newType = types.dynamicType;
- } else if (Elements.isStaticOrTopLevelField(element)) {
- Element getterElement = elements[node.selector];
- getterType =
- handleStaticSend(node, getterSelector, getterElement, null);
- newType = handleDynamicSend(
- node, operatorSelector, getterType, operatorArguments);
- handleStaticSend(
- node, setterSelector, element,
- new ArgumentsTypes<T>([newType], null));
- } else if (Elements.isUnresolved(element)
- || element.isSetter()
- || element.isField()) {
- getterType = handleDynamicSend(
- node, getterSelector, receiverType, null);
- newType = handleDynamicSend(
- node, operatorSelector, getterType, operatorArguments);
- handleDynamicSend(node, setterSelector, receiverType,
- new ArgumentsTypes<T>([newType], null),
- constraint);
- } else if (Elements.isLocal(element)) {
- getterType = locals.use(element);
- newType = handleDynamicSend(
- node, operatorSelector, getterType, operatorArguments);
- locals.update(element, newType, node);
- } else {
- // Bogus SendSet, for example [: myMethod += 42 :].
- getterType = types.dynamicType;
- newType = handleDynamicSend(
- node, operatorSelector, getterType, operatorArguments);
- }
-
- if (node.isPostfix) {
- return getterType;
- } else {
- return newType;
- }
- }
- }
-
- T handlePlainAssignment(Node node,
- Element element,
- Selector setterSelector,
- T receiverType,
- T rhsType,
- Node rhs) {
- CallSite constraint;
- if (node.asSend() != null && !Elements.isLocal(element)) {
- // Recognize a constraint of the form [: field = other.field :].
- // Note that we check if the right hand side is a local to
- // recognize the situation [: var a = 42; this.a = a; :]. Our
- // constraint mechanism only works with members or top level
- // elements.
- Send send = rhs.asSend();
- if (send != null
- && send.isPropertyAccess
- && !Elements.isLocal(elements[rhs])
- && send.selector.asIdentifier().source
- == node.asSend().selector.asIdentifier().source) {
- constraint = new CallSite(elements.getSelector(rhs), null);
- }
- }
- ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null);
- if (Elements.isErroneousElement(element)) {
- // Code will always throw.
- } else if (Elements.isStaticOrTopLevelField(element)) {
- handleStaticSend(node, setterSelector, element, arguments);
- } else if (Elements.isUnresolved(element) || element.isSetter()) {
- handleDynamicSend(
- node, setterSelector, receiverType, arguments, constraint);
- } else if (element.isField()) {
- if (element.modifiers.isFinal()) {
- inferrer.recordTypeOfFinalField(
- node, outermostElement, element, rhsType, constraint);
- } else {
- if (analyzedElement.isGenerativeConstructor()) {
- locals.updateField(element, rhsType);
- }
- if (visitingInitializers) {
- inferrer.recordTypeOfNonFinalField(
- node, element, rhsType, constraint);
- } else {
- handleDynamicSend(
- node, setterSelector, receiverType, arguments, constraint);
- }
- }
- } else if (Elements.isLocal(element)) {
- locals.update(element, rhsType, node);
- }
- return rhsType;
- }
-
- T visitSuperSend(Send node) {
- Element element = elements[node];
- if (Elements.isUnresolved(element)) {
- return types.dynamicType;
- }
- Selector selector = elements.getSelector(node);
- // TODO(ngeoffray): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = true;
- if (node.isPropertyAccess) {
- return handleStaticSend(node, selector, element, null);
- } else if (element.isFunction() || element.isGenerativeConstructor()) {
- if (!selector.applies(element, compiler)) return types.dynamicType;
- ArgumentsTypes arguments = analyzeArguments(node.arguments);
- return handleStaticSend(node, selector, element, arguments);
- } else {
- analyzeArguments(node.arguments);
- // Closure call on a getter. We don't have function types yet,
- // so we just return [:dynamic:].
- return types.dynamicType;
- }
- }
-
- T visitStaticSend(Send node) {
- if (visitingInitializers && Initializers.isConstructorRedirect(node)) {
- isConstructorRedirect = true;
- }
- Element element = elements[node];
- if (element.isForeign(compiler)) {
- return handleForeignSend(node);
- }
- Selector selector = elements.getSelector(node);
- ArgumentsTypes arguments = analyzeArguments(node.arguments);
- if (!selector.applies(element, compiler)) return types.dynamicType;
-
- T returnType = handleStaticSend(node, selector, element, arguments);
- if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
- return inferrer.concreteTypes.putIfAbsent(
- node, () => types.allocateContainer(
- types.growableListType, node, outermostElement));
- } else if (Elements.isFixedListConstructorCall(element, node, compiler)
- || Elements.isFilledListConstructorCall(element, node, compiler)) {
- return inferrer.concreteTypes.putIfAbsent(
- node, () => types.allocateContainer(
- types.fixedListType, node, outermostElement));
- } else if (element.isFunction() || element.isConstructor()) {
- return returnType;
- } else {
- assert(element.isField() || element.isGetter());
- // Closure call.
- return types.dynamicType;
- }
- }
-
- T handleForeignSend(Send node) {
- node.visitChildren(this);
- Selector selector = elements.getSelector(node);
- SourceString name = selector.name;
- if (name == const SourceString('JS')) {
- native.NativeBehavior nativeBehavior =
- compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
- sideEffects.add(nativeBehavior.sideEffects);
- return inferrer.typeOfNativeBehavior(nativeBehavior);
- } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')
- || name == const SourceString('JS_OPERATOR_AS_PREFIX')
- || name == const SourceString('JS_OBJECT_CLASS_NAME')
- || name == const SourceString('JS_NULL_CLASS_NAME')) {
- return types.stringType;
- } else {
- sideEffects.setAllSideEffects();
- return types.dynamicType;
- }
- }
-
- ArgumentsTypes analyzeArguments(Link<Node> arguments) {
- List<T> positional = [];
- Map<SourceString, T> named = new Map<SourceString, T>();
- for (var argument in arguments) {
- NamedArgument namedArgument = argument.asNamedArgument();
- if (namedArgument != null) {
- argument = namedArgument.expression;
- named[namedArgument.name.source] = argument.accept(this);
- } else {
- positional.add(argument.accept(this));
- }
- // TODO(ngeoffray): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = isThisExposed || argument.isThis();
- }
- return new ArgumentsTypes<T>(positional, named);
- }
-
- T visitGetterSend(Send node) {
- Element element = elements[node];
- Selector selector = elements.getSelector(node);
- if (Elements.isStaticOrTopLevelField(element)) {
- return handleStaticSend(node, selector, element, null);
- } else if (Elements.isInstanceSend(node, elements)) {
- return visitDynamicSend(node);
- } else if (Elements.isStaticOrTopLevelFunction(element)) {
- return handleStaticSend(node, selector, element, null);
- } else if (Elements.isErroneousElement(element)) {
- return types.dynamicType;
- } else if (Elements.isLocal(element)) {
- assert(locals.use(element) != null);
- return locals.use(element);
- } else {
- node.visitChildren(this);
- return types.dynamicType;
- }
- }
-
- T visitClosureSend(Send node) {
- node.visitChildren(this);
- Element element = elements[node];
- Selector selector = elements.getSelector(node);
- if (element != null && element.isFunction()) {
- assert(Elements.isLocal(element));
- // This only works for function statements. We need a
- // more sophisticated type system with function types to support
- // more.
- inferrer.updateSideEffects(sideEffects, selector, element);
- return inferrer.returnTypeOfElement(element);
- }
- sideEffects.setDependsOnSomething();
- sideEffects.setAllSideEffects();
- return types.dynamicType;
- }
-
- T handleStaticSend(Node node,
- Selector selector,
- Element element,
- ArgumentsTypes arguments) {
- if (Elements.isUnresolved(element)) return types.dynamicType;
- return inferrer.registerCalledElement(
- node, selector, outermostElement, element, arguments, null,
- sideEffects, inLoop);
- }
-
- T handleDynamicSend(Node node,
- Selector selector,
- T receiverType,
- ArgumentsTypes arguments,
- [CallSite constraint]) {
- assert(receiverType != null);
- if (selector.mask != receiverType) {
- selector = (receiverType == types.dynamicType)
- ? selector.asUntyped
- : types.newTypedSelector(receiverType, selector);
- inferrer.updateSelectorInTree(analyzedElement, node, selector);
- }
-
- // If the receiver of the call is a local, we may know more about
- // its type by refining it with the potential targets of the
- // calls.
- if (node.asSend() != null) {
- Node receiver = node.asSend().receiver;
- if (receiver != null) {
- Element element = elements[receiver];
- if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
- T refinedType = types.refineReceiver(selector, receiverType);
- locals.update(element, refinedType, node);
- }
- }
- }
-
- return inferrer.registerCalledSelector(
- node, selector, receiverType, outermostElement, arguments,
- constraint, sideEffects, inLoop);
- }
-
- T visitDynamicSend(Send node) {
- Element element = elements[node];
- T receiverType;
- bool isCallOnThis = false;
- if (node.receiver == null) {
- if (treatAsInstanceMember(element)) {
- isCallOnThis = true;
- receiverType = thisType;
- }
- } else {
- Node receiver = node.receiver;
- isCallOnThis = isThisOrSuper(receiver);
- receiverType = visit(receiver);
- }
-
- Selector selector = elements.getSelector(node);
- if (!isThisExposed && isCallOnThis) {
- checkIfExposesThis(types.newTypedSelector(receiverType, selector));
- }
-
- ArgumentsTypes arguments = node.isPropertyAccess
- ? null
- : analyzeArguments(node.arguments);
- return handleDynamicSend(node, selector, receiverType, arguments);
- }
-
- void recordReturnType(T type) {
- returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type);
- }
-
- T synthesizeForwardingCall(Spannable node, FunctionElement element) {
- element = element.implementation;
- FunctionElement function = analyzedElement;
- FunctionSignature signature = function.computeSignature(compiler);
- FunctionSignature calleeSignature = element.computeSignature(compiler);
- if (!calleeSignature.isCompatibleWith(signature)) {
- return types.nonNullEmpty();
- }
-
- List<T> unnamed = <T>[];
- Map<SourceString, T> named = new Map<SourceString, T>();
- signature.forEachRequiredParameter((Element element) {
- assert(locals.use(element) != null);
- unnamed.add(locals.use(element));
- });
- signature.forEachOptionalParameter((Element element) {
- if (signature.optionalParametersAreNamed) {
- named[element.name] = locals.use(element);
- } else {
- unnamed.add(locals.use(element));
- }
- });
- ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named);
- inferrer.registerCalledElement(node,
- null,
- outermostElement,
- element,
- arguments,
- null,
- sideEffects,
- inLoop);
- return inferrer.returnTypeOfElement(element);
- }
-
- T visitReturn(Return node) {
- if (node.isRedirectingFactoryBody) {
- Element element = elements[node.expression];
- if (Elements.isErroneousElement(element)) {
- recordReturnType(types.dynamicType);
- } else {
- // We don't create a selector for redirecting factories, and
- // the send is just a property access. Therefore we must
- // manually create the [ArgumentsTypes] of the call, and
- // manually register [analyzedElement] as a caller of [element].
- T mask = synthesizeForwardingCall(node.expression, element);
- recordReturnType(mask);
- }
- } else {
- Node expression = node.expression;
- recordReturnType(expression == null
- ? types.nullType
- : expression.accept(this));
- }
- locals.seenReturnOrThrow = true;
- }
-
- T visitForIn(ForIn node) {
- T expressionType = visit(node.expression);
- Selector iteratorSelector = elements.getIteratorSelector(node);
- Selector currentSelector = elements.getCurrentSelector(node);
- Selector moveNextSelector = elements.getMoveNextSelector(node);
-
- T iteratorType =
- handleDynamicSend(node, iteratorSelector, expressionType, null);
- handleDynamicSend(node, moveNextSelector,
- iteratorType, new ArgumentsTypes<T>([], null));
- T currentType =
- handleDynamicSend(node, currentSelector, iteratorType, null);
-
- if (node.expression.isThis()) {
- // Any reasonable implementation of an iterator would expose
- // this, so we play it safe and assume it will.
- isThisExposed = true;
- }
-
- Node identifier = node.declaredIdentifier;
- Element element = elements[identifier];
- Selector selector = elements.getSelector(identifier);
-
- T receiverType;
- if (element != null && element.isInstanceMember()) {
- receiverType = thisType;
- } else {
- receiverType = types.dynamicType;
- }
-
- handlePlainAssignment(identifier, element, selector,
- receiverType, currentType,
- node.expression);
- return handleLoop(node, () {
- visit(node.body);
- });
- }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart
deleted file mode 100644
index 10d96a0..0000000
--- a/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart
+++ /dev/null
@@ -1,1417 +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.
-
-library type_graph_inferrer;
-
-import 'dart:collection' show Queue, LinkedHashSet, IterableBase, HashMap;
-import '../dart_types.dart' show DartType, InterfaceType, TypeKind;
-import '../elements/elements.dart';
-import '../tree/tree.dart' show Node;
-import 'types.dart' show TypeMask, ContainerTypeMask, TypesInferrer;
-import '../universe/universe.dart' show Selector, TypedSelector, SideEffects;
-import '../dart2jslib.dart' show Compiler, SourceString, TreeElementMapping;
-import 'inferrer_visitor.dart' show TypeSystem, ArgumentsTypes, CallSite;
-import '../native_handler.dart' as native;
-import '../util/util.dart' show Spannable;
-import 'simple_types_inferrer.dart';
-import '../dart2jslib.dart' show invariant;
-
-/**
- * Common class for all nodes in the graph. The current nodes are:
- *
- * - Concrete types
- * - Elements
- * - Call sites
- * - Narrowing instructions
- * - Phi instructions
- * - Containers (for lists)
- * - Type of the element in a container
- *
- * A node has a set of assignments and users. Assignments are used to
- * compute the type of the node ([TypeInformation.refine]). Users are
- * added to the inferrer's work queue when the type of the node
- * changes.
- */
-abstract class TypeInformation {
- var /* List|Set */ users;
- var /* List|ParameterAssignments */ assignments;
-
- /// The type the inferrer has found for this [TypeInformation].
- /// Initially dynamic.
- TypeMask type;
-
- /// We give up on inferencing for special elements, as well as for
- /// complicated cyclic dependencies.
- bool abandonInferencing = false;
-
- /// Number of times this [TypeInformation] has changed type.
- int refineCount = 0;
-
- /// Whether this [TypeInformation] is currently in the inferrer's
- /// work queue.
- bool inQueue = false;
-
- // TypeInformations are unique.
- static int staticHashCode = 0;
- final int hashCode = staticHashCode++;
-
- bool get isConcrete => false;
-
- TypeInformation(this.type, [users, assignments])
- : users = (users == null) ? new Set<TypeInformation>() : users,
- assignments = (assignments == null) ? <TypeInformation>[] : assignments;
-
-
- void addUser(TypeInformation user) {
- assert(!user.isConcrete);
- users.add(user);
- }
-
- void removeUser(TypeInformation user) {
- assert(!user.isConcrete);
- users.remove(user);
- }
-
- void addAssignment(TypeInformation assignment) {
- if (abandonInferencing) return;
- // Cheap one-level cycle detection.
- if (assignment == this) return;
- assignments.add(assignment);
- assignment.addUser(this);
- }
-
- void removeAssignment(TypeInformation assignment) {
- if (!abandonInferencing) {
- assignments.remove(assignment);
- }
- // We can have multiple assignments of the same [TypeInformation].
- if (!assignments.contains(assignment)) {
- assignment.removeUser(this);
- }
- }
-
- TypeMask refine(TypeGraphInferrerEngine inferrer) {
- return type;
- }
-
- TypeMask refineOptimistic(TypeGraphInferrerEngine inferrer) {
- return refine(inferrer);
- }
-
- void giveUp(TypeGraphInferrerEngine inferrer) {
- abandonInferencing = true;
- type = inferrer.types.dynamicType.type;
- assignments = const <TypeInformation>[];
- }
-
- void clear() {
- assignments = const <TypeInformation>[];
- users = const <TypeInformation>[];
- }
-}
-
-/**
- * Parameters of instance functions behave differently than other
- * elements because the inferrer may remove assignments. This happens
- * when the receiver of a dynamic call site can be refined
- * to a type where we know more about which instance method is being
- * called.
- */
-class ParameterAssignments extends IterableBase<TypeInformation> {
- final Map<TypeInformation, int> assignments =
- new HashMap<TypeInformation, int>();
-
- void remove(TypeInformation info) {
- int existing = assignments[info];
- if (existing == null) return;
- if (existing == 1) {
- assignments.remove(info);
- } else {
- assignments[info] = existing - 1;
- }
- }
-
- void add(TypeInformation info) {
- int existing = assignments[info];
- if (existing == null) {
- assignments[info] = 1;
- } else {
- assignments[info] = existing + 1;
- }
- }
-
- Iterator<TypeInformation> get iterator => assignments.keys.iterator;
- Iterable<TypeInformation> where(Function f) => assignments.keys.where(f);
-
- bool contains(TypeInformation info) => assignments.containsKey(info);
-}
-
-/**
- * A node representing a resolved element of the program. The kind of
- * elements that need an [ElementTypeRepresentation] are:
- *
- * - Functions (including getters and setters)
- * - Constructors (factory or generative)
- * - Fields
- * - Parameters
- * - Local variables mutated in closures
- *
- * The [ElementTypeInformation] of a function and a constructor is its
- * return type.
- *
- * Note that a few elements of these kinds must be treated specially,
- * and they are dealt in [ElementTypeInformation.handleSpecialCase]:
- *
- * - Parameters of closures, [noSuchMethod] and [call] instance
- * methods: we currently do not infer types for those.
- *
- * - Fields and parameters being assigned by synthesized calls done by
- * the backend: we do not know what types the backend will use.
- *
- * - Native functions and fields: because native methods contain no Dart
- * code, and native fields do not have Dart assignments, we just
- * trust their type annotation.
- *
- */
-class ElementTypeInformation extends TypeInformation {
- final Element element;
- final Map<Element, Set<Spannable>> callers =
- new Map<Element, Set<Spannable>>();
-
- ElementTypeInformation.internal(this.element, type, assignments)
- : super(type, null, assignments);
-
- factory ElementTypeInformation(Element element, TypeMask type) {
- var assignments = null;
- if (element.enclosingElement.isInstanceMember()
- && (element.isParameter() || element.isFieldParameter())) {
- assignments = new ParameterAssignments();
- }
- return new ElementTypeInformation.internal(element, type, assignments);
- }
-
- void addCall(Element caller, Spannable node) {
- callers.putIfAbsent(caller, () => new Set<Spannable>()).add(node);
- }
-
- void removeCall(Element caller, Spannable node) {
- Set<Spannable> calls = callers[caller];
- if (calls == null) return;
- calls.remove(node);
- if (calls.isEmpty) {
- callers.remove(caller);
- }
- }
-
- TypeMask handleSpecialCases(TypeGraphInferrerEngine inferrer) {
- if (abandonInferencing) {
- return type;
- }
- if (element.isParameter()) {
- Element enclosing = element.enclosingElement;
- if (Elements.isLocal(enclosing)) {
- // Do not infer types for parameters of closures.
- giveUp(inferrer);
- return type;
- } else if (enclosing.isInstanceMember()
- && (enclosing.name == Compiler.NO_SUCH_METHOD
- || enclosing.name == Compiler.CALL_OPERATOR_NAME)) {
- // Do not infer types for parameters of [noSuchMethod] and
- // [call] instance methods.
- giveUp(inferrer);
- return type;
- }
- }
- if (element.isField()
- || element.isParameter()
- || element.isFieldParameter()) {
- if (!inferrer.compiler.backend.canBeUsedForGlobalOptimizations(element)) {
- // Do not infer types for fields and parameters being assigned
- // by synthesized calls.
- giveUp(inferrer);
- return type;
- }
- }
- if (inferrer.isNativeElement(element)) {
- // Use the type annotation as the type for native elements. We
- // also give up on inferring to make sure this element never
- // goes in the work queue.
- giveUp(inferrer);
- if (element.isField()) {
- InterfaceType rawType = element.computeType(inferrer.compiler).asRaw();
- return rawType.treatAsDynamic
- ? inferrer.types.dynamicType.type
- : new TypeMask.subtype(rawType);
- } else {
- assert(element.isFunction()
- || element.isGetter()
- || element.isSetter());
- var elementType = element.computeType(inferrer.compiler);
- if (elementType.kind != TypeKind.FUNCTION) {
- return type;
- } else {
- return inferrer.typeOfNativeBehavior(
- native.NativeBehavior.ofMethod(element, inferrer.compiler)).type;
- }
- }
- }
- return null;
- }
-
- TypeMask potentiallyNarrowType(TypeMask mask,
- TypeGraphInferrerEngine inferrer) {
- Compiler compiler = inferrer.compiler;
- if (!compiler.trustTypeAnnotations && !compiler.enableTypeAssertions) {
- return mask;
- }
- if (element.isGenerativeConstructor() || element.isSetter()) return mask;
- var type = element.computeType(compiler);
- if (element.isFunction()
- || element.isGetter()
- || element.isFactoryConstructor()) {
- type = type.returnType;
- }
- return new TypeMaskSystem(compiler).narrowType(mask, type);
- }
-
- TypeMask refine(TypeGraphInferrerEngine inferrer) {
- TypeMask special = handleSpecialCases(inferrer);
- if (special != null) return potentiallyNarrowType(special, inferrer);
- return potentiallyNarrowType(
- inferrer.types.computeTypeMask(assignments), inferrer);
- }
-
- TypeMask refineOptimistic(TypeGraphInferrerEngine inferrer) {
- TypeMask special = handleSpecialCases(inferrer);
- if (special != null) return potentiallyNarrowType(special, inferrer);
- return potentiallyNarrowType(inferrer.types.computeTypeMask(
- assignments.where((e) => e.isConcrete)), inferrer);
- }
-
- String toString() => 'Element $element';
-}
-
-/**
- * A [CallSiteTypeInformation] is a call found in the AST, or a
- * synthesized call for implicit calls in Dart (such as forwarding
- * factories). The [call] field is a [Node] for the former, and an
- * [Element] for the latter.
- *
- * In the inferrer graph, [CallSiteTypeInformation] nodes do not have
- * any assignment. They rely on the [caller] field for static calls,
- * and [selector] and [receiver] fields for dynamic calls.
- */
-abstract class CallSiteTypeInformation extends TypeInformation {
- final Spannable call;
- final Element caller;
- final Selector selector;
- final ArgumentsTypes arguments;
-
- CallSiteTypeInformation(
- this.call,
- this.caller,
- this.selector,
- this.arguments,
- TypeMask type) : super(type, null, const <TypeInformation>[]);
-
- String toString() => 'Call site $call';
-
- /// Add [this] to the graph being computed by [engine].
- void addToGraph(TypeGraphInferrerEngine engine);
-
- /// Return an iterable over the targets of this call.
- Iterable<Element> get callees;
-}
-
-class StaticCallSiteTypeInformation extends CallSiteTypeInformation {
- final Element calledElement;
-
- StaticCallSiteTypeInformation(
- Spannable call,
- Element enclosing,
- this.calledElement,
- Selector selector,
- ArgumentsTypes arguments,
- TypeMask type) : super(call, enclosing, selector, arguments, type);
-
- void addToGraph(TypeGraphInferrerEngine inferrer) {
- ElementTypeInformation callee =
- inferrer.types.getInferredTypeOf(calledElement);
- callee.addCall(caller, call);
- callee.addUser(this);
- if (arguments != null) {
- arguments.forEach((info) => info.addUser(this));
- }
- inferrer.updateParameterAssignments(
- this, calledElement, arguments, selector, remove: false, init: true);
- }
-
- bool get isSynthesized {
- // Some calls do not have a corresponding node, for example
- // fowarding factory constructors, or synthesized super
- // constructor calls. We synthesize these calls but do
- // not create a selector for them.
- return selector == null;
- }
-
- TypeMask refine(TypeGraphInferrerEngine inferrer) {
- if (isSynthesized) {
- assert(arguments != null);
- return inferrer.types.getInferredTypeOf(calledElement).type;
- } else {
- return inferrer.typeOfElementWithSelector(calledElement, selector).type;
- }
- }
-
- Iterable<Element> get callees => [calledElement.implementation];
-}
-
-class DynamicCallSiteTypeInformation extends CallSiteTypeInformation {
- final TypeInformation receiver;
- /// Cached targets of this call.
- Iterable<Element> targets;
-
- DynamicCallSiteTypeInformation(
- Spannable call,
- Element enclosing,
- Selector selector,
- this.receiver,
- ArgumentsTypes arguments,
- TypeMask type) : super(call, enclosing, selector, arguments, type);
-
- void addToGraph(TypeGraphInferrerEngine inferrer) {
- assert(receiver != null);
- Selector typedSelector = computeTypedSelector(inferrer);
- targets = inferrer.compiler.world.allFunctions.filter(typedSelector);
- receiver.addUser(this);
- if (arguments != null) {
- arguments.forEach((info) => info.addUser(this));
- }
- for (Element element in targets) {
- ElementTypeInformation callee = inferrer.types.getInferredTypeOf(element);
- callee.addCall(caller, call);
- callee.addUser(this);
- inferrer.updateParameterAssignments(
- this, element, arguments, typedSelector, remove: false, init: true);
- }
- }
-
- Iterable<Element> get callees => targets.map((e) => e.implementation);
-
- Selector computeTypedSelector(TypeGraphInferrerEngine inferrer) {
- TypeMask receiverType = receiver.type;
- if (selector.mask != receiverType) {
- return receiverType == inferrer.compiler.typesTask.dynamicType
- ? selector.asUntyped
- : new TypedSelector(receiverType, selector);
- } else {
- return selector;
- }
- }
-
- bool hasOnePositionalArgumentWithType(TypeMask type) {
- return arguments.named.isEmpty
- && arguments.positional.length == 1
- && arguments.positional[0].type == type;
- }
-
- /**
- * We optimize certain operations on the [int] class because we know
- * more about their return type than the actual Dart code. For
- * example, we know int + int returns an int. The Dart code for
- * [int.operator+] only says it returns a [num].
- */
- TypeInformation handleIntrisifiedSelector(Selector selector,
- TypeGraphInferrerEngine inferrer) {
- if (!inferrer.compiler.backend.intImplementation.isResolved) return null;
- TypeMask intType = inferrer.compiler.typesTask.intType;
- if (selector.mask != intType) return null;
- if (!selector.isCall() && !selector.isOperator()) return null;
- if (!arguments.named.isEmpty) return null;
- if (arguments.positional.length > 1) return null;
-
- SourceString name = selector.name;
- if (name == const SourceString('*')
- || name == const SourceString('+')
- || name == const SourceString('%')
- || name == const SourceString('remainder')) {
- return hasOnePositionalArgumentWithType(intType)
- ? inferrer.types.intType
- : null;
- } else if (name == const SourceString('-')) {
- if (arguments.hasNoArguments()) return inferrer.types.intType;
- if (hasOnePositionalArgumentWithType(intType)) {
- return inferrer.types.intType;
- }
- return null;
- } else if (name == const SourceString('abs')) {
- return arguments.hasNoArguments() ? inferrer.types.intType : null;
- }
- return null;
- }
-
- TypeMask refine(TypeGraphInferrerEngine inferrer) {
- Iterable<Element> oldTargets = targets;
- Selector typedSelector = computeTypedSelector(inferrer);
- inferrer.updateSelectorInTree(caller, call, typedSelector);
- targets = inferrer.compiler.world.allFunctions.filter(typedSelector);
-
- // Walk over the found targets, and compute the joined union type mask
- // for all these targets.
- TypeMask newType = inferrer.types.computeTypeMask(targets.map((element) {
- if (!oldTargets.contains(element)) {
- ElementTypeInformation callee =
- inferrer.types.getInferredTypeOf(element);
- callee.addCall(caller, call);
- callee.addUser(this);
- inferrer.updateParameterAssignments(
- this, element, arguments, typedSelector, remove: false);
- }
-
- if (receiver.type.isContainer && selector.isIndex()) {
- // Find the [ElementInContainerTypeInformation] node and tell
- // that this node is a user of it. Later, when the element
- // type changes, this node will be notified.
- ContainerTypeMask mask = receiver.type;
- ContainerTypeInformation container =
- inferrer.types.allocatedContainers[mask.allocationNode];
- ElementInContainerTypeInformation element = container.elementType;
- if (!element.users.contains(element)) {
- element.addUser(this);
- }
- return element;
- } else {
- TypeInformation info =
- handleIntrisifiedSelector(typedSelector, inferrer);
- if (info != null) return info;
- return inferrer.typeOfElementWithSelector(element, typedSelector);
- }
- }));
-
- // Walk over the old targets, and remove calls that cannot happen
- // anymore.
- oldTargets.forEach((element) {
- if (!targets.contains(element)) {
- ElementTypeInformation callee =
- inferrer.types.getInferredTypeOf(element);
- callee.removeCall(caller, call);
- callee.removeUser(this);
- inferrer.updateParameterAssignments(
- this, element, arguments, typedSelector, remove: true);
- }
- });
- return newType;
- }
-
- void giveUp(TypeGraphInferrerEngine inferrer) {
- inferrer.updateSelectorInTree(caller, call, selector);
- Iterable<Element> oldTargets = targets;
- targets = inferrer.compiler.world.allFunctions.filter(selector);
- for (Element element in targets) {
- if (!oldTargets.contains(element)) {
- ElementTypeInformation callee =
- inferrer.types.getInferredTypeOf(element);
- callee.addCall(caller, call);
- inferrer.updateParameterAssignments(
- this, element, arguments, selector, remove: false);
- }
- }
- super.giveUp(inferrer);
- }
-}
-
-/**
- * A [ConcreteTypeInformation] represents a type that needed
- * to be materialized during the creation of the graph. For example,
- * literals, [:this:] or [:super:] need a [ConcreteTypeInformation].
- *
- * [ConcreteTypeInformation] nodes have no assignment. Also, to save
- * on memory, we do not add users to [ConcreteTypeInformation] nodes,
- * because we know such node will never be refined to a different
- * type.
- */
-class ConcreteTypeInformation extends TypeInformation {
- ConcreteTypeInformation(TypeMask type)
- : super(type, const <TypeInformation>[], const <TypeInformation>[]);
-
- bool get isConcrete => true;
-
- void addUser(TypeInformation user) {
- // Nothing to do, a concrete type does not get updated so never
- // needs to notify its users.
- }
-
- void removeUser(TypeInformation user) {
- }
-
- void addAssignment(TypeInformation assignment) {
- }
-
- void removeAssignment(TypeInformation assignment) {
- assert(false);
- }
-
- String toString() => 'Type $type';
-}
-
-/**
- * A [NarrowTypeInformation] narrows a [TypeInformation] to a type,
- * represented in [typeAnnotation].
- *
- * A [NarrowTypeInformation] node has only one assignment: the
- * [TypeInformation] it narrows.
- *
- * [NarrowTypeInformation] nodes are created for:
- *
- * - Code after `is` and `as` checks, where we have more information
- * on the type of the right hand side of the expression.
- *
- * - Code after a dynamic call, where we have more information on the
- * type of the receiver: it can only be of a class that holds a
- * potential target of this dynamic call.
- *
- * - In checked mode, after a type annotation, we have more
- * information on the type of a local.
- */
-class NarrowTypeInformation extends TypeInformation {
- final TypeMask typeAnnotation;
-
- NarrowTypeInformation(narrowedType,
- this.typeAnnotation,
- TypeMask type) : super(type) {
- addAssignment(narrowedType);
- }
-
- TypeMask refine(TypeGraphInferrerEngine inferrer) {
- return assignments[0].type.intersection(typeAnnotation, inferrer.compiler);
- }
-
- String toString() => 'Narrow ${assignments.first} to $typeAnnotation';
-}
-
-/**
- * A [ContainerTypeInformation] is a [ConcreteTypeInformation] created
- * for each `List` instantiations.
- */
-class ContainerTypeInformation extends ConcreteTypeInformation {
- final TypeInformation elementType;
-
- ContainerTypeInformation(containerType, this.elementType)
- : super(containerType);
-
- String toString() => 'Container type';
-}
-
-/**
- * An [ElementInContainerTypeInformation] holds the common type of the
- * elements in a [ContainerTypeInformation].
- */
-class ElementInContainerTypeInformation extends TypeInformation {
- final ContainerTypeMask container;
-
- ElementInContainerTypeInformation(elementType, this.container, type)
- : super(type) {
- // [elementType] is not null for const lists.
- if (elementType != null) addAssignment(elementType);
- }
-
- TypeMask refine(TypeGraphInferrerEngine inferrer) {
- if (assignments.isEmpty) return type;
- return container.elementType =
- inferrer.types.computeTypeMask(assignments);
- }
-
- String toString() => 'Element in container';
-}
-
-/**
- * A [PhiElementTypeInformation] is an union of
- * [ElementTypeInformation], that is local to a method.
- */
-class PhiElementTypeInformation extends TypeInformation {
- final Node branchNode;
- final bool isLoopPhi;
- final Element element;
-
- PhiElementTypeInformation(this.branchNode, this.isLoopPhi, this.element, type)
- : super(type);
-
- TypeMask refine(TypeGraphInferrerEngine inferrer) {
- return inferrer.types.computeTypeMask(assignments);
- }
-
- TypeMask refineOptimistic(TypeGraphInferrerEngine inferrer) {
- return isLoopPhi
- ? assignments[0].type
- : inferrer.types.computeTypeMask(assignments);
- }
-
- String toString() => 'Phi $element';
-}
-
-class TypeInformationSystem extends TypeSystem<TypeInformation> {
- final Compiler compiler;
-
- /// [ElementTypeInformation]s for elements.
- final Map<Element, TypeInformation> typeInformations =
- new Map<Element, TypeInformation>();
-
- /// [ContainerTypeInformation] for allocated containers.
- final Map<Node, TypeInformation> allocatedContainers =
- new Map<Node, TypeInformation>();
-
- /// Cache of [ConcreteTypeInformation].
- final Map<TypeMask, TypeInformation> concreteTypes =
- new Map<TypeMask, TypeInformation>();
-
- /// List of [TypeInformation]s allocated inside method bodies (calls,
- /// narrowing, phis, and containers).
- final List<TypeInformation> allocatedTypes = <TypeInformation>[];
-
- TypeInformationSystem(this.compiler) {
- nonNullEmptyType = getConcreteTypeFor(const TypeMask.nonNullEmpty());
- }
-
- TypeInformation nullTypeCache;
- TypeInformation get nullType {
- if (nullTypeCache != null) return nullTypeCache;
- return nullTypeCache = getConcreteTypeFor(compiler.typesTask.nullType);
- }
-
- TypeInformation intTypeCache;
- TypeInformation get intType {
- if (intTypeCache != null) return intTypeCache;
- return intTypeCache = getConcreteTypeFor(compiler.typesTask.intType);
- }
-
- TypeInformation doubleTypeCache;
- TypeInformation get doubleType {
- if (doubleTypeCache != null) return doubleTypeCache;
- return doubleTypeCache = getConcreteTypeFor(compiler.typesTask.doubleType);
- }
-
- TypeInformation numTypeCache;
- TypeInformation get numType {
- if (numTypeCache != null) return numTypeCache;
- return numTypeCache = getConcreteTypeFor(compiler.typesTask.numType);
- }
-
- TypeInformation boolTypeCache;
- TypeInformation get boolType {
- if (boolTypeCache != null) return boolTypeCache;
- return boolTypeCache = getConcreteTypeFor(compiler.typesTask.boolType);
- }
-
- TypeInformation functionTypeCache;
- TypeInformation get functionType {
- if (functionTypeCache != null) return functionTypeCache;
- return functionTypeCache =
- getConcreteTypeFor(compiler.typesTask.functionType);
- }
-
- TypeInformation listTypeCache;
- TypeInformation get listType {
- if (listTypeCache != null) return listTypeCache;
- return listTypeCache = getConcreteTypeFor(compiler.typesTask.listType);
- }
-
- TypeInformation constListTypeCache;
- TypeInformation get constListType {
- if (constListTypeCache != null) return constListTypeCache;
- return constListTypeCache =
- getConcreteTypeFor(compiler.typesTask.constListType);
- }
-
- TypeInformation fixedListTypeCache;
- TypeInformation get fixedListType {
- if (fixedListTypeCache != null) return fixedListTypeCache;
- return fixedListTypeCache =
- getConcreteTypeFor(compiler.typesTask.fixedListType);
- }
-
- TypeInformation growableListTypeCache;
- TypeInformation get growableListType {
- if (growableListTypeCache != null) return growableListTypeCache;
- return growableListTypeCache =
- getConcreteTypeFor(compiler.typesTask.growableListType);
- }
-
- TypeInformation mapTypeCache;
- TypeInformation get mapType {
- if (mapTypeCache != null) return mapTypeCache;
- return mapTypeCache = getConcreteTypeFor(compiler.typesTask.mapType);
- }
-
- TypeInformation constMapTypeCache;
- TypeInformation get constMapType {
- if (constMapTypeCache != null) return constMapTypeCache;
- return constMapTypeCache =
- getConcreteTypeFor(compiler.typesTask.constMapType);
- }
-
- TypeInformation stringTypeCache;
- TypeInformation get stringType {
- if (stringTypeCache != null) return stringTypeCache;
- return stringTypeCache = getConcreteTypeFor(compiler.typesTask.stringType);
- }
-
- TypeInformation typeTypeCache;
- TypeInformation get typeType {
- if (typeTypeCache != null) return typeTypeCache;
- return typeTypeCache = getConcreteTypeFor(compiler.typesTask.typeType);
- }
-
- TypeInformation dynamicTypeCache;
- TypeInformation get dynamicType {
- if (dynamicTypeCache != null) return dynamicTypeCache;
- return dynamicTypeCache =
- getConcreteTypeFor(compiler.typesTask.dynamicType);
- }
-
- TypeInformation nonNullEmptyType;
-
- TypeInformation computeLUB(TypeInformation firstType,
- TypeInformation secondType) {
- if (firstType == null) return secondType;
- if (firstType == secondType) return firstType;
- if (firstType == nonNullEmptyType) return secondType;
- if (secondType == nonNullEmptyType) return firstType;
- if (firstType == dynamicType || secondType == dynamicType) {
- return dynamicType;
- }
- return getConcreteTypeFor(
- firstType.type.union(secondType.type, compiler));
- }
-
- TypeInformation refineReceiver(Selector selector, TypeInformation receiver) {
- if (receiver.type.isExact) return receiver;
- TypeMask otherType = compiler.world.allFunctions.receiverType(selector);
- // If this is refining to nullable subtype of `Object` just return
- // the receiver. We know the narrowing is useless.
- if (otherType.isNullable && otherType.containsAll(compiler)) {
- return receiver;
- }
- TypeInformation newType =
- new NarrowTypeInformation(receiver, otherType, dynamicType.type);
- allocatedTypes.add(newType);
- return newType;
- }
-
- TypeInformation narrowType(TypeInformation type,
- DartType annotation,
- {bool isNullable: true}) {
- if (annotation.treatAsDynamic) return type;
- if (annotation.isVoid) return nullType;
- if (annotation.element == compiler.objectClass) return type;
- TypeMask otherType;
- if (annotation.kind == TypeKind.TYPEDEF
- || annotation.kind == TypeKind.FUNCTION) {
- otherType = functionType.type;
- } else if (annotation.kind == TypeKind.TYPE_VARIABLE) {
- // TODO(ngeoffray): Narrow to bound.
- return type;
- } else {
- assert(annotation.kind == TypeKind.INTERFACE);
- otherType = new TypeMask.nonNullSubtype(annotation);
- }
- if (isNullable) otherType = otherType.nullable();
- if (type.type.isExact) {
- return type;
- } else {
- TypeInformation newType =
- new NarrowTypeInformation(type, otherType, dynamicType.type);
- allocatedTypes.add(newType);
- return newType;
- }
- }
-
- ElementTypeInformation getInferredTypeOf(Element element) {
- element = element.implementation;
- return typeInformations.putIfAbsent(element, () {
- return new ElementTypeInformation(element, dynamicType.type);
- });
- }
-
- ConcreteTypeInformation getConcreteTypeFor(TypeMask mask) {
- return concreteTypes.putIfAbsent(mask, () {
- return new ConcreteTypeInformation(mask);
- });
- }
-
- TypeInformation nonNullSubtype(DartType type) {
- return getConcreteTypeFor(new TypeMask.nonNullSubtype(type));
- }
-
- TypeInformation nonNullSubclass(DartType type) {
- return getConcreteTypeFor(new TypeMask.nonNullSubclass(type));
- }
-
- TypeInformation nonNullExact(DartType type) {
- return getConcreteTypeFor(new TypeMask.nonNullExact(type));
- }
-
- TypeInformation nonNullEmpty() {
- return nonNullEmptyType;
- }
-
- TypeInformation allocateContainer(TypeInformation type,
- Node node,
- Element enclosing,
- [TypeInformation elementType, int length]) {
- ContainerTypeMask mask = new ContainerTypeMask(type.type, node, enclosing);
- mask.elementType = elementType == null ? null : elementType.type;
- mask.length = length;
- TypeMask elementTypeMask = elementType == null
- ? dynamicType.type
- : elementType.type;
- TypeInformation element = new ElementInContainerTypeInformation(
- elementType, mask, elementTypeMask);
- allocatedTypes.add(element);
- return allocatedContainers[node] =
- new ContainerTypeInformation(mask, element);
- }
-
- Selector newTypedSelector(TypeInformation info, Selector selector) {
- return new TypedSelector(info.type, selector);
- }
-
- TypeInformation allocateDiamondPhi(TypeInformation firstInput,
- TypeInformation secondInput) {
- PhiElementTypeInformation result =
- new PhiElementTypeInformation(null, false, null, dynamicType.type);
- result.addAssignment(firstInput);
- result.addAssignment(secondInput);
- allocatedTypes.add(result);
- return result;
- }
-
- PhiElementTypeInformation allocatePhi(Node node,
- Element element,
- inputType) {
- // Check if [inputType] is a phi for a local updated in
- // the try/catch block [node]. If it is, no need to allocate a new
- // phi.
- if (inputType is PhiElementTypeInformation
- && inputType.branchNode == node) {
- return inputType;
- }
- PhiElementTypeInformation result =
- new PhiElementTypeInformation(node, true, element, dynamicType.type);
- allocatedTypes.add(result);
- result.addAssignment(inputType);
- return result;
- }
-
- TypeInformation simplifyPhi(Node node,
- Element element,
- PhiElementTypeInformation phiType) {
- if (phiType.assignments.length == 1) return phiType.assignments.first;
- return phiType;
- }
-
- PhiElementTypeInformation addPhiInput(Element element,
- PhiElementTypeInformation phiType,
- TypeInformation newType) {
- phiType.addAssignment(newType);
- return phiType;
- }
-
- TypeMask computeTypeMask(Iterable<TypeInformation> assignments) {
- TypeMask newType = const TypeMask.nonNullEmpty();
- for (var info in assignments) {
- newType = newType.union(info.type, compiler);
- }
- return newType.containsAll(compiler) ? dynamicType.type : newType;
- }
-}
-
-/**
- * A work queue for the inferrer. It filters out nodes on
- * which we gave up on inferencing, as well as ensures through
- * [TypeInformation.inQueue] that a node is in the queue only once at
- * a time.
- */
-class WorkQueue {
- final Queue<TypeInformation> queue = new Queue<TypeInformation>();
-
- void add(TypeInformation element) {
- if (element.abandonInferencing) return;
- if (element.inQueue) return;
- queue.addLast(element);
- element.inQueue = true;
- }
-
- void addAll(Iterable<TypeInformation> all) {
- all.forEach(add);
- }
-
- TypeInformation remove() {
- TypeInformation element = queue.removeFirst();
- element.inQueue = false;
- return element;
- }
-
- bool get isEmpty => queue.isEmpty;
-
- int get length => queue.length;
-}
-
-/**
- * An inferencing engine that computes a call graph of
- * [TypeInformation] nodes by visiting the AST of the application, and
- * then does the inferencing on the graph.
- *
- * The inferencing is currently done in three steps:
- *
- * 1) Compute the call graph.
- * 2) Refine all nodes in a way that avoids cycles.
- * 3) Refine all nodes.
- *
- */
-class TypeGraphInferrerEngine
- extends InferrerEngine<TypeInformation, TypeInformationSystem> {
- final Map<Element, ConcreteTypeInformation> defaultTypeOfParameter =
- new Map<Element, ConcreteTypeInformation>();
- final WorkQueue workQueue = new WorkQueue();
-
- /// The maximum number of times we allow a node in the graph to
- /// change types. If a node reaches that limit, we give up
- /// inferencing on it and give it the dynamic type.
- final int MAX_CHANGE_COUNT = 5;
-
- int overallRefineCount = 0;
-
- TypeGraphInferrerEngine(Compiler compiler)
- : super(compiler, new TypeInformationSystem(compiler));
-
- void runOverAllElements() {
- if (compiler.disableTypeInference) return;
- int addedInGraph = 0;
- compiler.progress.reset();
-
- sortResolvedElements().forEach((Element element) {
- if (compiler.progress.elapsedMilliseconds > 500) {
- compiler.log('Added $addedInGraph elements in inferencing graph.');
- compiler.progress.reset();
- }
- SimpleTypeInferrerVisitor visitor =
- new SimpleTypeInferrerVisitor(element, compiler, this);
- TypeInformation type;
- compiler.withCurrentElement(element, () {
- type = visitor.run();
- });
- addedInGraph++;
-
- if (element.isField()) {
- Node node = element.parseNode(compiler);
- if (element.modifiers.isFinal() || element.modifiers.isConst()) {
- // If [element] is final and has an initializer, we record
- // the inferred type.
- if (node.asSendSet() != null) {
- recordType(element, type);
- } else if (!element.isInstanceMember()) {
- recordType(element, types.nullType);
- }
- } else if (node.asSendSet() == null) {
- // Only update types of static fields if there is no
- // assignment. Instance fields are dealt with in the constructor.
- if (Elements.isStaticOrTopLevelField(element)) {
- recordTypeOfNonFinalField(node, element, type, null);
- }
- } else {
- recordTypeOfNonFinalField(node, element, type, null);
- }
- if (Elements.isStaticOrTopLevelField(element)
- && node.asSendSet() != null
- && !element.modifiers.isConst()) {
- var argument = node.asSendSet().arguments.head;
- // TODO(13429): We could do better here by using the
- // constant handler to figure out if it's a lazy field or not.
- if (argument.asSend() != null
- || (argument.asNewExpression() != null && !argument.isConst())) {
- recordType(element, types.nullType);
- }
- }
- } else {
- recordReturnType(element, type);
- }
- });
- compiler.log('Added $addedInGraph elements in inferencing graph.');
-
- buildWorkQueue();
- refineOptimistic();
- buildWorkQueue();
- refine();
-
- compiler.log('Inferred $overallRefineCount types.');
-
- if (compiler.enableTypeAssertions) {
- // Undo the narrowing of parameters types. Parameters are being
- // checked by the method, and we can therefore only trust their
- // type after the checks. It is okay for the inferrer to rely on
- // the type annotations, but the backend should has to
- // insert the checks.
- types.typeInformations.forEach((Element element,
- ElementTypeInformation info) {
- if (element.isParameter() || element.isFieldParameter()) {
- if (info.abandonInferencing) {
- info.type = types.dynamicType.type;
- } else {
- info.type = types.computeTypeMask(info.assignments);
- }
- }
- });
- }
- }
-
-
- void refineOptimistic() {
- while (!workQueue.isEmpty) {
- if (compiler.progress.elapsedMilliseconds > 500) {
- compiler.log('Inferred $overallRefineCount types.');
- compiler.progress.reset();
- }
- TypeInformation info = workQueue.remove();
- TypeMask oldType = info.type;
- TypeMask newType = info.refineOptimistic(this);
- if ((info.type = newType) != oldType) {
- overallRefineCount++;
- workQueue.addAll(info.users);
- }
- }
- }
-
- void refine() {
- while (!workQueue.isEmpty) {
- if (compiler.progress.elapsedMilliseconds > 500) {
- compiler.log('Inferred $overallRefineCount types.');
- compiler.progress.reset();
- }
- TypeInformation info = workQueue.remove();
- TypeMask oldType = info.type;
- TypeMask newType = info.refine(this);
- if ((info.type = newType) != oldType) {
- overallRefineCount++;
- info.refineCount++;
- if (info.refineCount > MAX_CHANGE_COUNT) {
- info.giveUp(this);
- }
- workQueue.addAll(info.users);
- }
- }
- }
-
- void buildWorkQueue() {
- workQueue.addAll(types.typeInformations.values);
- workQueue.addAll(types.allocatedTypes);
- }
-
- /**
- * Update the assignments to parameters in the graph. [remove] tells
- * wheter assignments must be added or removed. If [init] is true,
- * parameters are added to the work queue.
- */
- void updateParameterAssignments(TypeInformation caller,
- Element callee,
- ArgumentsTypes arguments,
- Selector selector,
- {bool remove, bool init: false}) {
- if (callee.name == Compiler.NO_SUCH_METHOD) return;
- if (callee.isField()) {
- if (selector.isSetter()) {
- ElementTypeInformation info = types.getInferredTypeOf(callee);
- if (remove) {
- info.removeAssignment(arguments.positional[0]);
- } else {
- info.addAssignment(arguments.positional[0]);
- }
- if (!init) workQueue.add(info);
- }
- } else if (callee.isGetter()) {
- return;
- } else if (selector != null && selector.isGetter()) {
- if (!remove) {
- FunctionElement function = callee.implementation;
- FunctionSignature signature = function.computeSignature(compiler);
- signature.forEachParameter((Element parameter) {
- ElementTypeInformation info = types.getInferredTypeOf(parameter);
- info.giveUp(this);
- });
- }
- } else {
- FunctionElement function = callee.implementation;
- FunctionSignature signature = function.computeSignature(compiler);
- int parameterIndex = 0;
- bool visitingRequiredParameter = true;
- signature.forEachParameter((Element parameter) {
- if (parameter == signature.firstOptionalParameter) {
- visitingRequiredParameter = false;
- }
- TypeInformation type = visitingRequiredParameter
- ? arguments.positional[parameterIndex]
- : signature.optionalParametersAreNamed
- ? arguments.named[parameter.name]
- : parameterIndex < arguments.positional.length
- ? arguments.positional[parameterIndex]
- : null;
- if (type == null) type = getDefaultTypeOfParameter(parameter);
- TypeInformation info = types.getInferredTypeOf(parameter);
- if (remove) {
- info.removeAssignment(type);
- } else {
- info.addAssignment(type);
- }
- parameterIndex++;
- if (!init) workQueue.add(info);
- });
- }
- }
-
- void updateAllParametersOf(FunctionElement function) {}
- void onGenerativeConstructorAnalyzed(Element element) {}
-
- void setDefaultTypeOfParameter(Element parameter, TypeInformation type) {
- assert(parameter.enclosingElement.isImplementation);
- getDefaultTypeOfParameter(parameter).type = type.type;
- }
-
- TypeInformation getDefaultTypeOfParameter(Element parameter) {
- return defaultTypeOfParameter.putIfAbsent(parameter, () {
- return new ConcreteTypeInformation(types.dynamicType.type);
- });
- }
-
- TypeInformation typeOfElement(Element element) {
- if (element is FunctionElement) return types.functionType;
- return types.getInferredTypeOf(element);
- }
-
- TypeInformation returnTypeOfElement(Element element) {
- if (element is !FunctionElement) return types.dynamicType;
- return types.getInferredTypeOf(element);
- }
-
- void recordTypeOfFinalField(Spannable node,
- Element analyzed,
- Element element,
- TypeInformation type,
- CallSite constraint) {
- types.getInferredTypeOf(element).addAssignment(type);
- }
-
- void recordTypeOfNonFinalField(Spannable node,
- Element element,
- TypeInformation type,
- CallSite constraint) {
- types.getInferredTypeOf(element).addAssignment(type);
- }
-
- bool recordType(Element element, TypeInformation type) {
- types.getInferredTypeOf(element).addAssignment(type);
- return false;
- }
-
- void recordReturnType(Element element, TypeInformation type) {
- TypeInformation info = types.getInferredTypeOf(element);
- if (element.name == const SourceString('==')) {
- info.addAssignment(types.boolType);
- }
- // TODO(ngeoffray): Clean up. We do these checks because
- // [SimpleTypesInferrer] deals with two different inferrers.
- if (type == null) return;
- if (info.assignments.isEmpty) info.addAssignment(type);
- }
-
- TypeInformation addReturnTypeFor(Element element,
- TypeInformation unused,
- TypeInformation newType) {
- TypeInformation type = types.getInferredTypeOf(element);
- // TODO(ngeoffray): Clean up. We do this check because
- // [SimpleTypesInferrer] deals with two different inferrers.
- if (element.isGenerativeConstructor()) return type;
- type.addAssignment(newType);
- return type;
- }
-
- TypeInformation registerCalledElement(Spannable node,
- Selector selector,
- Element caller,
- Element callee,
- ArgumentsTypes arguments,
- CallSite constraint,
- SideEffects sideEffects,
- bool inLoop) {
- CallSiteTypeInformation info = new StaticCallSiteTypeInformation(
- node, caller, callee, selector, arguments, types.dynamicType.type);
- if (inLoop) {
- compiler.world.addFunctionCalledInLoop(callee);
- }
- info.addToGraph(this);
- updateSideEffects(sideEffects, selector, callee);
- return info;
- }
-
- TypeInformation registerCalledSelector(Node node,
- Selector selector,
- TypeInformation receiverType,
- Element caller,
- ArgumentsTypes arguments,
- CallSite constraint,
- SideEffects sideEffects,
- bool inLoop) {
- if (selector.isClosureCall()) return types.dynamicType;
-
- if (inLoop && selector.mask != null) {
- // For instance methods, we only register a selector called in a
- // loop if it is a typed selector, to avoid marking too many
- // methods as being called from within a loop. This cuts down
- // on the code bloat.
- // TODO(ngeoffray): We should move the filtering on the selector
- // in the backend. It is not the inferrer role to do this kind
- // of optimization.
- compiler.world.allFunctions.filter(selector).forEach((callee) {
- compiler.world.addFunctionCalledInLoop(callee);
- });
- }
- compiler.world.allFunctions.filter(selector).forEach((callee) {
- updateSideEffects(sideEffects, selector, callee);
- });
-
- DynamicCallSiteTypeInformation info = new DynamicCallSiteTypeInformation(
- node, caller, selector, receiverType, arguments,
- types.dynamicType.type);
- info.addToGraph(this);
- return info;
- }
-
- // Sorts the resolved elements by size. We do this for this inferrer
- // to get the same results for [ContainerTracer] compared to the
- // [SimpleTypesInferrer].
- Iterable<Element> sortResolvedElements() {
- int max = 0;
- Map<int, Set<Element>> methodSizes = new Map<int, Set<Element>>();
- compiler.enqueuer.resolution.resolvedElements.forEach(
- (Element element, TreeElementMapping mapping) {
- element = element.implementation;
- if (element.impliesType()) return;
- assert(invariant(element,
- element.isField() ||
- element.isFunction() ||
- element.isGenerativeConstructor() ||
- element.isGetter() ||
- element.isSetter(),
- message: 'Unexpected element kind: ${element.kind}'));
- // TODO(ngeoffray): Not sure why the resolver would put a null
- // mapping.
- if (mapping == null) return;
- if (element.isAbstract(compiler)) return;
- // Put the other operators in buckets by length, later to be added in
- // length order.
- int length = mapping.selectors.length;
- max = length > max ? length : max;
- Set<Element> set = methodSizes.putIfAbsent(
- length, () => new LinkedHashSet<Element>());
- set.add(element);
- });
-
- List<Element> result = <Element>[];
-
- for (int i = 0; i <= max; i++) {
- Set<Element> set = methodSizes[i];
- if (set != null) {
- result.addAll(set);
- }
- }
- return result;
- }
-
- void clear() {
- defaultTypeOfParameter.clear();
- types.typeInformations.values.forEach((info) => info.clear());
- types.allocatedTypes.clear();
- types.concreteTypes.clear();
- }
-
- Iterable<Element> getCallersOf(Element element) {
- if (compiler.disableTypeInference) {
- throw new UnsupportedError(
- "Cannot query the type inferrer when type inference is disabled.");
- }
- return types.getInferredTypeOf(element).callers.keys;
- }
-}
-
-class TypeGraphInferrer implements TypesInferrer {
- TypeGraphInferrerEngine inferrer;
- final Compiler compiler;
- TypeGraphInferrer(Compiler this.compiler);
-
- String get name => 'Graph inferrer';
-
- void analyzeMain(_) {
- inferrer = new TypeGraphInferrerEngine(compiler);
- inferrer.runOverAllElements();
- }
-
- TypeMask getReturnTypeOfElement(Element element) {
- if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
- return inferrer.types.getInferredTypeOf(element).type;
- }
-
- TypeMask getTypeOfElement(Element element) {
- if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
- return inferrer.types.getInferredTypeOf(element).type;
- }
-
- TypeMask getTypeOfNode(Element owner, Node node) {
- if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
- return inferrer.types.allocatedContainers[node].type;
- }
-
- TypeMask getTypeOfSelector(Selector selector) {
- if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
- // Bailout for closure calls. We're not tracking types of
- // closures.
- if (selector.isClosureCall()) return compiler.typesTask.dynamicType;
- if (selector.isSetter() || selector.isIndexSet()) {
- return compiler.typesTask.dynamicType;
- }
- if (selector.isIndex()
- && selector.mask != null
- && selector.mask.isContainer) {
- ContainerTypeMask mask = selector.mask;
- TypeMask elementType = mask.elementType;
- return elementType == null ? compiler.typesTask.dynamicType : elementType;
- }
-
- TypeMask result = const TypeMask.nonNullEmpty();
- Iterable<Element> elements = compiler.world.allFunctions.filter(selector);
- for (Element element in elements) {
- TypeMask type =
- inferrer.typeOfElementWithSelector(element, selector).type;
- result = result.union(type, compiler);
- }
- return result;
- }
-
- Iterable<TypeMask> get containerTypes {
- if (compiler.disableTypeInference) {
- throw new UnsupportedError(
- "Cannot query the type inferrer when type inference is disabled.");
- }
- return inferrer.types.allocatedContainers.values.map((info) => info.type);
- }
-
- Iterable<Element> getCallersOf(Element element) {
- if (compiler.disableTypeInference) {
- throw new UnsupportedError(
- "Cannot query the type inferrer when type inference is disabled.");
- }
- return inferrer.getCallersOf(element);
- }
-
- void clear() {
- inferrer.clear();
- }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 37f42d8..a809af3 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -50,7 +50,6 @@
bool get isUnion;
bool get isContainer;
bool get isForwarding;
- bool get isElement;
bool containsOnlyInt(Compiler compiler);
bool containsOnlyDouble(Compiler compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 6b7afbb..d4a83b98 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -5,16 +5,15 @@
library types;
import '../dart2jslib.dart' hide Selector, TypedSelector;
-import '../tree/tree.dart';
+import '../dart_types.dart';
import '../elements/elements.dart';
+import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
+import '../tree/tree.dart';
import '../util/util.dart';
import '../universe/universe.dart';
-import 'type_graph_inferrer.dart' show TypeGraphInferrer;
import 'concrete_types_inferrer.dart' show ConcreteTypesInferrer;
-import '../dart_types.dart';
part 'container_type_mask.dart';
-part 'element_type_mask.dart';
part 'flat_type_mask.dart';
part 'forwarding_type_mask.dart';
part 'type_mask.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
index fc294dd..6c40e56 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -199,7 +199,6 @@
bool get isUnion => true;
bool get isContainer => false;
bool get isForwarding => false;
- bool get isElement => false;
bool containsOnlyInt(Compiler compiler) => false;
bool containsOnlyDouble(Compiler compiler) => false;
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 4802139..1bcf514 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -167,24 +167,37 @@
assert(!name.isPrivate() || library != null);
}
+ static Map<int, List<Selector>> canonicalizedValues =
+ new Map<int, List<Selector>>();
+
factory Selector(SelectorKind kind,
SourceString name,
LibraryElement library,
int argumentCount,
[List<SourceString> namedArguments]) {
if (!name.isPrivate()) library = null;
- List<SourceString> orderedNamedArguments = const <SourceString>[];
- if (namedArguments == null) {
- namedArguments = const <SourceString>[];
- } else if (!namedArguments.isEmpty) {
- orderedNamedArguments = <SourceString>[];
- }
+ if (namedArguments == null) namedArguments = const <SourceString>[];
int hashCode = computeHashCode(
kind, name, library, argumentCount, namedArguments);
- return new Selector.internal(
+ List<Selector> list = canonicalizedValues.putIfAbsent(hashCode,
+ () => <Selector>[]);
+ for (int i = 0; i < list.length; i++) {
+ Selector existing = list[i];
+ if (existing.match(kind, name, library, argumentCount, namedArguments)) {
+ assert(existing.hashCode == hashCode);
+ assert(existing.mask == null);
+ return existing;
+ }
+ }
+ List<SourceString> orderedNamedArguments = namedArguments.isEmpty
+ ? const <SourceString>[]
+ : <SourceString>[];
+ Selector result = new Selector.internal(
kind, name, library, argumentCount,
namedArguments, orderedNamedArguments,
hashCode);
+ list.add(result);
+ return result;
}
factory Selector.fromElement(Element element, Compiler compiler) {
@@ -510,17 +523,17 @@
return true;
}
- bool operator ==(other) {
- if (other is !Selector) return false;
- if (identical(this, other)) return true;
- return hashCode == other.hashCode // Fast because it is cached.
- && kind == other.kind
- && name == other.name
- && mask == other.mask
- && identical(library, other.library)
- && argumentCount == other.argumentCount
- && namedArguments.length == other.namedArguments.length
- && sameNames(namedArguments, other.namedArguments);
+ bool match(SelectorKind kind,
+ SourceString name,
+ LibraryElement library,
+ int argumentCount,
+ List<SourceString> namedArguments) {
+ return this.kind == kind
+ && this.name == name
+ && identical(this.library, library)
+ && this.argumentCount == argumentCount
+ && this.namedArguments.length == namedArguments.length
+ && sameNames(this.namedArguments, namedArguments);
}
static int computeHashCode(SelectorKind kind,
@@ -610,10 +623,19 @@
assert(asUntyped.mask == null);
}
+ static Map<Selector, Map<TypeMask, TypedSelector>> canonicalizedValues =
+ new Map<Selector, Map<TypeMask, TypedSelector>>();
+
factory TypedSelector(TypeMask mask, Selector selector) {
Selector untyped = selector.asUntyped;
- int hashCode = Selector.mixHashCodeBits(untyped.hashCode, mask.hashCode);
- return new TypedSelector.internal(mask, untyped, hashCode);
+ Map<TypeMask, TypedSelector> map = canonicalizedValues.putIfAbsent(untyped,
+ () => new Map<TypeMask, TypedSelector>());
+ TypedSelector result = map[mask];
+ if (result == null) {
+ int hashCode = Selector.mixHashCodeBits(untyped.hashCode, mask.hashCode);
+ result = map[mask] = new TypedSelector.internal(mask, untyped, hashCode);
+ }
+ return result;
}
factory TypedSelector.exact(DartType base, Selector selector)
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 23ec164..b44e3ec 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -93,85 +93,85 @@
static const DualKind NOT_ASSIGNABLE = const DualKind(
error: const MessageKind(
- 'Error: "#{fromType}" is not assignable to "#{toType}".'),
+ "Error: '#{fromType}' is not assignable to '#{toType}'."),
warning: const MessageKind(
- 'Warning: "#{fromType}" is not assignable to "#{toType}".'));
+ "Warning: '#{fromType}' is not assignable to '#{toType}'."));
static const MessageKind VOID_EXPRESSION = const MessageKind(
- 'Warning: Expression does not yield a value.');
+ "Warning: Expression does not yield a value.");
static const MessageKind VOID_VARIABLE = const MessageKind(
- 'Warning: Variable cannot be of type void.');
+ "Warning: Variable cannot be of type void.");
static const MessageKind RETURN_VALUE_IN_VOID = const MessageKind(
- 'Warning: Cannot return value from void function.');
+ "Warning: Cannot return value from void function.");
static const MessageKind RETURN_NOTHING = const MessageKind(
- 'Warning: Value of type "#{returnType}" expected.');
+ "Warning: Value of type '#{returnType}' expected.");
static const MessageKind MISSING_ARGUMENT = const MessageKind(
- 'Warning: Missing argument of type "#{argumentType}".');
+ "Warning: Missing argument of type '#{argumentType}'.");
static const MessageKind ADDITIONAL_ARGUMENT = const MessageKind(
- 'Warning: Additional argument.');
+ "Warning: Additional argument.");
static const MessageKind NAMED_ARGUMENT_NOT_FOUND = const MessageKind(
- 'Warning: No named argument "#{argumentName}" found on method.');
+ "Warning: No named argument '#{argumentName}' found on method.");
static const DualKind MEMBER_NOT_FOUND = const DualKind(
error: const MessageKind(
- 'Error: No member named "#{memberName}" in class "#{className}".'),
+ "Error: No member named '#{memberName}' in class '#{className}'."),
warning: const MessageKind(
- 'Warning: No member named "#{memberName}" in class "#{className}".'));
+ "Warning: No member named '#{memberName}' in class '#{className}'."));
static const MessageKind METHOD_NOT_FOUND = const MessageKind(
- 'Warning: No method named "#{memberName}" in class "#{className}".');
+ "Warning: No method named '#{memberName}' in class '#{className}'.");
static const MessageKind OPERATOR_NOT_FOUND = const MessageKind(
- 'Warning: No operator "#{memberName}" in class "#{className}".');
+ "Warning: No operator '#{memberName}' in class '#{className}'.");
static const MessageKind PROPERTY_NOT_FOUND = const MessageKind(
- 'Warning: No property named "#{memberName}" in class "#{className}".');
+ "Warning: No property named '#{memberName}' in class '#{className}'.");
static const MessageKind NOT_CALLABLE = const MessageKind(
- 'Warning: "#{elementName}" is not callable.');
+ "Warning: '#{elementName}' is not callable.");
static const DualKind MEMBER_NOT_STATIC = const DualKind(
error: const MessageKind(
- 'Error: "#{className}.#{memberName}" is not static.'),
+ "Error: '#{className}.#{memberName}' is not static."),
warning: const MessageKind(
- 'Warning: "#{className}.#{memberName}" is not static.'));
+ "Warning: '#{className}.#{memberName}' is not static."));
static const MessageKind NO_INSTANCE_AVAILABLE = const MessageKind(
- 'Error: "#{name}" is only available in instance methods.');
+ "Error: '#{name}' is only available in instance methods.");
static const MessageKind PRIVATE_ACCESS = const MessageKind(
- 'Warning: "#{name}" is declared private within library '
- '"#{libraryName}".');
+ "Warning: '#{name}' is declared private within library "
+ "'#{libraryName}'.");
static const MessageKind THIS_IS_THE_METHOD = const MessageKind(
- 'Info: This is the method declaration.');
+ "Info: This is the method declaration.");
static const MessageKind UNREACHABLE_CODE = const MessageKind(
- 'Warning: Unreachable code.');
+ "Warning: Unreachable code.");
static const MessageKind MISSING_RETURN = const MessageKind(
- 'Warning: Missing return.');
+ "Warning: Missing return.");
static const MessageKind MAYBE_MISSING_RETURN = const MessageKind(
- 'Warning: Not all paths lead to a return or throw statement.');
+ "Warning: Not all paths lead to a return or throw statement.");
static const DualKind CANNOT_RESOLVE = const DualKind(
- error: const MessageKind('Error: Cannot resolve "#{name}".'),
- warning: const MessageKind('Warning: Cannot resolve "#{name}".'));
+ error: const MessageKind("Error: Cannot resolve '#{name}'."),
+ warning: const MessageKind("Warning: Cannot resolve '#{name}'."));
static const MessageKind CANNOT_RESOLVE_CONSTRUCTOR = const MessageKind(
- 'Error: Cannot resolve constructor "#{constructorName}".');
+ "Error: Cannot resolve constructor '#{constructorName}'.");
static const MessageKind CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT =
- const MessageKind('Error: cannot resolve constructor "#{constructorName}"'
- ' for implicit super call.',
- howToFix: 'Try explicitly invoking a constructor of the super class',
+ const MessageKind("Error: cannot resolve constructor '#{constructorName}'"
+ " for implicit super call.",
+ howToFix: "Try explicitly invoking a constructor of the super class",
examples: const ["""
class A {
A.foo() {}
@@ -183,28 +183,28 @@
"""]);
static const MessageKind INVALID_UNNAMED_CONSTRUCTOR_NAME = const MessageKind(
- 'Error: Unnamed constructor name must be "#{name}".');
+ "Error: Unnamed constructor name must be '#{name}'.");
static const MessageKind INVALID_CONSTRUCTOR_NAME = const MessageKind(
- 'Error: Constructor name must start with "#{name}".');
+ "Error: Constructor name must start with '#{name}'.");
static const DualKind CANNOT_RESOLVE_TYPE = const DualKind(
- error: const MessageKind('Error: Cannot resolve type "#{typeName}".'),
+ error: const MessageKind("Error: Cannot resolve type '#{typeName}'."),
warning: const MessageKind(
- 'Warning: Cannot resolve type "#{typeName}".'));
+ "Warning: Cannot resolve type '#{typeName}'."));
static const MessageKind DUPLICATE_DEFINITION = const MessageKind(
- 'Error: Duplicate definition of "#{name}".');
+ "Error: Duplicate definition of '#{name}'.");
static const MessageKind EXISTING_DEFINITION = const MessageKind(
- 'Info: Existing definition of "#{name}".');
+ "Info: Existing definition of '#{name}'.");
static const DualKind DUPLICATE_IMPORT = const DualKind(
- error: const MessageKind('Error: Duplicate import of "#{name}".'),
- warning: const MessageKind('Warning: Duplicate import of "#{name}".'));
+ error: const MessageKind("Error: Duplicate import of '#{name}'."),
+ warning: const MessageKind("Warning: Duplicate import of '#{name}'."));
static const MessageKind HIDDEN_IMPORT = const MessageKind(
- "Warning: '#{name}' from library '#{hiddenUri}' by '#{name}' "
+ "Warning: '#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
"from library '#{hidingUri}'.",
howToFix: "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
examples: const [
@@ -256,60 +256,81 @@
export 'future.dart';"""}]);
+
+ static const MessageKind HIDDEN_IMPLICIT_IMPORT = const MessageKind(
+ "Warning: '#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+ "from library '#{hidingUri}'.",
+ howToFix: "Try adding an explicit "
+ "'import \"#{hiddenUri}\" hide #{name}'.",
+ examples: const [
+ const {
+'main.dart':
+"""
+// This hides the implicit import of class Type from dart:core.
+import 'type.dart';
+
+void main() {}""",
+
+'type.dart':
+"""
+library type;
+
+class Type {}"""}]);
+
static const MessageKind DUPLICATE_EXPORT = const MessageKind(
- 'Error: Duplicate export of "#{name}".');
+ "Error: Duplicate export of '#{name}'.");
static const DualKind NOT_A_TYPE = const DualKind(
- error: const MessageKind('Error: "#{node}" is not a type.'),
- warning: const MessageKind('Warning: "#{node}" is not a type.'));
+ error: const MessageKind("Error: '#{node}' is not a type."),
+ warning: const MessageKind("Warning: '#{node}' is not a type."));
static const MessageKind NOT_A_PREFIX = const MessageKind(
- 'Error: "#{node}" is not a prefix.');
+ "Error: '#{node}' is not a prefix.");
static const DualKind CANNOT_FIND_CONSTRUCTOR = const DualKind(
error: const MessageKind(
- 'Error: Cannot find constructor "#{constructorName}".'),
+ "Error: Cannot find constructor '#{constructorName}'."),
warning: const MessageKind(
- 'Warning: Cannot find constructor "#{constructorName}".'));
+ "Warning: Cannot find constructor '#{constructorName}'."));
static const MessageKind CYCLIC_CLASS_HIERARCHY = const MessageKind(
- 'Error: "#{className}" creates a cycle in the class hierarchy.');
+ "Error: '#{className}' creates a cycle in the class hierarchy.");
static const MessageKind CYCLIC_REDIRECTING_FACTORY = const MessageKind(
'Error: Redirecting factory leads to a cyclic redirection.');
static const MessageKind INVALID_RECEIVER_IN_INITIALIZER = const MessageKind(
- 'Error: Field initializer expected.');
+ "Error: Field initializer expected.");
static const MessageKind NO_SUPER_IN_STATIC = const MessageKind(
- 'Error: "super" is only available in instance methods.');
+ "Error: 'super' is only available in instance methods.");
static const MessageKind DUPLICATE_INITIALIZER = const MessageKind(
- 'Error: Field "#{fieldName}" is initialized more than once.');
+ "Error: Field '#{fieldName}' is initialized more than once.");
static const MessageKind ALREADY_INITIALIZED = const MessageKind(
- 'Info: "#{fieldName}" was already initialized here.');
+ "Info: '#{fieldName}' was already initialized here.");
static const MessageKind INIT_STATIC_FIELD = const MessageKind(
- 'Error: Cannot initialize static field "#{fieldName}".');
+ "Error: Cannot initialize static field '#{fieldName}'.");
static const MessageKind NOT_A_FIELD = const MessageKind(
- 'Error: "#{fieldName}" is not a field.');
+ "Error: '#{fieldName}' is not a field.");
static const MessageKind CONSTRUCTOR_CALL_EXPECTED = const MessageKind(
- 'Error: only call to "this" or "super" constructor allowed.');
+ "Error: only call to 'this' or 'super' constructor allowed.");
static const MessageKind INVALID_FOR_IN = const MessageKind(
- 'Error: Invalid for-in variable declaration.');
+ "Error: Invalid for-in variable declaration.");
static const MessageKind INVALID_INITIALIZER = const MessageKind(
- 'Error: Invalid initializer.');
+ "Error: Invalid initializer.");
static const MessageKind FUNCTION_WITH_INITIALIZER = const MessageKind(
- 'Error: Only constructors can have initializers.');
+ "Error: Only constructors can have initializers.");
static const MessageKind REDIRECTING_CONSTRUCTOR_CYCLE = const MessageKind(
- 'Error: Cyclic constructor redirection.');
+ "Error: Cyclic constructor redirection.");
static const MessageKind REDIRECTING_CONSTRUCTOR_HAS_BODY = const MessageKind(
"Error: Redirecting constructor can't have a body.");
@@ -326,32 +347,32 @@
static const MessageKind REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER =
const MessageKind(
- 'Error: Redirecting constructor cannot have other initializers.');
+ "Error: Redirecting constructor cannot have other initializers.");
static const MessageKind SUPER_INITIALIZER_IN_OBJECT = const MessageKind(
- 'Error: "Object" cannot have a super initializer.');
+ "Error: 'Object' cannot have a super initializer.");
static const MessageKind DUPLICATE_SUPER_INITIALIZER = const MessageKind(
- 'Error: Cannot have more than one super initializer.');
+ "Error: Cannot have more than one super initializer.");
static const DualKind INVALID_ARGUMENTS = const DualKind(
error: const MessageKind(
- 'Error: Arguments do not match the expected parameters of '
- '"#{methodName}".'),
+ "Error: Arguments do not match the expected parameters of "
+ "'#{methodName}'."),
warning: const MessageKind(
- 'Warning: Arguments do not match the expected parameters of '
- '"#{methodName}".'));
+ "Warning: Arguments do not match the expected parameters of "
+ "'#{methodName}'."));
static const MessageKind NO_MATCHING_CONSTRUCTOR = const MessageKind(
- 'Error: "super" call arguments and constructor parameters do not match.');
+ "Error: 'super' call arguments and constructor parameters do not match.");
static const MessageKind NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT =
const MessageKind(
- 'Error: Implicit "super" call arguments and constructor parameters '
- 'do not match.');
+ "Error: Implicit 'super' call arguments and constructor parameters "
+ "do not match.");
static const MessageKind CONST_CALLS_NON_CONST = const MessageKind(
- 'Error: "const" constructor cannot call a non-const constructor.');
+ "Error: 'const' constructor cannot call a non-const constructor.");
static const MessageKind CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS =
const MessageKind(
@@ -368,86 +389,86 @@
main() => new C(0);"""]);
static const MessageKind CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD =
- const MessageKind('Info: This non-final field prevents using const '
- 'constructors.');
+ const MessageKind("Info: This non-final field prevents using const "
+ "constructors.");
static const MessageKind CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR =
- const MessageKind('Info: This const constructor is not allowed due to '
- 'non-final fields.');
+ const MessageKind("Info: This const constructor is not allowed due to "
+ "non-final fields.");
static const MessageKind INITIALIZING_FORMAL_NOT_ALLOWED = const MessageKind(
- 'Error: Initializing formal parameter only allowed in generative '
- 'constructor.');
+ "Error: Initializing formal parameter only allowed in generative "
+ "constructor.");
static const MessageKind INVALID_PARAMETER = const MessageKind(
- 'Error: Cannot resolve parameter.');
+ "Error: Cannot resolve parameter.");
static const MessageKind NOT_INSTANCE_FIELD = const MessageKind(
- 'Error: "#{fieldName}" is not an instance field.');
+ "Error: '#{fieldName}' is not an instance field.");
static const MessageKind NO_CATCH_NOR_FINALLY = const MessageKind(
- 'Error: Expected "catch" or "finally".');
+ "Error: Expected 'catch' or 'finally'.");
static const MessageKind EMPTY_CATCH_DECLARATION = const MessageKind(
- 'Error: Expected an identifier in catch declaration.');
+ "Error: Expected an identifier in catch declaration.");
static const MessageKind EXTRA_CATCH_DECLARATION = const MessageKind(
- 'Error: Extra parameter in catch declaration.');
+ "Error: Extra parameter in catch declaration.");
static const MessageKind PARAMETER_WITH_TYPE_IN_CATCH = const MessageKind(
- 'Error: Cannot use type annotations in catch.');
+ "Error: Cannot use type annotations in catch.");
static const MessageKind PARAMETER_WITH_MODIFIER_IN_CATCH = const MessageKind(
- 'Error: Cannot use modifiers in catch.');
+ "Error: Cannot use modifiers in catch.");
static const MessageKind OPTIONAL_PARAMETER_IN_CATCH = const MessageKind(
- 'Error: Cannot use optional parameters in catch.');
+ "Error: Cannot use optional parameters in catch.");
static const MessageKind THROW_WITHOUT_EXPRESSION = const MessageKind(
- 'Error: Cannot use re-throw outside of catch block '
- '(expression expected after "throw").');
+ "Error: Cannot use re-throw outside of catch block "
+ "(expression expected after 'throw').");
static const MessageKind UNBOUND_LABEL = const MessageKind(
- 'Error: Cannot resolve label "#{labelName}".');
+ "Error: Cannot resolve label '#{labelName}'.");
static const MessageKind NO_BREAK_TARGET = const MessageKind(
- 'Error: "break" statement not inside switch or loop.');
+ "Error: 'break' statement not inside switch or loop.");
static const MessageKind NO_CONTINUE_TARGET = const MessageKind(
- 'Error: "continue" statement not inside loop.');
+ "Error: 'continue' statement not inside loop.");
static const MessageKind EXISTING_LABEL = const MessageKind(
- 'Info: Original declaration of duplicate label "#{labelName}".');
+ "Info: Original declaration of duplicate label '#{labelName}'.");
static const DualKind DUPLICATE_LABEL = const DualKind(
error: const MessageKind(
- 'Error: Duplicate declaration of label "#{labelName}".'),
+ "Error: Duplicate declaration of label '#{labelName}'."),
warning: const MessageKind(
- 'Warning: Duplicate declaration of label "#{labelName}".'));
+ "Warning: Duplicate declaration of label '#{labelName}'."));
static const MessageKind UNUSED_LABEL = const MessageKind(
- 'Warning: Unused label "#{labelName}".');
+ "Warning: Unused label '#{labelName}'.");
static const MessageKind INVALID_CONTINUE = const MessageKind(
- 'Error: Target of continue is not a loop or switch case.');
+ "Error: Target of continue is not a loop or switch case.");
static const MessageKind INVALID_BREAK = const MessageKind(
- 'Error: Target of break is not a statement.');
+ "Error: Target of break is not a statement.");
static const MessageKind DUPLICATE_TYPE_VARIABLE_NAME = const MessageKind(
- 'Error: Type variable "#{typeVariableName}" already declared.');
+ "Error: Type variable '#{typeVariableName}' already declared.");
static const DualKind TYPE_VARIABLE_WITHIN_STATIC_MEMBER = const DualKind(
error: const MessageKind(
- 'Error: Cannot refer to type variable "#{typeVariableName}" '
- 'within a static member.'),
+ "Error: Cannot refer to type variable '#{typeVariableName}' "
+ "within a static member."),
warning: const MessageKind(
- 'Warning: Cannot refer to type variable "#{typeVariableName}" '
- 'within a static member.'));
+ "Warning: Cannot refer to type variable '#{typeVariableName}' "
+ "within a static member."));
static const MessageKind TYPE_VARIABLE_IN_CONSTANT = const MessageKind(
- 'Error: Cannot refer to type variable in constant.');
+ "Error: Cannot refer to type variable in constant.");
static const MessageKind INVALID_TYPE_VARIABLE_BOUND = const MessageKind(
"Warning: '#{typeArgument}' is not a subtype of bound '#{bound}' for "
@@ -461,44 +482,44 @@
"""]);
static const MessageKind INVALID_USE_OF_SUPER = const MessageKind(
- 'Error: "super" not allowed here.');
+ "Error: 'super' not allowed here.");
static const MessageKind INVALID_CASE_DEFAULT = const MessageKind(
- 'Error: "default" only allowed on last case of a switch.');
+ "Error: 'default' only allowed on last case of a switch.");
static const MessageKind SWITCH_CASE_TYPES_NOT_EQUAL = const MessageKind(
- 'Error: "case" expressions do not all have type "#{type}".');
+ "Error: 'case' expressions do not all have type '#{type}'.");
static const MessageKind SWITCH_CASE_TYPES_NOT_EQUAL_CASE = const MessageKind(
- 'Info: "case" expression of type "#{type}".');
+ "Info: 'case' expression of type '#{type}'.");
static const MessageKind SWITCH_CASE_VALUE_OVERRIDES_EQUALS =
const MessageKind(
- 'Error: "case" expression value overrides "operator==".');
+ "Error: 'case' expression value overrides 'operator=='.");
static const MessageKind INVALID_ARGUMENT_AFTER_NAMED = const MessageKind(
- 'Error: Unnamed argument after named argument.');
+ "Error: Unnamed argument after named argument.");
static const MessageKind NOT_A_COMPILE_TIME_CONSTANT = const MessageKind(
- 'Error: Not a compile-time constant.');
+ "Error: Not a compile-time constant.");
static const MessageKind CYCLIC_COMPILE_TIME_CONSTANTS = const MessageKind(
- 'Error: Cycle in the compile-time constant computation.');
+ "Error: Cycle in the compile-time constant computation.");
static const MessageKind CONSTRUCTOR_IS_NOT_CONST = const MessageKind(
- 'Error: Constructor is not a "const" constructor.');
+ "Error: Constructor is not a 'const' constructor.");
static const MessageKind KEY_NOT_A_STRING_LITERAL = const MessageKind(
- 'Error: Map-literal key not a string literal.');
+ "Error: Map-literal key not a string literal.");
static const DualKind NO_SUCH_LIBRARY_MEMBER = const DualKind(
error: const MessageKind(
- 'Error: "#{libraryName}" has no member named "#{memberName}".'),
+ "Error: '#{libraryName}' has no member named '#{memberName}'."),
warning: const MessageKind(
- 'Warning: "#{libraryName}" has no member named "#{memberName}".'));
+ "Warning: '#{libraryName}' has no member named '#{memberName}'."));
static const MessageKind CANNOT_INSTANTIATE_TYPEDEF = const MessageKind(
- 'Error: Cannot instantiate typedef "#{typedefName}".');
+ "Error: Cannot instantiate typedef '#{typedefName}'.");
static const MessageKind REQUIRED_PARAMETER_WITH_DEFAULT = const MessageKind(
"Error: Non-optional parameters can't have a default value.",
@@ -564,11 +585,25 @@
main() => foo(42);
"""]);
+ static const MessageKind FORMAL_DECLARED_STATIC = const MessageKind(
+ "Error: A formal parameter can't be declared static.",
+ howToFix: "Try removing 'static'.",
+ examples: const ["""
+foo(static x) {}
+main() => foo(42);
+""", """
+foo({static x}) {}
+main() => foo(42);
+""", """
+foo([static x]) {}
+main() => foo(42);
+"""]);
+
static const MessageKind CANNOT_INSTANTIATE_TYPE_VARIABLE = const MessageKind(
- 'Error: Cannot instantiate type variable "#{typeVariableName}".');
+ "Error: Cannot instantiate type variable '#{typeVariableName}'.");
static const MessageKind CYCLIC_TYPE_VARIABLE = const MessageKind(
- 'Warning: Type variable "#{typeVariableName}" is a supertype of itself.');
+ "Warning: Type variable '#{typeVariableName}' is a supertype of itself.");
static const CYCLIC_TYPEDEF = const MessageKind(
"Error: A typedef can't refer to itself.",
@@ -597,113 +632,113 @@
"supported on typedefs.");
static const MessageKind CLASS_NAME_EXPECTED = const MessageKind(
- 'Error: Class name expected.');
+ "Error: Class name expected.");
static const MessageKind CANNOT_EXTEND = const MessageKind(
- 'Error: "#{type}" cannot be extended.');
+ "Error: '#{type}' cannot be extended.");
static const MessageKind CANNOT_IMPLEMENT = const MessageKind(
- 'Error: "#{type}" cannot be implemented.');
+ "Error: '#{type}' cannot be implemented.");
static const MessageKind DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
- 'Error: "#{type}" can not be both extended and implemented.');
+ "Error: '#{type}' can not be both extended and implemented.");
static const MessageKind DUPLICATE_IMPLEMENTS = const MessageKind(
- 'Error: "#{type}" must not occur more than once '
- 'in the implements clause.');
+ "Error: '#{type}' must not occur more than once "
+ "in the implements clause.");
static const MessageKind ILLEGAL_SUPER_SEND = const MessageKind(
- 'Error: "#{name}" cannot be called on super.');
+ "Error: '#{name}' cannot be called on super.");
static const DualKind NO_SUCH_SUPER_MEMBER = const DualKind(
error: const MessageKind(
- 'Error: Cannot resolve "#{memberName}" in a superclass of '
- '"#{className}".'),
+ "Error: Cannot resolve '#{memberName}' in a superclass of "
+ "'#{className}'."),
warning: const MessageKind(
- 'Warning: Cannot resolve "#{memberName}" in a superclass of '
- '"#{className}".'));
+ "Warning: Cannot resolve '#{memberName}' in a superclass of "
+ "'#{className}'."));
static const DualKind ADDITIONAL_TYPE_ARGUMENT = const DualKind(
- error: const MessageKind('Error: Additional type argument.'),
- warning: const MessageKind('Warning: Additional type argument.'));
+ error: const MessageKind("Error: Additional type argument."),
+ warning: const MessageKind("Warning: Additional type argument."));
static const DualKind MISSING_TYPE_ARGUMENT = const DualKind(
- error: const MessageKind('Error: Missing type argument.'),
- warning: const MessageKind('Warning: Missing type argument.'));
+ error: const MessageKind("Error: Missing type argument."),
+ warning: const MessageKind("Warning: Missing type argument."));
// TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or MISSING_TYPE_ARGUMENT
// instead.
static const MessageKind TYPE_ARGUMENT_COUNT_MISMATCH = const MessageKind(
- 'Error: Incorrect number of type arguments on "#{type}".');
+ "Error: Incorrect number of type arguments on '#{type}'.");
static const MessageKind GETTER_MISMATCH = const MessageKind(
- 'Error: Setter disagrees on: "#{modifiers}".');
+ "Error: Setter disagrees on: '#{modifiers}'.");
static const MessageKind SETTER_MISMATCH = const MessageKind(
- 'Error: Getter disagrees on: "#{modifiers}".');
+ "Error: Getter disagrees on: '#{modifiers}'.");
static const MessageKind ILLEGAL_SETTER_FORMALS = const MessageKind(
- 'Error: A setter must have exactly one argument.');
+ "Error: A setter must have exactly one argument.");
static const MessageKind NO_STATIC_OVERRIDE = const MessageKind(
- 'Error: Static member cannot override instance member "#{memberName}" of '
- '"#{className}".');
+ "Error: Static member cannot override instance member '#{memberName}' of "
+ "'#{className}'.");
static const MessageKind NO_STATIC_OVERRIDE_CONT = const MessageKind(
- 'Info: This is the instance member that cannot be overridden '
- 'by a static member.');
+ "Info: This is the instance member that cannot be overridden "
+ "by a static member.");
static const MessageKind CANNOT_OVERRIDE_FIELD_WITH_METHOD =
const MessageKind(
- 'Error: Method cannot override field "#{memberName}" of '
- '"#{className}".');
+ "Error: Method cannot override field '#{memberName}' of "
+ "'#{className}'.");
static const MessageKind CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT =
const MessageKind(
- 'Info: This is the field that cannot be overridden by a method.');
+ "Info: This is the field that cannot be overridden by a method.");
static const MessageKind CANNOT_OVERRIDE_METHOD_WITH_FIELD =
const MessageKind(
- 'Error: Field cannot override method "#{memberName}" of '
- '"#{className}".');
+ "Error: Field cannot override method '#{memberName}' of "
+ "'#{className}'.");
static const MessageKind CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT =
const MessageKind(
- 'Info: This is the method that cannot be overridden by a field.');
+ "Info: This is the method that cannot be overridden by a field.");
static const MessageKind BAD_ARITY_OVERRIDE = const MessageKind(
- 'Error: Cannot override method "#{memberName}" in "#{className}"; '
- 'the parameters do not match.');
+ "Error: Cannot override method '#{memberName}' in '#{className}'; "
+ "the parameters do not match.");
static const MessageKind BAD_ARITY_OVERRIDE_CONT = const MessageKind(
- 'Info: This is the method whose parameters do not match.');
+ "Info: This is the method whose parameters do not match.");
static const MessageKind MISSING_FORMALS = const MessageKind(
- 'Error: Formal parameters are missing.');
+ "Error: Formal parameters are missing.");
static const MessageKind EXTRA_FORMALS = const MessageKind(
- 'Error: Formal parameters are not allowed here.');
+ "Error: Formal parameters are not allowed here.");
static const MessageKind UNARY_OPERATOR_BAD_ARITY = const MessageKind(
- 'Error: Operator "#{operatorName}" must have no parameters.');
+ "Error: Operator '#{operatorName}' must have no parameters.");
static const MessageKind MINUS_OPERATOR_BAD_ARITY = const MessageKind(
- 'Error: Operator "-" must have 0 or 1 parameters.');
+ "Error: Operator '-' must have 0 or 1 parameters.");
static const MessageKind BINARY_OPERATOR_BAD_ARITY = const MessageKind(
- 'Error: Operator "#{operatorName}" must have exactly 1 parameter.');
+ "Error: Operator '#{operatorName}' must have exactly 1 parameter.");
static const MessageKind TERNARY_OPERATOR_BAD_ARITY = const MessageKind(
- 'Error: Operator "#{operatorName}" must have exactly 2 parameters.');
+ "Error: Operator '#{operatorName}' must have exactly 2 parameters.");
static const MessageKind OPERATOR_OPTIONAL_PARAMETERS = const MessageKind(
- 'Error: Operator "#{operatorName}" cannot have optional parameters.');
+ "Error: Operator '#{operatorName}' cannot have optional parameters.");
static const MessageKind OPERATOR_NAMED_PARAMETERS = const MessageKind(
- 'Error: Operator "#{operatorName}" cannot have named parameters.');
+ "Error: Operator '#{operatorName}' cannot have named parameters.");
static const MessageKind CONSTRUCTOR_WITH_RETURN_TYPE = const MessageKind(
- 'Error: Cannot have return type for constructor.');
+ "Error: Cannot have return type for constructor.");
static const MessageKind CANNOT_RETURN_FROM_CONSTRUCTOR = const MessageKind(
"Error: Constructors can't return values.",
@@ -718,45 +753,45 @@
main() => new C();"""]);
static const MessageKind ILLEGAL_FINAL_METHOD_MODIFIER = const MessageKind(
- 'Error: Cannot have final modifier on method.');
+ "Error: Cannot have final modifier on method.");
static const MessageKind ILLEGAL_CONSTRUCTOR_MODIFIERS = const MessageKind(
- 'Error: Illegal constructor modifiers: "#{modifiers}".');
+ "Error: Illegal constructor modifiers: '#{modifiers}'.");
static const MessageKind ILLEGAL_MIXIN_APPLICATION_MODIFIERS =
const MessageKind(
- 'Error: Illegal mixin application modifiers: "#{modifiers}".');
+ "Error: Illegal mixin application modifiers: '#{modifiers}'.");
static const MessageKind ILLEGAL_MIXIN_SUPERCLASS = const MessageKind(
- 'Error: Class used as mixin must have Object as superclass.');
+ "Error: Class used as mixin must have Object as superclass.");
static const MessageKind ILLEGAL_MIXIN_OBJECT = const MessageKind(
- 'Error: Cannot use Object as mixin.');
+ "Error: Cannot use Object as mixin.");
static const MessageKind ILLEGAL_MIXIN_CONSTRUCTOR = const MessageKind(
- 'Error: Class used as mixin cannot have non-factory constructor.');
+ "Error: Class used as mixin cannot have non-factory constructor.");
static const MessageKind ILLEGAL_MIXIN_CYCLE = const MessageKind(
- 'Error: Class used as mixin introduces mixin cycle: '
- '"#{mixinName1}" <-> "#{mixinName2}".');
+ "Error: Class used as mixin introduces mixin cycle: "
+ "'#{mixinName1}' <-> '#{mixinName2}'.");
static const MessageKind ILLEGAL_MIXIN_WITH_SUPER = const MessageKind(
- 'Error: Cannot use class "#{className}" as a mixin because it uses '
- '"super".');
+ "Error: Cannot use class '#{className}' as a mixin because it uses "
+ "'super'.");
static const MessageKind ILLEGAL_MIXIN_SUPER_USE = const MessageKind(
- 'Info: Use of "super" in class used as mixin.');
+ "Info: Use of 'super' in class used as mixin.");
static const MessageKind PARAMETER_NAME_EXPECTED = const MessageKind(
- 'Error: parameter name expected.');
+ "Error: parameter name expected.");
static const DualKind CANNOT_RESOLVE_GETTER = const DualKind(
- error: const MessageKind('Error: Cannot resolve getter.'),
- warning: const MessageKind('Warning: Cannot resolve getter.'));
+ error: const MessageKind("Error: Cannot resolve getter."),
+ warning: const MessageKind("Warning: Cannot resolve getter."));
static const DualKind CANNOT_RESOLVE_SETTER = const DualKind(
- error: const MessageKind('Error: Cannot resolve setter.'),
- warning: const MessageKind('Warning: Cannot resolve setter.'));
+ error: const MessageKind("Error: Cannot resolve setter."),
+ warning: const MessageKind("Warning: Cannot resolve setter."));
static const MessageKind VOID_NOT_ALLOWED = const MessageKind(
"Error: Type 'void' can't be used here because it isn't a return type.",
@@ -768,22 +803,22 @@
]);
static const MessageKind BEFORE_TOP_LEVEL = const MessageKind(
- 'Error: Part header must come before top-level definitions.');
+ "Error: Part header must come before top-level definitions.");
static const MessageKind LIBRARY_NAME_MISMATCH = const MessageKind(
- 'Warning: Expected part of library name "#{libraryName}".');
+ "Warning: Expected part of library name '#{libraryName}'.");
static const MessageKind MISSING_PART_OF_TAG = const MessageKind(
- 'Error: This file has no part-of tag, but it is being used as a part.');
+ "Error: This file has no part-of tag, but it is being used as a part.");
static const MessageKind DUPLICATED_PART_OF = const MessageKind(
- 'Error: Duplicated part-of directive.');
+ "Error: Duplicated part-of directive.");
static const MessageKind ILLEGAL_DIRECTIVE = const MessageKind(
- 'Error: Directive not allowed here.');
+ "Error: Directive not allowed here.");
static const MessageKind DUPLICATED_LIBRARY_NAME = const MessageKind(
- 'Warning: Duplicated library name "#{libraryName}".');
+ "Warning: Duplicated library name '#{libraryName}'.");
// This is used as an exception.
static const MessageKind INVALID_SOURCE_FILE_LOCATION = const MessageKind('''
@@ -793,7 +828,7 @@
static const MessageKind TOP_LEVEL_VARIABLE_DECLARED_STATIC =
const MessageKind(
- 'Error: Top-level variable cannot be declared static.');
+ "Error: Top-level variable cannot be declared static.");
static const MessageKind REFERENCE_IN_INITIALIZATION = const MessageKind(
"Error: Variable '#{variableName}' is referenced during its "
@@ -835,85 +870,85 @@
static const MessageKind WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT =
const MessageKind(
- 'Error: Wrong number of arguments to assert. Should be 1, but given '
- '#{argumentCount}.');
+ "Error: Wrong number of arguments to assert. Should be 1, but given "
+ "#{argumentCount}.");
static const MessageKind ASSERT_IS_GIVEN_NAMED_ARGUMENTS = const MessageKind(
- 'Error: "assert" takes no named arguments, but given #{argumentCount}.');
+ "Error: 'assert' takes no named arguments, but given #{argumentCount}.");
static const MessageKind FACTORY_REDIRECTION_IN_NON_FACTORY =
const MessageKind(
- 'Error: Factory redirection only allowed in factories.');
+ "Error: Factory redirection only allowed in factories.");
static const MessageKind MISSING_FACTORY_KEYWORD = const MessageKind(
- 'Hint: Did you forget a factory keyword here?');
+ "Hint: Did you forget a factory keyword here?");
static const MessageKind DEFERRED_LIBRARY_NAME_MISMATCH =
const MessageKind(
- 'Error: Library name mismatch "#{expectedName}" != "#{actualName}".');
+ "Error: Library name mismatch '#{expectedName}' != '#{actualName}'.");
static const MessageKind ILLEGAL_STATIC = const MessageKind(
- 'Error: Modifier static is only allowed on functions declared in '
- 'a class.');
+ "Error: Modifier static is only allowed on functions declared in "
+ "a class.");
static const MessageKind STATIC_FUNCTION_BLOAT = const MessageKind(
- 'Hint: Using "#{class}.#{name}" may result in larger output.');
+ "Hint: Using '#{class}.#{name}' may result in larger output.");
static const MessageKind NON_CONST_BLOAT = const MessageKind('''
-Hint: Using "new #{name}" may result in larger output.
-Use "const #{name}" if possible.''');
+Hint: Using "new #{name}' may result in larger output.
+Use 'const #{name}' if possible.''');
static const MessageKind STRING_EXPECTED = const MessageKind(
- 'Error: Expected a "String", but got an instance of "#{type}".');
+ "Error: Expected a 'String', but got an instance of '#{type}'.");
static const MessageKind PRIVATE_IDENTIFIER = const MessageKind(
- 'Error: "#{value}" is not a valid Symbol name because it starts with '
- '"_".');
+ "Error: '#{value}' is not a valid Symbol name because it starts with "
+ "'_'.");
static const MessageKind UNSUPPORTED_LITERAL_SYMBOL = const MessageKind(
- 'Internal Error: Symbol literal "##{value}" is currently unsupported.');
+ "Internal Error: Symbol literal '##{value}' is currently unsupported.");
static const MessageKind INVALID_SYMBOL = const MessageKind('''
-Error: "#{value}" is not a valid Symbol name because is not:
+Error: '#{value}' is not a valid Symbol name because is not:
* an empty String,
* a user defined operator,
- * a qualified non-private identifier optionally followed by "=", or
- * a qualified non-private identifier followed by "." and a user-defined '''
-'operator.');
+ * a qualified non-private identifier optionally followed by '=', or
+ * a qualified non-private identifier followed by '.' and a user-defined '''
+"operator.");
static const MessageKind AMBIGUOUS_REEXPORT = const MessageKind(
- 'Info: "#{element}" is (re)exported by multiple libraries.');
+ "Info: '#{element}' is (re)exported by multiple libraries.");
static const MessageKind AMBIGUOUS_LOCATION = const MessageKind(
- 'Info: "#{element}" is defined here.');
+ "Info: '#{element}' is defined here.");
static const MessageKind IMPORTED_HERE = const MessageKind(
- 'Info: "#{element}" is imported here.');
+ "Info: '#{element}' is imported here.");
static const MessageKind OVERRIDE_EQUALS_NOT_HASH_CODE = const MessageKind(
- 'Hint: The class "#{class}" overrides "operator==", '
- 'but not "get hashCode".');
+ "Hint: The class '#{class}' overrides 'operator==', "
+ "but not 'get hashCode'.");
static const MessageKind PACKAGE_ROOT_NOT_SET = const MessageKind(
- 'Error: Cannot resolve "#{uri}". Package root has not been set.');
+ "Error: Cannot resolve '#{uri}'. Package root has not been set.");
static const MessageKind INTERNAL_LIBRARY_FROM = const MessageKind(
- 'Error: Internal library "#{resolvedUri}" is not accessible from '
- '"#{importingUri}".');
+ "Error: Internal library '#{resolvedUri}' is not accessible from "
+ "'#{importingUri}'.");
static const MessageKind INTERNAL_LIBRARY = const MessageKind(
- 'Error: Internal library "#{resolvedUri}" is not accessible.');
+ "Error: Internal library '#{resolvedUri}' is not accessible.");
static const MessageKind LIBRARY_NOT_FOUND = const MessageKind(
- 'Error: Library not found "#{resolvedUri}".');
+ "Error: Library not found '#{resolvedUri}'.");
static const MessageKind UNSUPPORTED_EQ_EQ_EQ = const MessageKind(
- 'Error: "===" is not an operator. '
- 'Did you mean "#{lhs} == #{rhs}" or "identical(#{lhs}, #{rhs})"?');
+ "Error: '===' is not an operator. "
+ "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?");
static const MessageKind UNSUPPORTED_BANG_EQ_EQ = const MessageKind(
- 'Error: "!==" is not an operator. '
- 'Did you mean "#{lhs} != #{rhs}" or "!identical(#{lhs}, #{rhs})"?');
+ "Error: '!==' is not an operator. "
+ "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?");
static const MessageKind UNSUPPORTED_PREFIX_PLUS = const MessageKind(
"Error: '+' is not a prefix operator. ",
@@ -923,8 +958,8 @@
]);
static const MessageKind UNSUPPORTED_THROW_WITHOUT_EXP = const MessageKind(
- 'Error: No expression after "throw". '
- 'Did you mean "rethrow"?');
+ "Error: No expression after 'throw'. "
+ "Did you mean 'rethrow'?");
static const MessageKind MIRRORS_EXPECTED_STRING = const MessageKind(
"Hint: Can't use '#{name}' here because it's an instance of '#{type}' "
@@ -1091,7 +1126,7 @@
"Info: Import of 'dart:mirrors'.");
static const MessageKind COMPILER_CRASHED = const MessageKind(
- 'Error: The compiler crashed when compiling this element.');
+ "Error: The compiler crashed when compiling this element.");
static const MessageKind PLEASE_REPORT_THE_CRASH = const MessageKind('''
The compiler is broken.
@@ -1119,89 +1154,89 @@
//////////////////////////////////////////////////////////////////////////////
static const MessageKind PATCH_RETURN_TYPE_MISMATCH = const MessageKind(
- 'Error: Patch return type "#{patchReturnType}" does not match '
- '"#{originReturnType}" on origin method "#{methodName}".');
+ "Error: Patch return type '#{patchReturnType}' does not match "
+ "'#{originReturnType}' on origin method '#{methodName}'.");
static const MessageKind PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH =
const MessageKind(
- 'Error: Required parameter count of patch method '
- '(#{patchParameterCount}) does not match parameter count on origin '
- 'method "#{methodName}" (#{originParameterCount}).');
+ "Error: Required parameter count of patch method "
+ "(#{patchParameterCount}) does not match parameter count on origin "
+ "method '#{methodName}' (#{originParameterCount}).");
static const MessageKind PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH =
const MessageKind(
- 'Error: Optional parameter count of patch method '
- '(#{patchParameterCount}) does not match parameter count on origin '
- 'method "#{methodName}" (#{originParameterCount}).');
+ "Error: Optional parameter count of patch method "
+ "(#{patchParameterCount}) does not match parameter count on origin "
+ "method '#{methodName}' (#{originParameterCount}).");
static const MessageKind PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH =
const MessageKind(
- 'Error: Optional parameters of origin and patch method '
- '"#{methodName}" must both be either named or positional.');
+ "Error: Optional parameters of origin and patch method "
+ "'#{methodName}' must both be either named or positional.");
static const MessageKind PATCH_PARAMETER_MISMATCH = const MessageKind(
- 'Error: Patch method parameter "#{patchParameter}" does not match '
- '"#{originParameter}" on origin method "#{methodName}".');
+ "Error: Patch method parameter '#{patchParameter}' does not match "
+ "'#{originParameter}' on origin method '#{methodName}'.");
static const MessageKind PATCH_PARAMETER_TYPE_MISMATCH = const MessageKind(
- 'Error: Patch method parameter "#{parameterName}" type '
- '"#{patchParameterType}" does not match "#{originParameterType}" on '
- 'origin method "#{methodName}".');
+ "Error: Patch method parameter '#{parameterName}' type "
+ "'#{patchParameterType}' does not match '#{originParameterType}' on "
+ "origin method '#{methodName}'.");
static const MessageKind PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION =
- const MessageKind('Error: External method without an implementation.');
+ const MessageKind("Error: External method without an implementation.");
static const MessageKind PATCH_POINT_TO_FUNCTION = const MessageKind(
- 'Info: This is the function patch "#{functionName}".');
+ "Info: This is the function patch '#{functionName}'.");
static const MessageKind PATCH_POINT_TO_CLASS = const MessageKind(
- 'Info: This is the class patch "#{className}".');
+ "Info: This is the class patch '#{className}'.");
static const MessageKind PATCH_POINT_TO_GETTER = const MessageKind(
- 'Info: This is the getter patch "#{getterName}".');
+ "Info: This is the getter patch '#{getterName}'.");
static const MessageKind PATCH_POINT_TO_SETTER = const MessageKind(
- 'Info: This is the setter patch "#{setterName}".');
+ "Info: This is the setter patch '#{setterName}'.");
static const MessageKind PATCH_POINT_TO_CONSTRUCTOR = const MessageKind(
- 'Info: This is the constructor patch "#{constructorName}".');
+ "Info: This is the constructor patch '#{constructorName}'.");
static const MessageKind PATCH_POINT_TO_PARAMETER = const MessageKind(
- 'Info: This is the patch parameter "#{parameterName}".');
+ "Info: This is the patch parameter '#{parameterName}'.");
static const MessageKind PATCH_NON_EXISTING = const MessageKind(
- 'Error: Origin does not exist for patch "#{name}".');
+ "Error: Origin does not exist for patch '#{name}'.");
// TODO(ahe): Eventually, this error should be removed as it will be handled
// by the regular parser.
static const MessageKind PATCH_NONPATCHABLE = const MessageKind(
- 'Error: Only classes and functions can be patched.');
+ "Error: Only classes and functions can be patched.");
static const MessageKind PATCH_NON_EXTERNAL = const MessageKind(
- 'Error: Only external functions can be patched.');
+ "Error: Only external functions can be patched.");
static const MessageKind PATCH_NON_CLASS = const MessageKind(
- 'Error: Patching non-class with class patch "#{className}".');
+ "Error: Patching non-class with class patch '#{className}'.");
static const MessageKind PATCH_NON_GETTER = const MessageKind(
- 'Error: Cannot patch non-getter "#{name}" with getter patch.');
+ "Error: Cannot patch non-getter '#{name}' with getter patch.");
static const MessageKind PATCH_NO_GETTER = const MessageKind(
- 'Error: No getter found for getter patch "#{getterName}".');
+ "Error: No getter found for getter patch '#{getterName}'.");
static const MessageKind PATCH_NON_SETTER = const MessageKind(
- 'Error: Cannot patch non-setter "#{name}" with setter patch.');
+ "Error: Cannot patch non-setter '#{name}' with setter patch.");
static const MessageKind PATCH_NO_SETTER = const MessageKind(
- 'Error: No setter found for setter patch "#{setterName}".');
+ "Error: No setter found for setter patch '#{setterName}'.");
static const MessageKind PATCH_NON_CONSTRUCTOR = const MessageKind(
- 'Error: Cannot patch non-constructor with constructor patch '
- '"#{constructorName}".');
+ "Error: Cannot patch non-constructor with constructor patch "
+ "'#{constructorName}'.");
static const MessageKind PATCH_NON_FUNCTION = const MessageKind(
- 'Error: Cannot patch non-function with function patch '
- '"#{functionName}".');
+ "Error: Cannot patch non-function with function patch "
+ "'#{functionName}'.");
//////////////////////////////////////////////////////////////////////////////
// Patch errors end.
diff --git a/sdk/lib/_internal/lib/async_patch.dart b/sdk/lib/_internal/lib/async_patch.dart
index 850d4e6..bb1aa7c 100644
--- a/sdk/lib/_internal/lib/async_patch.dart
+++ b/sdk/lib/_internal/lib/async_patch.dart
@@ -4,6 +4,7 @@
// Patch file for the dart:async library.
+import 'dart:_js_helper' show Primitives;
import 'dart:_isolate_helper' show IsolateNatives, TimerImpl;
import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS;
@@ -45,7 +46,7 @@
return future.then((_) => false);
}
- if (IsolateNatives.isJsshell) {
+ if (Primitives.isJsshell) {
// TODO(ahe): Move this code to a JavaScript command helper script that is
// not included in generated output.
return _loadedLibraries[libraryName] = new Future<bool>(() {
@@ -55,7 +56,7 @@
JS('void', '(new Function(#))()', 'loadRelativeToScript("$uri")');
return true;
});
- } else if (IsolateNatives.isD8) {
+ } else if (Primitives.isD8) {
// TODO(ahe): Move this code to a JavaScript command helper script that is
// not included in generated output.
return _loadedLibraries[libraryName] = new Future<bool>(() {
diff --git a/sdk/lib/_internal/lib/collection_patch.dart b/sdk/lib/_internal/lib/collection_patch.dart
index 7066b05..7d6313c 100644
--- a/sdk/lib/_internal/lib/collection_patch.dart
+++ b/sdk/lib/_internal/lib/collection_patch.dart
@@ -14,12 +14,15 @@
if (equals == null) {
return new _HashMap<K, V>();
}
- if (identical(identical, equals)) {
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
return new _IdentityHashMap<K, V>();
}
- hashCode = _defaultHashCode;
- } else if (equals == null) {
- equals = _defaultEquals;
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
} else {
if (hashCode == null) {
@@ -31,6 +34,8 @@
}
return new _CustomHashMap<K, V>(equals, hashCode, isValidKey);
}
+
+ patch factory HashMap.identity() = _IdentityHashMap<K, V>;
}
class _HashMap<K, V> implements HashMap<K, V> {
@@ -56,7 +61,6 @@
_HashMap();
- Type get runtimeType => HashMap;
int get length => _length;
bool get isEmpty => _length == 0;
@@ -339,6 +343,13 @@
}
class _IdentityHashMap<K, V> extends _HashMap<K, V> {
+ int _computeHashCode(var key) {
+ // We force the hash codes to be unsigned 30-bit integers to avoid
+ // issues with problematic keys like '__proto__'. Another option
+ // would be to throw an exception if the hash code isn't a number.
+ return JS('int', '# & 0x3ffffff', identityHashCode(key));
+ }
+
int _findBucketIndex(var bucket, var key) {
if (bucket == null) return -1;
int length = JS('int', '#.length', bucket);
@@ -454,12 +465,15 @@
if (equals == null) {
return new _LinkedHashMap<K, V>();
}
- if (identical(identical, equals)) {
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
return new _LinkedIdentityHashMap<K, V>();
}
- hashCode = _defaultHashCode;
- } else if (equals == null) {
- equals = _defaultEquals;
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
} else {
if (hashCode == null) {
@@ -471,6 +485,8 @@
}
return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
}
+
+ patch factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>;
}
class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
@@ -500,7 +516,6 @@
_LinkedHash();
- Type get runtimeType => LinkedHashMap;
int get length => _length;
bool get isEmpty => _length == 0;
@@ -766,6 +781,13 @@
}
class _LinkedIdentityHashMap<K, V> extends _LinkedHashMap<K, V> {
+ int _computeHashCode(var key) {
+ // We force the hash codes to be unsigned 30-bit integers to avoid
+ // issues with problematic keys like '__proto__'. Another option
+ // would be to throw an exception if the hash code isn't a number.
+ return JS('int', '# & 0x3ffffff', identityHashCode(key));
+ }
+
int _findBucketIndex(var bucket, var key) {
if (bucket == null) return -1;
int length = JS('int', '#.length', bucket);
@@ -891,19 +913,28 @@
if (equals == null) {
return new _HashSet<E>();
}
- if (identical(identical, equals)) {
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
return new _IdentityHashSet<E>();
}
- hashCode = _defaultHashCode;
- } else if (equals == null) {
- equals = _defaultEquals;
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
} else {
- if (hashCode == null) hashCode = _defaultHashCode;
- if (equals == null) equals = _defaultEquals;
+ if (hashCode == null) {
+ hashCode = _defaultHashCode;
+ }
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
return new _CustomHashSet<E>(equals, hashCode, isValidKey);
}
+
+ patch factory HashSet.identity() = _IdentityHashSet<E>;
}
class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> {
@@ -1172,6 +1203,13 @@
class _IdentityHashSet<E> extends _HashSet<E> {
Set<E> _newSet() => new _IdentityHashSet<E>();
+ int _computeHashCode(var key) {
+ // We force the hash codes to be unsigned 30-bit integers to avoid
+ // issues with problematic keys like '__proto__'. Another option
+ // would be to throw an exception if the hash code isn't a number.
+ return JS('int', '# & 0x3ffffff', identityHashCode(key));
+ }
+
int _findBucketIndex(var bucket, var element) {
if (bucket == null) return -1;
int length = JS('int', '#.length', bucket);
@@ -1277,19 +1315,28 @@
if (equals == null) {
return new _LinkedHashSet<E>();
}
- if (identical(identical, equals)) {
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
return new _LinkedIdentityHashSet<E>();
}
- hashCode = _defaultHashCode;
- } else if (equals == null) {
- equals = _defaultEquals;
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
} else {
- if (hashCode == null) hashCode = _defaultHashCode;
- if (equals == null) equals = _defaultEquals;
+ if (hashCode == null) {
+ hashCode = _defaultHashCode;
+ }
+ if (equals == null) {
+ equals = _defaultEquals;
+ }
}
return new _LinkedCustomHashSet<E>(equals, hashCode, isValidKey);
}
+
+ patch factory LinkedHashSet.identity() = _LinkedIdentityHashSet<E>;
}
class _LinkedHashSet<E> extends _HashSetBase<E> implements LinkedHashSet<E> {
@@ -1591,6 +1638,13 @@
class _LinkedIdentityHashSet<E> extends _LinkedHashSet<E> {
Set<E> _newSet() => new _LinkedIdentityHashSet<E>();
+ int _computeHashCode(var key) {
+ // We force the hash codes to be unsigned 30-bit integers to avoid
+ // issues with problematic keys like '__proto__'. Another option
+ // would be to throw an exception if the hash code isn't a number.
+ return JS('int', '# & 0x3ffffff', identityHashCode(key));
+ }
+
int _findBucketIndex(var bucket, var element) {
if (bucket == null) return -1;
int length = JS('int', '#.length', bucket);
diff --git a/sdk/lib/_internal/lib/core_patch.dart b/sdk/lib/_internal/lib/core_patch.dart
index aaa8164..e14786a 100644
--- a/sdk/lib/_internal/lib/core_patch.dart
+++ b/sdk/lib/_internal/lib/core_patch.dart
@@ -3,12 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
// Patch file for dart:core classes.
+import "dart:_collection-dev" as _symbol_dev;
import 'dart:_interceptors';
import 'dart:_js_helper' show checkNull,
getRuntimeType,
JSSyntaxRegExp,
Primitives,
- stringJoinUnchecked;
+ stringJoinUnchecked,
+ objectHashCode;
import "dart:_collection-dev" as _symbol_dev;
String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
@@ -26,10 +28,13 @@
Primitives.printString(object.toString());
}
+patch int identityHashCode(Object object) => objectHashCode(object);
+
// Patch for Object implementation.
patch class Object {
patch int get hashCode => Primitives.objectHashCode(this);
+
patch String toString() => Primitives.objectToString(this);
patch dynamic noSuchMethod(Invocation invocation) {
@@ -311,4 +316,10 @@
patch class Uri {
patch static bool get _isWindows => false;
+
+ patch static Uri get base {
+ String uri = Primitives.currentUri();
+ if (uri != null) return Uri.parse(uri);
+ throw new UnsupportedError("'Uri.base' is not supported");
+ }
}
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index b87d045..095c424 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -27,9 +27,6 @@
patch static List _list(String path, bool recursive, bool followLinks) {
throw new UnsupportedError("Directory._list");
}
- patch static SendPort _newServicePort() {
- throw new UnsupportedError("Directory._newServicePort");
- }
}
patch class _EventHandler {
@@ -40,12 +37,6 @@
}
}
-patch class _FileUtils {
- patch static SendPort _newServicePort() {
- throw new UnsupportedError("FileUtils._newServicePort");
- }
-}
-
patch class FileStat {
patch static List<int> _statSync(String path) {
throw new UnsupportedError("FileStat.stat");
@@ -300,9 +291,6 @@
patch factory _SecureFilter() {
throw new UnsupportedError("_SecureFilter._SecureFilter");
}
- patch static SendPort _newServicePort() {
- throw new UnsupportedError("_SecureFilter._newServicePort");
- }
}
patch class _StdIOUtils {
@@ -358,3 +346,9 @@
throw new UnsupportedError("_FileSystemWatcher.isSupported");
}
}
+
+patch class _IOService {
+ patch static Future dispatch(int request, List data) {
+ throw new UnsupportedError("_IOService.dispatch");
+ }
+}
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index 7a6e620..ac4cc0f 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -424,17 +424,6 @@
/// Associates an ID with a native worker object.
static final Expando<int> workerIds = new Expando<int>();
- static bool get isD8 {
- return JS('bool',
- 'typeof version == "function"'
- ' && typeof os == "object" && "system" in os');
- }
-
- static bool get isJsshell {
- return JS('bool',
- 'typeof version == "function" && typeof system == "function"');
- }
-
/**
* The src url for the script tag that loaded this code. Used to create
* JavaScript workers.
@@ -444,8 +433,8 @@
if (currentScript != null) {
return JS('String', 'String(#.src)', currentScript);
}
- if (isD8) return computeThisScriptD8();
- if (isJsshell) return computeThisScriptJsshell();
+ if (Primitives.isD8) return computeThisScriptD8();
+ if (Primitives.isJsshell) return computeThisScriptJsshell();
return null;
}
@@ -606,7 +595,13 @@
// TODO(sigmund): clean up above, after we make the new API the default:
+ /// If [uri] is `null` it is replaced with the current script.
static spawn(String functionName, String uri, bool isLight) {
+ // Assume that the compiled version of the Dart file lives just next to the
+ // dart file.
+ // TODO(floitsch): support precompiled version of dart2js output.
+ if (uri != null && uri.endsWith(".dart")) uri += ".js";
+
Completer<SendPort> completer = new Completer.sync<SendPort>();
ReceivePort port = new ReceivePort();
port.receive((msg, SendPort replyPort) {
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index 073436e..ddeb666 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -470,6 +470,45 @@
return 1000 * dateNow();
}
+ static bool get isD8 {
+ return JS('bool',
+ 'typeof version == "function"'
+ ' && typeof os == "object" && "system" in os');
+ }
+
+ static bool get isJsshell {
+ return JS('bool',
+ 'typeof version == "function" && typeof system == "function"');
+ }
+
+ static String currentUri() {
+ // In a browser return self.location.href.
+ if (JS('bool', 'typeof self != "undefined"')) {
+ return JS('String', 'self.location.href');
+ }
+
+ // In JavaScript shells try to determine the current working
+ // directory.
+ var workingDirectory;
+ if (isD8) {
+ // TODO(sgjesse): This does not work on Windows.
+ workingDirectory = JS('String', 'os.system("pwd")');
+ var length = workingDirectory.length;
+ if (workingDirectory[length - 1] == '\n') {
+ workingDirectory = workingDirectory.substring(0, length - 1);
+ }
+ }
+
+ if (isJsshell) {
+ // TODO(sgjesse): This does not work on Windows.
+ workingDirectory = JS('String', 'environment["PWD"]');
+ }
+
+ return workingDirectory != null
+ ? "file://" + workingDirectory + "/"
+ : null;
+ }
+
// This is to avoid stack overflows due to very large argument arrays in
// apply(). It fixes http://dartbug.com/6919
static String _fromCharCodeApply(List<int> array) {
@@ -667,7 +706,6 @@
arguments.addAll(positionalArguments);
}
- // TODO(ahe): Use JS_SOMETHING to get name from Namer.
if (JS('bool', r'# in #', JS_GET_NAME('CALL_CATCH_ALL'), function)) {
// We expect the closure to have a "call$catchAll" (the value of
// JS_GET_NAME('CALL_CATCH_ALL')) function that returns all the expected
@@ -1422,7 +1460,7 @@
}
}
-int _objectHashCode(var object) {
+int objectHashCode(var object) {
if (object == null || JS('bool', "typeof # != 'object'", object)) {
return object.hashCode;
} else {
@@ -1440,7 +1478,7 @@
makeConstantMap(keyValuePairs) {
return fillLiteralMap(keyValuePairs,
- new LinkedHashMap(equals: identical, hashCode: _objectHashCode));
+ new LinkedHashMap(equals: identical, hashCode: objectHashCode));
}
fillLiteralMap(keyValuePairs, Map result) {
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index cf002e8..2887c43 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -33,6 +33,8 @@
JSExtendableArray;
import 'dart:_js_names';
+const String METHODS_WITH_OPTIONAL_ARGUMENTS = r'$methodsWithOptionalArguments';
+
/// No-op method that is called to inform the compiler that tree-shaking needs
/// to be disabled.
disableTreeShaking() => preserveNames();
@@ -178,6 +180,29 @@
SourceLocation get location => throw new UnimplementedError();
}
+class JsTypeVariableMirror extends JsTypeMirror implements TypeVariableMirror {
+ final TypeMirror upperBound;
+ final DeclarationMirror owner;
+
+ JsTypeVariableMirror(Symbol simpleName, this.upperBound, this.owner)
+ : super(simpleName);
+
+ bool operator ==(other) {
+ return (other is JsTypeVariableMirror &&
+ simpleName == other.simpleName &&
+ owner == other.owner);
+ }
+
+ int get hashCode {
+ int code = 0x3FFFFFFF & (JsTypeVariableMirror).hashCode;
+ code ^= 17 * simpleName.hashCode;
+ code ^= 19 * owner.hashCode;
+ return code;
+ }
+
+ String get _prettyName => 'TypeVariableMirror';
+}
+
class JsTypeMirror extends JsDeclarationMirror implements TypeMirror {
JsTypeMirror(Symbol simpleName)
: super(simpleName);
@@ -624,9 +649,6 @@
Future<InstanceMirror> invokeAsync(Symbol memberName,
List<Object> positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null && !namedArguments.isEmpty) {
- throw new UnsupportedError('Named arguments are not implemented.');
- }
return
new Future<InstanceMirror>(
() => invoke(memberName, positionalArguments, namedArguments));
@@ -635,12 +657,55 @@
InstanceMirror invoke(Symbol memberName,
List positionalArguments,
[Map<Symbol,dynamic> namedArguments]) {
+ String name = n(memberName);
+ String reflectiveName;
if (namedArguments != null && !namedArguments.isEmpty) {
- throw new UnsupportedError('Named arguments are not implemented.');
+ var methodsWithOptionalArguments =
+ JS('=Object', '#.\$methodsWithOptionalArguments', reflectee);
+ String mangledName =
+ JS('String|Null', '#[#]', methodsWithOptionalArguments, '*$name');
+ if (mangledName == null) {
+ // TODO(ahe): Invoke noSuchMethod.
+ throw new UnimplementedNoSuchMethodError(
+ 'Invoking noSuchMethod with named arguments not implemented');
+ }
+ var defaultValueIndices =
+ JS('List|Null', '#[#].\$defaultValues', reflectee, mangledName);
+ var defaultValues =
+ defaultValueIndices.map((int i) => JS('', 'init.metadata[#]', i))
+ .iterator;
+ var defaultArguments = new Map();
+ reflectiveName = mangledNames[mangledName];
+ var reflectiveNames = reflectiveName.split(':');
+ int requiredPositionalArgumentCount =
+ int.parse(reflectiveNames.elementAt(1));
+ positionalArguments = new List.from(positionalArguments);
+ // Check the number of positional arguments is valid.
+ if (requiredPositionalArgumentCount != positionalArguments.length) {
+ // TODO(ahe): Invoke noSuchMethod.
+ throw new UnimplementedNoSuchMethodError(
+ 'Invoking noSuchMethod with named arguments not implemented');
+ }
+ for (String parameter in reflectiveNames.skip(3)) {
+ defaultValues.moveNext();
+ defaultArguments[parameter] = defaultValues.current;
+ }
+ namedArguments.forEach((Symbol symbol, value) {
+ String parameter = n(symbol);
+ if (defaultArguments.containsKey(parameter)) {
+ defaultArguments[parameter] = value;
+ } else {
+ // Extraneous named argument.
+ // TODO(ahe): Invoke noSuchMethod.
+ throw new UnimplementedNoSuchMethodError(
+ 'Invoking noSuchMethod with named arguments not implemented');
+ }
+ });
+ positionalArguments.addAll(defaultArguments.values);
+ } else {
+ reflectiveName =
+ JS('String', '# + ":" + # + ":0"', name, positionalArguments.length);
}
- String reflectiveName =
- JS('String', '# + ":" + # + ":0"',
- n(memberName), positionalArguments.length);
// We can safely pass positionalArguments to _invoke as it will wrap it in
// a JSArray if needed.
return _invoke(memberName, JSInvocationMirror.METHOD, reflectiveName,
@@ -663,8 +728,13 @@
if (cacheEntry == null) {
disableTreeShaking();
String mangledName = reflectiveNames[reflectiveName];
- // TODO(ahe): Get the argument names.
- List<String> argumentNames = [];
+ List<String> argumentNames = const [];
+ if (type == JSInvocationMirror.METHOD) {
+ // Note: [argumentNames] are not what the user actually provided, it is
+ // always all the named paramters.
+ argumentNames = reflectiveName.split(':').skip(3).toList();
+ }
+
// TODO(ahe): We don't need to create an invocation mirror here. The
// logic from JSInvocationMirror.getCachedInvocation could easily be
// inlined here.
@@ -899,6 +969,7 @@
UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
UnmodifiableListView<InstanceMirror> _cachedMetadata;
UnmodifiableListView<ClassMirror> _cachedSuperinterfaces;
+ UnmodifiableListView<TypeVariableMirror> _cachedTypeVariables;
// Set as side-effect of accessing JsLibraryMirror.classes.
JsLibraryMirror _owner;
@@ -938,7 +1009,7 @@
List<String> keys = extractKeys(prototype);
var result = <JsMethodMirror>[];
for (String key in keys) {
- if (key == '') continue;
+ if (isReflectiveDataInPrototype(key)) continue;
String simpleName = mangledNames[key];
// [simpleName] can be null if [key] represents an implementation
// detail, for example, a bailout method, or runtime type support.
@@ -957,7 +1028,7 @@
int length = keys.length;
for (int i = 0; i < length; i++) {
String mangledName = keys[i];
- if (mangledName == '') continue; // Skip static field descriptor.
+ if (isReflectiveDataInPrototype(mangledName)) continue;
String unmangledName = mangledName;
var jsFunction = JS('', '#[#]', owner._globalObject, mangledName);
@@ -1243,9 +1314,23 @@
new UnmodifiableListView<ClassMirror>(result);
}
- // TODO(ahe): Implement these.
- List<TypeVariableMirror> get typeVariables
- => throw new UnimplementedError();
+ List<TypeVariableMirror> get typeVariables {
+ if (_cachedTypeVariables != null) return _cachedTypeVariables;
+ List result = new List();
+ List typeVars =
+ JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
+ if (typeVars == null) return result;
+ for (int i = 0; i < typeVars.length; i += 2) {
+ TypeMirror upperBound =
+ typeMirrorFromRuntimeTypeRepresentation(JS('', 'init.metadata[#]',
+ typeVars[i+1]));
+ var typeMirror =
+ new JsTypeVariableMirror(s(typeVars[i]), upperBound, this);
+ result.add(typeMirror);
+ }
+ return _cachedTypeVariables = new UnmodifiableListView(result);
+ }
+
List<TypeMirror> get typeArguments => new List();
}
@@ -1812,6 +1897,14 @@
}
}
+/// Returns true if the key represent ancillary reflection data, that is, not a
+/// method.
+bool isReflectiveDataInPrototype(String key) {
+ if (key == '' || key == METHODS_WITH_OPTIONAL_ARGUMENTS) return true;
+ String firstChar = key[0];
+ return firstChar == '*' || firstChar == '+';
+}
+
// Copied from package "unmodifiable_collection".
// TODO(ahe): Lobby to get it added to dart:collection.
class UnmodifiableMapView<K, V> implements Map<K, V> {
@@ -1851,3 +1944,13 @@
void clear() => _throw();
}
+
+// TODO(ahe): Remove this class and call noSuchMethod instead.
+class UnimplementedNoSuchMethodError extends Error
+ implements NoSuchMethodError {
+ final String _message;
+
+ UnimplementedNoSuchMethodError(this._message);
+
+ String toString() => "Unsupported operation: $_message";
+}
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index fee473e..8da7a8c 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -27,9 +27,9 @@
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/lib/async_patch.dart"),
- "chrome": const LibraryInfo(
- "chrome/dart2js/chrome_dart2js.dart",
- maturity: Maturity.DEPRECATED,
+ "_chrome": const LibraryInfo(
+ "_chrome/dart2js/chrome_dart2js.dart",
+ documented: false,
category: "Client"),
"collection": const LibraryInfo(
diff --git a/sdk/lib/_internal/pub/bin/pub.dart b/sdk/lib/_internal/pub/bin/pub.dart
index 1a3e16c..ecd58bd 100644
--- a/sdk/lib/_internal/pub/bin/pub.dart
+++ b/sdk/lib/_internal/pub/bin/pub.dart
@@ -26,7 +26,8 @@
} on FormatException catch (e) {
log.error(e.message);
log.error('Run "pub help" to see available options.');
- exit(exit_codes.USAGE);
+ flushThenExit(exit_codes.USAGE);
+ return;
}
if (options['version']) {
@@ -46,7 +47,7 @@
} else {
log.error('Could not find a command named "${options.rest[0]}".');
log.error('Run "pub help" to see available commands.');
- exit(exit_codes.USAGE);
+ flushThenExit(exit_codes.USAGE);
}
return;
}
@@ -126,7 +127,7 @@
return runProcess('ver', []).then((result) {
if (result.stdout.join('\n').contains('XP')) {
log.error('Sorry, but pub is not supported on Windows XP.');
- exit(exit_codes.USAGE);
+ return flushThenExit(exit_codes.USAGE);
}
});
});
diff --git a/sdk/lib/_internal/pub/lib/src/barback.dart b/sdk/lib/_internal/pub/lib/src/barback.dart
index 3c14a16..803ec64 100644
--- a/sdk/lib/_internal/pub/lib/src/barback.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback.dart
@@ -10,9 +10,9 @@
import 'barback/load_all_transformers.dart';
import 'barback/pub_package_provider.dart';
-import 'barback/rewrite_import_transformer.dart';
import 'barback/server.dart';
import 'barback/watch_sources.dart';
+import 'package_graph.dart';
import 'utils.dart';
/// An identifier for a transformer and the configuration that will be passed to
@@ -33,9 +33,8 @@
if (configuration == null) return;
for (var reserved in ['include', 'exclude']) {
if (!configuration.containsKey(reserved)) continue;
- throw new FormatException('Configuration for transformer '
- '${idToLibraryIdentifier(asset)} may not include reserved key '
- '"$reserved".');
+ throw new FormatException('Transformer configuration may not include '
+ 'reserved key "$reserved".');
}
}
@@ -98,7 +97,7 @@
/// Otherwise, it expands to lib/${path}.dart in that package.
AssetId libraryIdentifierToId(String identifier) {
if (identifier.isEmpty) {
- throw new FormatError('Invalid library identifier: "".');
+ throw new FormatException('Invalid library identifier: "".');
}
// Convert the concise asset name in the pubspec (of the form "package"
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
index e954da8..3efce84 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
@@ -11,8 +11,8 @@
import 'load_transformers.dart';
import 'rewrite_import_transformer.dart';
import 'server.dart';
-import 'watch_sources.dart';
import '../barback.dart';
+import '../package_graph.dart';
import '../utils.dart';
/// Loads all transformers depended on by packages in [graph].
@@ -245,7 +245,7 @@
///
/// It's an error to call this before [load] is called with [id] and the
/// future it returns has completed.
- Set<Transformers> transformersFor(TransformerId id) {
+ Set<Transformer> transformersFor(TransformerId id) {
assert(_transformers.containsKey(id));
return _transformers[id];
}
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
index b2c8464..557dbba 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
@@ -9,11 +9,12 @@
import 'dart:isolate';
import 'package:barback/barback.dart';
-import 'package:stack_trace/stack_trace.dart';
+import '../barback.dart';
import '../dart.dart' as dart;
import '../log.dart' as log;
import '../utils.dart';
+import 'server.dart';
/// A Dart script to run in an isolate.
///
@@ -25,7 +26,7 @@
import 'dart:convert';
import 'dart:mirrors';
-import 'http://localhost:<<PORT>>/packages/barback/barback.dart';
+import 'http://<<HOST_AND_PORT>>/packages/barback/barback.dart';
/// Sets up the initial communication with the host isolate.
void main() {
@@ -47,7 +48,7 @@
var mirrors = currentMirrorSystem();
// TODO(nweiz): look this up by name once issue 5897 is fixed.
var transformerUri = Uri.parse(
- 'http://localhost:<<PORT>>/packages/barback/src/transformer.dart');
+ 'http://<<HOST_AND_PORT>>/packages/barback/src/transformer.dart');
var transformerClass = mirrors.libraries[transformerUri]
.classes[const Symbol('Transformer')];
@@ -288,10 +289,10 @@
TransformerId id) {
var path = id.asset.path.replaceFirst('lib/', '');
// TODO(nweiz): load from a "package:" URI when issue 12474 is fixed.
- var uri = 'http://localhost:${server.port}/packages/${id.asset.package}/'
- '$path';
+ var hostAndPort = '${server.host}:${server.port}';
+ var uri = 'http://$hostAndPort/packages/${id.asset.package}/$path';
var code = 'import "$uri";' +
- _TRANSFORMER_ISOLATE.replaceAll('<<PORT>>', server.port.toString());
+ _TRANSFORMER_ISOLATE.replaceAll('<<HOST_AND_PORT>>', hostAndPort);
log.fine("Loading transformers from ${id.asset}");
return dart.runInIsolate(code).then((sendPort) {
return _receiveFuture(sendPort.call({
@@ -306,7 +307,7 @@
return transformers;
});
}).catchError((error) {
- if (error is! CrossIsolateException) throw error;
+ if (error is! dart.CrossIsolateException) throw error;
if (error.type != 'IsolateSpawnException') throw error;
// TODO(nweiz): don't parse this as a string once issues 12617 and 12689 are
// fixed.
@@ -322,7 +323,7 @@
}
/// A wrapper for a transformer that's in a different isolate.
-class _ForeignTransformer implements Transformer {
+class _ForeignTransformer extends Transformer {
/// The port with which we communicate with the child isolate.
///
/// This port and all messages sent across it are specific to this
@@ -407,13 +408,13 @@
/// Sends the result of [future] through [port].
///
/// This should be received on the other end using [_receiveFuture]. It
-/// re-raises any exceptions on the other side as [CrossIsolateException]s.
+/// re-raises any exceptions on the other side as [dart.CrossIsolateException]s.
void _sendFuture(SendPort port, Future future) {
future.then((result) {
port.send({'success': result});
}).catchError((error) {
// TODO(nweiz): at least MissingInputException should be preserved here.
- port.send({'error': CrossIsolateException.serialize(error)});
+ port.send({'error': dart.CrossIsolateException.serialize(error)});
});
}
diff --git a/sdk/lib/_internal/pub/lib/src/barback/rewrite_import_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/rewrite_import_transformer.dart
index 66fda92..072a4c2 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/rewrite_import_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/rewrite_import_transformer.dart
@@ -4,6 +4,8 @@
library pub.rewrite_import_transformer;
+import 'dart:async';
+
import 'package:barback/barback.dart';
import 'package:analyzer_experimental/analyzer.dart';
diff --git a/sdk/lib/_internal/pub/lib/src/barback/server.dart b/sdk/lib/_internal/pub/lib/src/barback/server.dart
index 3db42e5..a2ce379 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/server.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/server.dart
@@ -29,6 +29,11 @@
/// The server's port.
final int port;
+ /// The server's hostname.
+ final String host;
+ // TODO(whesse): replace this with the InternetAddress of the HttpServer, when
+ // that is exposed.
+
/// The results of requests handled by the server.
///
/// These can be used to provide visual feedback for the server's processing.
@@ -45,10 +50,10 @@
static Future<BarbackServer> bind(String host, int port, Barback barback,
String rootPackage) {
return HttpServer.bind(host, port)
- .then((server) => new BarbackServer._(server, barback, rootPackage));
+ .then((server) => new BarbackServer._(server, barback, rootPackage, host));
}
- BarbackServer._(HttpServer server, this.barback, this._rootPackage)
+ BarbackServer._(HttpServer server, this.barback, this._rootPackage, this.host)
: _server = server,
port = server.port {
_server.listen(_handleRequest, onError: (error) {
@@ -204,7 +209,7 @@
/// result. Malformed requests will be handled internally.
class BarbackServerResult {
/// The requested url.
- final Url url;
+ final Uri url;
/// The id that [url] identifies.
final AssetId id;
diff --git a/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart b/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
index dc29294..89f474c 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
@@ -10,6 +10,7 @@
import '../entrypoint.dart';
import '../io.dart';
+import '../package.dart';
import '../package_graph.dart';
/// Adds all of the source assets in the provided packages to barback and
diff --git a/sdk/lib/_internal/pub/lib/src/command.dart b/sdk/lib/_internal/pub/lib/src/command.dart
index 9689cc6..f522854 100644
--- a/sdk/lib/_internal/pub/lib/src/command.dart
+++ b/sdk/lib/_internal/pub/lib/src/command.dart
@@ -24,8 +24,8 @@
import 'entrypoint.dart';
import 'exit_codes.dart' as exit_codes;
import 'http.dart';
+import 'io.dart';
import 'log.dart' as log;
-import 'package.dart';
import 'system_cache.dart';
import 'utils.dart';
@@ -113,7 +113,7 @@
""");
}
- exit(_chooseExitCode(error));
+ return flushThenExit(_chooseExitCode(error));
}
new Future.sync(() {
@@ -128,20 +128,12 @@
if (commandFuture == null) return true;
return commandFuture;
- }).whenComplete(() => cache.deleteTempDir()).catchError((e) {
- if (e is PubspecNotFoundException && e.name == null) {
- e = new ApplicationException('Could not find a file named '
- '"pubspec.yaml" in the directory ${path.current}.');
- } else if (e is PubspecHasNoNameException && e.name == null) {
- e = new ApplicationException('pubspec.yaml is missing the required '
- '"name" field (e.g. "name: ${path.basename(path.current)}").');
- }
-
- handleError(e);
- }).then((_) {
+ }).whenComplete(() => cache.deleteTempDir())
+ .catchError(handleError)
+ .then((_) {
// Explicitly exit on success to ensure that any dangling dart:io handles
// don't cause the process to never terminate.
- exit(0);
+ return flushThenExit(0);
});
}
diff --git a/sdk/lib/_internal/pub/lib/src/command/cache.dart b/sdk/lib/_internal/pub/lib/src/command/cache.dart
index 122ee1c..ec0d181 100644
--- a/sdk/lib/_internal/pub/lib/src/command/cache.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/cache.dart
@@ -6,10 +6,10 @@
import 'dart:async';
import 'dart:convert';
-import 'dart:io';
import '../command.dart';
import '../exit_codes.dart' as exit_codes;
+import '../io.dart';
import '../log.dart' as log;
/// Handles the `cache` pub command.
@@ -23,13 +23,13 @@
if (commandOptions.rest.length != 1) {
log.error('The cache command expects one argument.');
this.printUsage();
- exit(exit_codes.USAGE);
+ return flushThenExit(exit_codes.USAGE);
}
if ((commandOptions.rest[0] != 'list')) {
log.error('Unknown cache command "${commandOptions.rest[0]}".');
this.printUsage();
- exit(exit_codes.USAGE);
+ return flushThenExit(exit_codes.USAGE);
}
// TODO(keertip): Add flag to list packages from non default sources
diff --git a/sdk/lib/_internal/pub/lib/src/command/help.dart b/sdk/lib/_internal/pub/lib/src/command/help.dart
index 854d3cd..191be65 100644
--- a/sdk/lib/_internal/pub/lib/src/command/help.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/help.dart
@@ -5,10 +5,10 @@
library pub.command.help;
import 'dart:async';
-import 'dart:io' as io;
import '../command.dart';
import '../exit_codes.dart' as exit_codes;
+import '../io.dart';
import '../log.dart' as log;
/// Handles the `help` pub command.
@@ -26,7 +26,7 @@
if (command == null) {
log.error('Could not find a command named "$name".');
log.error('Run "pub help" to see available commands.');
- io.exit(exit_codes.USAGE);
+ return flushThenExit(exit_codes.USAGE);
}
command.printUsage();
diff --git a/sdk/lib/_internal/pub/lib/src/command/lish.dart b/sdk/lib/_internal/pub/lib/src/command/lish.dart
index fb65fc3..b962f24 100644
--- a/sdk/lib/_internal/pub/lib/src/command/lish.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/lish.dart
@@ -5,7 +5,6 @@
library pub.command.lish;
import 'dart:async';
-import 'dart:io';
import 'package:http/http.dart' as http;
@@ -97,7 +96,7 @@
if (force && dryRun) {
log.error('Cannot use both --force and --dry-run.');
this.printUsage();
- exit(exit_codes.USAGE);
+ return flushThenExit(exit_codes.USAGE);
}
var packageBytesFuture = entrypoint.packageFiles().then((files) {
diff --git a/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart b/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
index f16ad65..30c0fe9 100644
--- a/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
@@ -6,12 +6,12 @@
import 'dart:async';
import 'dart:convert';
-import 'dart:io';
import 'package:path/path.dart' as path;
import '../command.dart';
import '../exit_codes.dart' as exit_codes;
+import '../io.dart';
import '../log.dart' as log;
/// Handles the `list-package-dirs` pub command.
@@ -30,7 +30,7 @@
if (!entrypoint.lockFileExists) {
log.error(JSON.encode(
'Package "myapp" has no lockfile. Please run "pub install" first.'));
- exit(exit_codes.NO_INPUT);
+ return flushThenExit(exit_codes.NO_INPUT);
}
var output = {};
diff --git a/sdk/lib/_internal/pub/lib/src/command/serve.dart b/sdk/lib/_internal/pub/lib/src/command/serve.dart
index d1149bc..3a46f5c 100644
--- a/sdk/lib/_internal/pub/lib/src/command/serve.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/serve.dart
@@ -5,12 +5,13 @@
library pub.command.serve;
import 'dart:async';
-import 'dart:io';
import '../barback.dart' as barback;
+import '../barback/pub_package_provider.dart';
import '../command.dart';
import '../entrypoint.dart';
import '../exit_codes.dart' as exit_codes;
+import '../io.dart';
import '../log.dart' as log;
import '../utils.dart';
@@ -26,17 +27,34 @@
PubPackageProvider _provider;
+ String get hostname => commandOptions['hostname'];
+
ServeCommand() {
commandParser.addOption('port', defaultsTo: '8080',
help: 'The port to listen on.');
+
+ // A hidden option for the tests to work around a bug in some of the OS X
+ // bots where "localhost" very rarely resolves to the IPv4 loopback address
+ // instead of IPv6 (or vice versa). The tests will always set this to
+ // 127.0.0.1.
+ commandParser.addOption('hostname',
+ defaultsTo: 'localhost',
+ hide: true);
}
Future onRun() {
- var port = parsePort();
+ var port;
+ try {
+ port = int.parse(commandOptions['port']);
+ } on FormatException catch (_) {
+ log.error('Could not parse port "${commandOptions['port']}"');
+ this.printUsage();
+ return flushThenExit(exit_codes.USAGE);
+ }
return ensureLockFileIsUpToDate()
.then((_) => entrypoint.loadPackageGraph())
- .then((graph) => barback.createServer("localhost", port, graph))
+ .then((graph) => barback.createServer(hostname, port, graph))
.then((server) {
/// This completer is used to keep pub running (by not completing) and
/// to pipe fatal errors to pub's top-level error-handling machinery.
@@ -77,7 +95,7 @@
});
log.message("Serving ${entrypoint.root.name} "
- "on http://localhost:${server.port}");
+ "on http://$hostname:${server.port}");
return completer.future;
});
@@ -97,15 +115,4 @@
}
});
}
-
- /// Parses the `--port` command-line argument and exits if it isn't valid.
- int parsePort() {
- try {
- return int.parse(commandOptions['port']);
- } on FormatException catch(_) {
- log.error('Could not parse port "${commandOptions['port']}"');
- this.printUsage();
- exit(exit_codes.USAGE);
- }
- }
}
diff --git a/sdk/lib/_internal/pub/lib/src/command/uploader.dart b/sdk/lib/_internal/pub/lib/src/command/uploader.dart
index f3cf290..c3160ee 100644
--- a/sdk/lib/_internal/pub/lib/src/command/uploader.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/uploader.dart
@@ -5,7 +5,6 @@
library pub.command.uploader;
import 'dart:async';
-import 'dart:io';
import 'package:path/path.dart' as path;
@@ -13,6 +12,7 @@
import '../entrypoint.dart';
import '../exit_codes.dart' as exit_codes;
import '../http.dart';
+import '../io.dart';
import '../log.dart' as log;
import '../oauth2.dart' as oauth2;
import '../source/hosted.dart';
@@ -38,7 +38,7 @@
if (commandOptions.rest.isEmpty) {
log.error('No uploader command given.');
this.printUsage();
- exit(exit_codes.USAGE);
+ return flushThenExit(exit_codes.USAGE);
}
var rest = commandOptions.rest.toList();
@@ -47,11 +47,11 @@
if (!['add', 'remove'].contains(command)) {
log.error('Unknown uploader command "$command".');
this.printUsage();
- exit(exit_codes.USAGE);
+ return flushThenExit(exit_codes.USAGE);
} else if (rest.isEmpty) {
log.error('No uploader given for "pub uploader $command".');
this.printUsage();
- exit(exit_codes.USAGE);
+ return flushThenExit(exit_codes.USAGE);
}
return new Future.sync(() {
diff --git a/sdk/lib/_internal/pub/lib/src/dart.dart b/sdk/lib/_internal/pub/lib/src/dart.dart
index b7765b8..f6d8b11 100644
--- a/sdk/lib/_internal/pub/lib/src/dart.dart
+++ b/sdk/lib/_internal/pub/lib/src/dart.dart
@@ -127,15 +127,22 @@
/// Loads a [CrossIsolateException] from a serialized representation.
///
/// [error] should be the result of [CrossIsolateException.serialize].
- CrossIsolateException.deserialize(Object error)
- : type = error['type'],
- message = error['message'],
- stackTrace = error['stack'] == null ? null :
+ factory CrossIsolateException.deserialize(Map error) {
+ var type = error['type'];
+ var message = error['message'];
+ var stackTrace = error['stack'] == null ? null :
new Trace.parse(error['stack']);
+ return new CrossIsolateException._(type, message, stackTrace);
+ }
+
+ /// Loads a [CrossIsolateException] from a serialized representation.
+ ///
+ /// [error] should be the result of [CrossIsolateException.serialize].
+ CrossIsolateException._(this.type, this.message, this.stackTrace);
/// Serializes [error] to an object that can safely be passed across isolate
/// boundaries.
- static Object serialize(error, [StackTrace stack]) {
+ static Map serialize(error, [StackTrace stack]) {
if (stack == null) stack = getAttachedStackTrace(error);
return {
'type': error.runtimeType.toString(),
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 0bd5c14..41a2543 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -150,7 +150,8 @@
/// Creates [file] and writes [contents] to it.
///
/// If [dontLogContents] is true, the contents of the file will never be logged.
-String writeTextFile(String file, String contents, {dontLogContents: false}) {
+String writeTextFile(String file, String contents,
+ {bool dontLogContents: false}) {
// Sanity check: don't spew a huge file.
log.io("Writing ${contents.length} characters to text file $file.");
if (!dontLogContents && contents.length < 1024 * 1024) {
@@ -422,6 +423,15 @@
return stream.fold(null, (x, y) {});
}
+/// Flushes the stdout and stderr streams, then exits the program with the given
+/// status code.
+///
+/// This returns a Future that will never complete, since the program will have
+/// exited already. This is useful to prevent Future chains from proceeding
+/// after you've decided to exit.
+Future flushThenExit(int status) =>
+ Future.wait([stdout.close(), stderr.close()]).then((_) => exit(status));
+
/// Returns a [EventSink] that pipes all data to [consumer] and a [Future] that
/// will succeed when [EventSink] is closed or fail with any errors that occur
/// while writing.
@@ -442,7 +452,7 @@
/// [cancelOnError] and [closeSink] are both true, [sink] will then be
/// closed.
Future store(Stream stream, EventSink sink,
- {bool cancelOnError: true, closeSink: true}) {
+ {bool cancelOnError: true, bool closeSink: true}) {
var completer = new Completer();
stream.listen(sink.add,
onError: (e) {
diff --git a/sdk/lib/_internal/pub/lib/src/oauth2.dart b/sdk/lib/_internal/pub/lib/src/oauth2.dart
index f88c3d6..7146817 100644
--- a/sdk/lib/_internal/pub/lib/src/oauth2.dart
+++ b/sdk/lib/_internal/pub/lib/src/oauth2.dart
@@ -168,9 +168,9 @@
// Spin up a one-shot HTTP server to receive the authorization code from the
// Google OAuth2 server via redirect. This server will close itself as soon as
// the code is received.
- return SafeHttpServer.bind('localhost', 0).then((server) {
+ return SafeHttpServer.bind('127.0.0.1', 0).then((server) {
var authUrl = grant.getAuthorizationUrl(
- Uri.parse('http://localhost:${server.port}'), scopes: _scopes);
+ Uri.parse('http://127.0.0.1:${server.port}'), scopes: _scopes);
log.message(
'Pub needs your authorization to upload packages on your behalf.\n'
diff --git a/sdk/lib/_internal/pub/lib/src/package.dart b/sdk/lib/_internal/pub/lib/src/package.dart
index 63ed342..8945021 100644
--- a/sdk/lib/_internal/pub/lib/src/package.dart
+++ b/sdk/lib/_internal/pub/lib/src/package.dart
@@ -9,7 +9,6 @@
import 'io.dart';
import 'pubspec.dart';
import 'source_registry.dart';
-import 'utils.dart';
import 'version.dart';
final _README_REGEXP = new RegExp(r"^README($|\.)", caseSensitive: false);
@@ -62,7 +61,7 @@
/// `null` if the package being loaded is the entrypoint package.
Package.load(String name, String packageDir, SourceRegistry sources)
: dir = packageDir,
- pubspec = new Pubspec.load(name, packageDir, sources);
+ pubspec = new Pubspec.load(packageDir, sources, expectedName: name);
/// Constructs a package with the given pubspec. The package will have no
/// directory associated with it.
@@ -190,31 +189,3 @@
other.constraint == constraint;
}
}
-
-class PubspecNotFoundException extends ApplicationException {
- final String name;
-
- PubspecNotFoundException(String name)
- : name = name,
- super('Package "$name" doesn\'t have a pubspec.yaml file.');
-}
-
-class PubspecHasNoNameException extends ApplicationException {
- final String name;
-
- PubspecHasNoNameException(String name)
- : name = name,
- super('Package "$name"\'s pubspec.yaml file is missing the '
- 'required "name" field (e.g. "name: $name").');
-}
-
-class PubspecNameMismatchException extends ApplicationException {
- final String expectedName;
- final String actualName;
-
- PubspecNameMismatchException(String expectedName, String actualName)
- : expectedName = expectedName,
- actualName = actualName,
- super('The name you specified for your dependency, "$expectedName", '
- 'doesn\'t match the name "$actualName" in its pubspec.');
-}
diff --git a/sdk/lib/_internal/pub/lib/src/pubspec.dart b/sdk/lib/_internal/pub/lib/src/pubspec.dart
index 0813315..a8d1195 100644
--- a/sdk/lib/_internal/pub/lib/src/pubspec.dart
+++ b/sdk/lib/_internal/pub/lib/src/pubspec.dart
@@ -4,7 +4,6 @@
library pub.pubspec;
-import 'package:barback/barback.dart';
import 'package:yaml/yaml.dart';
import 'package:path/path.dart' as path;
@@ -16,373 +15,423 @@
import 'utils.dart';
import 'version.dart';
-/// The parsed and validated contents of a pubspec file.
+/// The parsed contents of a pubspec file.
+///
+/// The fields of a pubspec are, for the most part, validated when they're first
+/// accessed. This allows a partially-invalid pubspec to be used if only the
+/// valid portions are relevant. To get a list of all errors in the pubspec, use
+/// [allErrors].
class Pubspec {
- /// This package's name.
- final String name;
+ // If a new lazily-initialized field is added to this class and the
+ // initialization can throw a [PubspecError], that error should also be
+ // exposed through [allErrors].
- /// This package's version.
- final Version version;
+ /// The registry of sources to use when parsing [dependencies] and
+ /// [devDependencies].
+ ///
+ /// This will be null if this was created using [new Pubspec] or [new
+ /// Pubspec.empty].
+ final SourceRegistry _sources;
- /// The packages this package depends on.
- final List<PackageDep> dependencies;
-
- /// The packages this package depends on when it is the root package.
- final List<PackageDep> devDependencies;
-
- /// The ids of the transformers to use for this package.
- final List<Set<TransformerId>> transformers;
-
- /// The environment-related metadata.
- final PubspecEnvironment environment;
+ /// The location from which the pubspec was loaded.
+ ///
+ /// This can be null if the pubspec was created in-memory or if its location
+ /// is unknown or can't be represented by a Uri.
+ final Uri _location;
/// All pubspec fields. This includes the fields from which other properties
/// are derived.
- final Map<String, Object> fields;
+ final Map fields;
- /// Loads the pubspec for a package [name] located in [packageDir].
- factory Pubspec.load(String name, String packageDir, SourceRegistry sources) {
- var pubspecPath = path.join(packageDir, 'pubspec.yaml');
- if (!fileExists(pubspecPath)) throw new PubspecNotFoundException(name);
+ /// The package's name.
+ String get name {
+ if (_name != null) return _name;
- try {
- var pubspec = new Pubspec.parse(pubspecPath, readTextFile(pubspecPath),
- sources);
-
- if (pubspec.name == null) {
- throw new PubspecHasNoNameException(name);
- }
-
- if (name != null && pubspec.name != name) {
- throw new PubspecNameMismatchException(name, pubspec.name);
- }
-
- return pubspec;
- } on FormatException catch (ex) {
- fail('Could not parse $pubspecPath:\n${ex.message}');
+ var name = fields['name'];
+ if (name == null) {
+ throw new PubspecException(null, _location,
+ 'Missing the required "name" field.');
+ } else if (name is! String) {
+ throw new PubspecException(null, _location,
+ '"name" field must be a string, but was "$name".');
}
+
+ _name = name;
+ return _name;
}
+ String _name;
- Pubspec(this.name, this.version, this.dependencies, this.devDependencies,
- this.environment, this.transformers, [Map<String, Object> fields])
- : this.fields = fields == null ? {} : fields;
+ /// The package's version.
+ Version get version {
+ if (_version != null) return _version;
- Pubspec.empty()
- : name = null,
- version = Version.none,
- dependencies = <PackageDep>[],
- devDependencies = <PackageDep>[],
- environment = new PubspecEnvironment(),
- transformers = <Set<TransformerId>>[],
- fields = {};
+ var version = fields['version'];
+ if (version == null) {
+ _version = Version.none;
+ return _version;
+ }
+ if (version is! String) {
+ _error('"version" field must be a string, but was "$version".');
+ }
+
+ _version = _wrapFormatException('version number', 'version',
+ () => new Version.parse(version));
+ return _version;
+ }
+ Version _version;
+
+ /// The additional packages this package depends on.
+ List<PackageDep> get dependencies {
+ if (_dependencies != null) return _dependencies;
+ _dependencies = _parseDependencies('dependencies');
+ if (_devDependencies == null) {
+ _checkDependencyOverlap(_dependencies, devDependencies);
+ }
+ return _dependencies;
+ }
+ List<PackageDep> _dependencies;
+
+ /// The packages this package depends on when it is the root package.
+ List<PackageDep> get devDependencies {
+ if (_devDependencies != null) return _devDependencies;
+ _devDependencies = _parseDependencies('dev_dependencies');
+ if (_dependencies == null) {
+ _checkDependencyOverlap(dependencies, _devDependencies);
+ }
+ return _devDependencies;
+ }
+ List<PackageDep> _devDependencies;
+
+ /// The ids of the transformers to use for this package.
+ List<Set<TransformerId>> get transformers {
+ if (_transformers != null) return _transformers;
+
+ var transformers = fields['transformers'];
+ if (transformers == null) {
+ _transformers = [];
+ return _transformers;
+ }
+
+ if (transformers is! List) {
+ _error('"transformers" field must be a list, but was "$transformers".');
+ }
+
+ var i = 0;
+ _transformers = transformers.map((phase) {
+ var field = "transformers";
+ if (phase is! List) {
+ phase = [phase];
+ } else {
+ field = "$field[${i++}]";
+ }
+
+ return phase.map((transformer) {
+ if (transformer is! String && transformer is! Map) {
+ _error('"$field" field must be a string or map, but was '
+ '"$transformer".');
+ }
+
+ var id;
+ var configuration;
+ if (transformer is String) {
+ id = _wrapFormatException('library identifier', field,
+ () => libraryIdentifierToId(transformer));
+ } else {
+ if (transformer.length != 1) {
+ _error('"$field" must have a single key: the library identifier.');
+ } else if (transformer.keys.single is! String) {
+ _error('"$field" library identifier must be a string, but was '
+ '"$id".');
+ }
+
+ id = _wrapFormatException('library identifier', field,
+ () => libraryIdentifierToId(transformer.keys.single));
+ configuration = transformer.values.single;
+ if (configuration is! Map) {
+ _error('"$field.${idToLibraryIdentifier(id)}" field must be a map, '
+ 'but was "$configuration".');
+ }
+ }
+
+ if (id.package != name &&
+ !dependencies.any((ref) => ref.name == id.package)) {
+ _error('"$field.${idToLibraryIdentifier(id)}" refers to a package '
+ 'that\'s not listed in "dependencies".');
+ }
+
+ return _wrapFormatException("transformer identifier",
+ "$field.${idToLibraryIdentifier(id)}",
+ () => new TransformerId(id, configuration));
+ }).toSet();
+ }).toList();
+ return _transformers;
+ }
+ List<Set<TransformerId>> _transformers;
+
+ /// The environment-related metadata.
+ PubspecEnvironment get environment {
+ if (_environment != null) return _environment;
+
+ var yaml = fields['environment'];
+ if (yaml == null) {
+ _environment = new PubspecEnvironment(VersionConstraint.any);
+ return _environment;
+ }
+
+ if (yaml is! Map) {
+ _error('"environment" field must be a map, but was "$yaml".');
+ }
+
+ _environment = new PubspecEnvironment(
+ _parseVersionConstraint(yaml['sdk'], 'environment.sdk'));
+ return _environment;
+ }
+ PubspecEnvironment _environment;
/// Whether or not the pubspec has no contents.
bool get isEmpty =>
name == null && version == Version.none && dependencies.isEmpty;
+ /// Loads the pubspec for a package located in [packageDir].
+ ///
+ /// If [expectedName] is passed and the pubspec doesn't have a matching name
+ /// field, this will throw a [PubspecError].
+ factory Pubspec.load(String packageDir, SourceRegistry sources,
+ {String expectedName}) {
+ var pubspecPath = path.join(packageDir, 'pubspec.yaml');
+ var pubspecUri = path.toUri(pubspecPath);
+ if (!fileExists(pubspecPath)) {
+ throw new PubspecException(expectedName, pubspecUri,
+ 'Could not find a file named "pubspec.yaml" in "$packageDir".');
+ }
+
+ return new Pubspec.parse(readTextFile(pubspecPath), sources,
+ expectedName: expectedName, location: pubspecUri);
+ }
+
+ Pubspec(this._name, this._version, this._dependencies, this._devDependencies,
+ this._environment, this._transformers, [Map fields])
+ : this.fields = fields == null ? {} : fields,
+ _sources = null,
+ _location = null;
+
+ Pubspec.empty()
+ : _sources = null,
+ _location = null,
+ _name = null,
+ _version = Version.none,
+ _dependencies = <PackageDep>[],
+ _devDependencies = <PackageDep>[],
+ _environment = new PubspecEnvironment(),
+ _transformers = <Set<TransformerId>>[],
+ fields = {};
+
/// Returns a Pubspec object for an already-parsed map representing its
/// contents.
///
- /// This will validate that [contents] is a valid pubspec.
- factory Pubspec.fromMap(Map contents, SourceRegistry sources) =>
- _parseMap(null, contents, sources);
+ /// If [expectedName] is passed and the pubspec doesn't have a matching name
+ /// field, this will throw a [PubspecError].
+ ///
+ /// [location] is the location from which this pubspec was loaded.
+ Pubspec.fromMap(this.fields, this._sources, {String expectedName,
+ Uri location})
+ : _location = location {
+ if (expectedName == null) return;
- // TODO(rnystrom): Instead of allowing a null argument here, split this up
- // into load(), parse(), and _parse() like LockFile does.
+ // If [expectedName] is passed, ensure that the actual 'name' field exists
+ // and matches the expectation.
+
+ // If the 'name' field doesn't exist, manually throw an exception rather
+ // than relying on the exception thrown by [name] so that we can provide a
+ // suggested fix.
+ if (fields['name'] == null) {
+ throw new PubspecException(expectedName, _location,
+ 'Missing the required "name" field (e.g. "name: $expectedName").');
+ }
+
+ try {
+ if (name == expectedName) return;
+ throw new PubspecException(expectedName, _location,
+ '"name" field "$name" doesn\'t match expected name '
+ '"$expectedName".');
+ } on PubspecException catch (e) {
+ // Catch and re-throw any exceptions thrown by [name] so that they refer
+ // to [expectedName] for additional context.
+ throw new PubspecException(expectedName, e.location,
+ split1(e.message, '\n').last);
+ }
+ }
+
/// Parses the pubspec stored at [filePath] whose text is [contents]. If the
/// pubspec doesn't define version for itself, it defaults to [Version.none].
/// [filePath] may be `null` if the pubspec is not on the user's local
/// file system.
- factory Pubspec.parse(String filePath, String contents,
- SourceRegistry sources) {
+ factory Pubspec.parse(String contents, SourceRegistry sources,
+ {String expectedName, Uri location}) {
if (contents.trim() == '') return new Pubspec.empty();
var parsedPubspec = loadYaml(contents);
if (parsedPubspec == null) return new Pubspec.empty();
if (parsedPubspec is! Map) {
- throw new FormatException('The pubspec must be a YAML mapping.');
+ throw new PubspecException(expectedName, location,
+ 'The pubspec must be a YAML mapping.');
}
- return _parseMap(filePath, parsedPubspec, sources);
- }
-}
-
-/// Evaluates whether the given [url] for [field] is valid.
-///
-/// Throws [FormatException] on an invalid url.
-void _validateFieldUrl(url, String field) {
- if (url is! String) {
- throw new FormatException(
- 'The "$field" field should be a string, but was "$url".');
+ return new Pubspec.fromMap(parsedPubspec, sources,
+ expectedName: expectedName, location: location);
}
- var goodScheme = new RegExp(r'^https?:');
- if (!goodScheme.hasMatch(url)) {
- throw new FormatException(
- 'The "$field" field should be an "http:" or "https:" URL, but '
- 'was "$url".');
- }
-}
-
-Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) {
- var name = null;
-
- if (map.containsKey('name')) {
- name = map['name'];
- if (name is! String) {
- throw new FormatException(
- 'The pubspec "name" field should be a string, but was "$name".');
+ /// Returns a list of most errors in this pubspec.
+ ///
+ /// This will return at most one error for each field.
+ List<PubspecException> get allErrors {
+ var errors = <PubspecException>[];
+ _getError(fn()) {
+ try {
+ fn();
+ } on PubspecException catch (e) {
+ errors.add(e);
+ }
}
+
+ _getError(() => this.name);
+ _getError(() => this.version);
+ _getError(() => this.dependencies);
+ _getError(() => this.devDependencies);
+ _getError(() => this.transformers);
+ _getError(() => this.environment);
+ return errors;
}
- var version = _parseVersion(map['version'], (v) =>
- 'The pubspec "version" field should be a semantic version number, '
- 'but was "$v".');
+ /// Parses the dependency field named [field], and returns the corresponding
+ /// list of dependencies.
+ List<PackageDep> _parseDependencies(String field) {
+ var dependencies = <PackageDep>[];
- var dependencies = _parseDependencies(name, filePath, sources,
- map['dependencies']);
+ var yaml = fields[field];
+ // Allow an empty dependencies key.
+ if (yaml == null) return dependencies;
- var devDependencies = _parseDependencies(name, filePath, sources,
- map['dev_dependencies']);
+ if (yaml is! Map || yaml.keys.any((e) => e is! String)) {
+ _error('"$field" field should be a map of package names, but was '
+ '"$yaml".');
+ }
+
+ yaml.forEach((name, spec) {
+ if (fields['name'] != null && name == this.name) {
+ _error('"$field.$name": Package may not list itself as a '
+ 'dependency.');
+ }
+
+ var description;
+ var sourceName;
+
+ var versionConstraint = new VersionRange();
+ if (spec == null) {
+ description = name;
+ sourceName = _sources.defaultSource.name;
+ } else if (spec is String) {
+ description = name;
+ sourceName = _sources.defaultSource.name;
+ versionConstraint = _parseVersionConstraint(spec, "$field.$name");
+ } else if (spec is Map) {
+ if (spec.containsKey('version')) {
+ versionConstraint = _parseVersionConstraint(spec.remove('version'),
+ "$field.$name.version");
+ }
+
+ var sourceNames = spec.keys.toList();
+ if (sourceNames.length > 1) {
+ _error('"$field.$name" field may only have one source, but it had '
+ '${toSentence(sourceNames)}.');
+ }
+
+ sourceName = sourceNames.single;
+ if (sourceName is! String) {
+ _error('"$field.$name" source name must be a string, but was '
+ '"$sourceName".');
+ }
+
+ description = spec[sourceName];
+ } else {
+ _error('"$field.$name" field must be a string or a mapping.');
+ }
+
+ // If we have a valid source, use it to process the description. Allow
+ // unknown sources so pub doesn't choke on old pubspecs.
+ if (_sources.contains(sourceName)) {
+ var descriptionField = "$field.$name";
+ if (spec is Map) descriptionField = "$descriptionField.$sourceName";
+ _wrapFormatException('description', descriptionField, () {
+ var pubspecPath;
+ if (_location != null && _isFileUri(_location)) {
+ pubspecPath = path.fromUri(_location);
+ }
+ description = _sources[sourceName].parseDescription(
+ pubspecPath, description, fromLockFile: false);
+ });
+ }
+
+ dependencies.add(new PackageDep(
+ name, sourceName, versionConstraint, description));
+ });
+
+ return dependencies;
+ }
+
+ /// Parses [yaml] to a [VersionConstraint].
+ ///
+ /// If [yaml] is `null`, returns [VersionConstraint.any].
+ VersionConstraint _parseVersionConstraint(yaml, String field) {
+ if (yaml == null) return VersionConstraint.any;
+ if (yaml is! String) {
+ _error('"$field" must be a string, but was "$yaml".');
+ }
+
+ return _wrapFormatException('version constraint', field,
+ () => new VersionConstraint.parse(yaml));
+ }
// Make sure the same package doesn't appear as both a regular and dev
// dependency.
- var dependencyNames = dependencies.map((dep) => dep.name).toSet();
- var collisions = dependencyNames.intersection(
- devDependencies.map((dep) => dep.name).toSet());
+ void _checkDependencyOverlap(List<PackageDep> dependencies,
+ List<PackageDep> devDependencies) {
+ var dependencyNames = dependencies.map((dep) => dep.name).toSet();
+ var collisions = dependencyNames.intersection(
+ devDependencies.map((dep) => dep.name).toSet());
+ if (collisions.isEmpty) return;
- if (!collisions.isEmpty) {
- var packageNames;
- if (collisions.length == 1) {
- packageNames = 'Package "${collisions.first}"';
- } else {
- var names = ordered(collisions);
- var buffer = new StringBuffer();
- buffer.write("Packages ");
- for (var i = 0; i < names.length; i++) {
- buffer.write('"');
- buffer.write(names[i]);
- buffer.write('"');
- if (i == names.length - 2) {
- buffer.write(", ");
- } else if (i == names.length - 1) {
- buffer.write(", and ");
- }
- }
-
- packageNames = buffer.toString();
- }
-
- throw new FormatException(
- '$packageNames cannot appear in both "dependencies" and '
- '"dev_dependencies".');
+ _error('${pluralize('Package', collisions.length)} '
+ '${toSentence(collisions.map((package) => '"$package"'))} cannot '
+ 'appear in both "dependencies" and "dev_dependencies".');
}
- var transformers = map['transformers'];
- if (transformers != null) {
- if (transformers is! List) {
- throw new FormatException('"transformers" field must be a list, but was '
- '"$transformers".');
- }
-
- transformers = transformers.map((phase) {
- if (phase is! List) phase = [phase];
- return phase.map((transformer) {
- if (transformer is! String && transformer is! Map) {
- throw new FormatException(
- 'Transformer "$transformer" must be a string or map.');
- }
-
- var id;
- var configuration;
- if (transformer is String) {
- id = libraryIdentifierToId(transformer);
- } else {
- if (transformer.length != 1) {
- throw new FormatException('Transformer map "$transformer" must '
- 'have a single key: the library identifier.');
- }
-
- id = libraryIdentifierToId(transformer.keys.single);
- configuration = transformer.values.single;
- if (configuration is! Map) {
- throw new FormatException('Configuration for transformer "$id" '
- 'must be a map, but was "$configuration".');
- }
- }
-
- if (id.package != name &&
- !dependencies.any((ref) => ref.name == id.package)) {
- throw new FormatException('Could not find package for transformer '
- '"$transformer".');
- }
-
- return new TransformerId(id, configuration);
- }).toSet();
- }).toList();
- } else {
- transformers = [];
- }
-
- var environmentYaml = map['environment'];
- var sdkConstraint = VersionConstraint.any;
- if (environmentYaml != null) {
- if (environmentYaml is! Map) {
- throw new FormatException(
- 'The pubspec "environment" field should be a map, but was '
- '"$environmentYaml".');
- }
-
- sdkConstraint = _parseVersionConstraint(environmentYaml['sdk'], (v) =>
- 'The "sdk" field of "environment" should be a semantic version '
- 'constraint, but was "$v".');
- }
- var environment = new PubspecEnvironment(sdkConstraint);
-
- // Even though the pub app itself doesn't use these fields, we validate
- // them here so that users find errors early before they try to upload to
- // the server:
- // TODO(rnystrom): We should split this validation into separate layers:
- // 1. Stuff that is required in any pubspec to perform any command. Things
- // like "must have a name". That should go here.
- // 2. Stuff that is required to upload a package. Things like "homepage
- // must use a valid scheme". That should go elsewhere. pub upload should
- // call it, and we should provide a separate command to show the user,
- // and also expose it to the editor in some way.
-
- if (map.containsKey('homepage')) {
- _validateFieldUrl(map['homepage'], 'homepage');
- }
- if (map.containsKey('documentation')) {
- _validateFieldUrl(map['documentation'], 'documentation');
- }
-
- if (map.containsKey('author') && map['author'] is! String) {
- throw new FormatException(
- 'The "author" field should be a string, but was '
- '${map["author"]}.');
- }
-
- if (map.containsKey('authors')) {
- var authors = map['authors'];
- if (authors is List) {
- // All of the elements must be strings.
- if (!authors.every((author) => author is String)) {
- throw new FormatException('The "authors" field should be a string '
- 'or a list of strings, but was "$authors".');
- }
- } else if (authors is! String) {
- throw new FormatException('The pubspec "authors" field should be a '
- 'string or a list of strings, but was "$authors".');
- }
-
- if (map.containsKey('author')) {
- throw new FormatException('A pubspec should not have both an "author" '
- 'and an "authors" field.');
+ /// Runs [fn] and wraps any [FormatException] it throws in a
+ /// [PubspecException].
+ ///
+ /// [description] should be a noun phrase that describes whatever's being
+ /// parsed or processed by [fn]. [field] should be the location of whatever's
+ /// being processed within the pubspec.
+ _wrapFormatException(String description, String field, fn()) {
+ try {
+ return fn();
+ } on FormatException catch (e) {
+ _error('Invalid $description for "$field": ${e.message}');
}
}
- return new Pubspec(name, version, dependencies, devDependencies,
- environment, transformers, map);
-}
-
-/// Parses [yaml] to a [Version] or throws a [FormatException] with the result
-/// of calling [message] if it isn't valid.
-///
-/// If [yaml] is `null`, returns [Version.none].
-Version _parseVersion(yaml, String message(yaml)) {
- if (yaml == null) return Version.none;
- if (yaml is! String) throw new FormatException(message(yaml));
-
- try {
- return new Version.parse(yaml);
- } on FormatException catch(_) {
- throw new FormatException(message(yaml));
- }
-}
-
-/// Parses [yaml] to a [VersionConstraint] or throws a [FormatException] with
-/// the result of calling [message] if it isn't valid.
-///
-/// If [yaml] is `null`, returns [VersionConstraint.any].
-VersionConstraint _parseVersionConstraint(yaml, String getMessage(yaml)) {
- if (yaml == null) return VersionConstraint.any;
- if (yaml is! String) throw new FormatException(getMessage(yaml));
-
- try {
- return new VersionConstraint.parse(yaml);
- } on FormatException catch(_) {
- throw new FormatException(getMessage(yaml));
- }
-}
-
-List<PackageDep> _parseDependencies(String packageName, String pubspecPath,
- SourceRegistry sources, yaml) {
- var dependencies = <PackageDep>[];
-
- // Allow an empty dependencies key.
- if (yaml == null) return dependencies;
-
- if (yaml is! Map || yaml.keys.any((e) => e is! String)) {
- throw new FormatException(
- 'The pubspec dependencies should be a map of package names, but '
- 'was ${yaml}.');
- }
-
- yaml.forEach((name, spec) {
- if (name == packageName) {
- throw new FormatException("Package '$name' cannot depend on itself.");
+ /// Throws a [PubspecException] with the given message.
+ void _error(String message) {
+ var name;
+ try {
+ name = this.name;
+ } on PubspecException catch (_) {
+ // [name] is null.
}
- var description;
- var sourceName;
-
- var versionConstraint = new VersionRange();
- if (spec == null) {
- description = name;
- sourceName = sources.defaultSource.name;
- } else if (spec is String) {
- description = name;
- sourceName = sources.defaultSource.name;
- versionConstraint = new VersionConstraint.parse(spec);
- } else if (spec is Map) {
- if (spec.containsKey('version')) {
- versionConstraint = _parseVersionConstraint(spec.remove('version'),
- (v) => 'The "version" field for $name should be a semantic '
- 'version constraint, but was "$v".');
- }
-
- var sourceNames = spec.keys.toList();
- if (sourceNames.length > 1) {
- throw new FormatException(
- 'Dependency $name may only have one source: $sourceNames.');
- }
-
- sourceName = only(sourceNames);
- if (sourceName is! String) {
- throw new FormatException(
- 'Source name $sourceName should be a string.');
- }
-
- description = spec[sourceName];
- } else {
- throw new FormatException(
- 'Dependency specification $spec should be a string or a mapping.');
- }
-
- // If we have a valid source, use it to process the description. Allow
- // unknown sources so pub doesn't choke on old pubspecs.
- if (sources.contains(sourceName)) {
- description = sources[sourceName].parseDescription(
- pubspecPath, description, fromLockFile: false);
- }
-
- dependencies.add(new PackageDep(
- name, sourceName, versionConstraint, description));
- });
-
- return dependencies;
+ throw new PubspecException(name, _location, message);
+ }
}
/// The environment-related metadata in the pubspec. Corresponds to the data
@@ -395,3 +444,54 @@
PubspecEnvironment([VersionConstraint sdk])
: sdkVersion = sdk != null ? sdk : VersionConstraint.any;
}
+
+/// An exception thrown when parsing a pubspec.
+///
+/// These exceptions are often thrown lazily while accessing pubspec properties.
+/// Their string representation contains additional contextual information about
+/// the pubspec for which parsing failed.
+class PubspecException extends ApplicationException {
+ /// The name of the package that the pubspec is for.
+ ///
+ /// This can be null if the pubspec didn't specify a name and no external name
+ /// was provided.
+ final String name;
+
+ /// The location of the pubspec.
+ ///
+ /// This can be null if the pubspec has no physical location, or if the
+ /// location is unknown.
+ final Uri location;
+
+ PubspecException(String name, Uri location, String subMessage)
+ : this.name = name,
+ this.location = location,
+ super(_computeMessage(name, location, subMessage));
+
+ static String _computeMessage(String name, Uri location, String subMessage) {
+ var str = 'Error in';
+
+ if (name != null) {
+ str += ' pubspec for package "$name"';
+ if (location != null) str += ' loaded from';
+ } else if (location == null) {
+ str += ' pubspec for an unknown package';
+ }
+
+ if (location != null) {
+ if (_isFileUri(location)) {
+ str += ' ${nicePath(path.fromUri(location))}';
+ } else {
+ str += ' $location';
+ }
+ }
+
+ return "$str:\n$subMessage";
+ }
+}
+
+/// Returns whether [uri] is a file URI.
+///
+/// This is slightly more complicated than just checking if the scheme is
+/// 'file', since relative URIs also refer to the filesystem on the VM.
+bool _isFileUri(Uri uri) => uri.scheme == 'file' || uri.scheme == '';
diff --git a/sdk/lib/_internal/pub/lib/src/safe_http_server.dart b/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
index f5f57cf..63b7705 100644
--- a/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
+++ b/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
@@ -39,6 +39,16 @@
_inner.sessionTimeout = timeout;
}
+ String get serverHeader => _inner.serverHeader;
+ set serverHeader(String value) {
+ _inner.serverHeader = value;
+ }
+
+ Duration get idleTimeout => _inner.idleTimeout;
+ set idleTimeout(Duration value) {
+ _inner.idleTimeout = value;
+ }
+
HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
@@ -139,4 +149,12 @@
void writeCharCode(int charCode) => _inner.writeCharCode(charCode);
void writeln([Object obj = ""]) => _inner.writeln(obj);
void addError(error) => _inner.addError(error);
+
+ Duration get deadline => _inner.deadline;
+ set deadline(Duration value) {
+ _inner.deadline = value;
+ }
+
+ Future redirect(Uri location, {int status: HttpStatus.MOVED_TEMPORARILY}) =>
+ _inner.redirect(location, status: status);
}
diff --git a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
index e03d960..06e328f 100644
--- a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
+++ b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
@@ -41,7 +41,6 @@
import '../package.dart';
import '../pubspec.dart';
import '../sdk.dart' as sdk;
-import '../source.dart';
import '../source_registry.dart';
import '../utils.dart';
import '../version.dart';
diff --git a/sdk/lib/_internal/pub/lib/src/solver/version_solver.dart b/sdk/lib/_internal/pub/lib/src/solver/version_solver.dart
index 09d5fbf..cf47da2 100644
--- a/sdk/lib/_internal/pub/lib/src/solver/version_solver.dart
+++ b/sdk/lib/_internal/pub/lib/src/solver/version_solver.dart
@@ -11,7 +11,6 @@
import '../log.dart' as log;
import '../package.dart';
import '../pubspec.dart';
-import '../source.dart';
import '../source_registry.dart';
import '../version.dart';
import '../utils.dart';
@@ -275,7 +274,7 @@
: super(package, dependencies);
String toString() {
- var dep = only(dependencies);
+ var dep = dependencies.single;
return "Package '${dep.depender}' depends on '${dep.dep.name}' from "
"unknown source '${dep.dep.source}'.";
}
diff --git a/sdk/lib/_internal/pub/lib/src/source.dart b/sdk/lib/_internal/pub/lib/src/source.dart
index 99f12ab..a746676 100644
--- a/sdk/lib/_internal/pub/lib/src/source.dart
+++ b/sdk/lib/_internal/pub/lib/src/source.dart
@@ -95,7 +95,8 @@
return describeUncached(id);
}
- return new Pubspec.load(id.name, packageDir, _systemCache.sources);
+ return new Pubspec.load(packageDir, _systemCache.sources,
+ expectedName: id.name);
});
}
diff --git a/sdk/lib/_internal/pub/lib/src/source/hosted.dart b/sdk/lib/_internal/pub/lib/src/source/hosted.dart
index b2c1647..af110e6 100644
--- a/sdk/lib/_internal/pub/lib/src/source/hosted.dart
+++ b/sdk/lib/_internal/pub/lib/src/source/hosted.dart
@@ -71,7 +71,8 @@
// a secondary cache of just pubspecs. This would let us have a
// persistent cache for pubspecs for packages that haven't actually
// been installed.
- return new Pubspec.fromMap(version['pubspec'], systemCache.sources);
+ return new Pubspec.fromMap(version['pubspec'], systemCache.sources,
+ expectedName: id.name, location: url);
}).catchError((ex) {
var parsed = _parseDescription(id.description);
_throwFriendlyError(ex, id, parsed.last);
diff --git a/sdk/lib/_internal/pub/lib/src/source/path.dart b/sdk/lib/_internal/pub/lib/src/source/path.dart
index d007f2e..a9a88d8 100644
--- a/sdk/lib/_internal/pub/lib/src/source/path.dart
+++ b/sdk/lib/_internal/pub/lib/src/source/path.dart
@@ -22,8 +22,8 @@
Future<Pubspec> describeUncached(PackageId id) {
return new Future.sync(() {
_validatePath(id.name, id.description);
- return new Pubspec.load(id.name, id.description["path"],
- systemCache.sources);
+ return new Pubspec.load(id.description["path"], systemCache.sources,
+ expectedName: id.name);
});
}
diff --git a/sdk/lib/_internal/pub/lib/src/utils.dart b/sdk/lib/_internal/pub/lib/src/utils.dart
index acca0bb..55529ea 100644
--- a/sdk/lib/_internal/pub/lib/src/utils.dart
+++ b/sdk/lib/_internal/pub/lib/src/utils.dart
@@ -6,9 +6,10 @@
library pub.utils;
import 'dart:async';
-import 'dart:io';
import "dart:collection";
import "dart:convert";
+import 'dart:io';
+import 'dart:isolate';
import 'dart:mirrors';
import "package:analyzer_experimental/analyzer.dart";
@@ -101,6 +102,16 @@
return iter.take(iter.length - 1).join(", ") + " and ${iter.last}";
}
+/// Returns [name] if [number] is 1, or the plural of [name] otherwise.
+///
+/// By default, this just adds "s" to the end of [name] to get the plural. If
+/// [plural] is passed, that's used instead.
+String pluralize(String name, int number, {String plural}) {
+ if (number == 1) return name;
+ if (plural != null) return plural;
+ return '${name}s';
+}
+
/// Flattens nested lists inside an iterable into a single list containing only
/// non-list elements.
List flatten(Iterable nested) {
@@ -118,16 +129,6 @@
return result;
}
-/// Asserts that [iter] contains only one element, and returns it.
-only(Iterable iter) {
- var iterator = iter.iterator;
- var currentIsValid = iterator.moveNext();
- assert(currentIsValid);
- var obj = iterator.current;
- assert(!iterator.moveNext());
- return obj;
-}
-
/// Returns a set containing all elements in [minuend] that are not in
/// [subtrahend].
Set setMinus(Iterable minuend, Iterable subtrahend) {
@@ -506,6 +507,20 @@
return uri;
}
+/// Returns a human-friendly representation of [inputPath].
+///
+/// If [inputPath] isn't too distant from the current working directory, this
+/// will return the relative path to it. Otherwise, it will return the absolute
+/// path.
+String nicePath(String inputPath) {
+ var relative = path.relative(inputPath);
+ var split = path.split(relative);
+ if (split.length > 1 && split[0] == '..' && split[1] == '..') {
+ return path.absolute(inputPath);
+ }
+ return relative;
+}
+
/// Decodes a URL-encoded string. Unlike [Uri.decodeComponent], this includes
/// replacing `+` with ` `.
String urlDecode(String encoded) =>
diff --git a/sdk/lib/_internal/pub/lib/src/validator/pubspec_field.dart b/sdk/lib/_internal/pub/lib/src/validator/pubspec_field.dart
index e9d2d35..7ff8ec7 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/pubspec_field.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/pubspec_field.dart
@@ -16,44 +16,91 @@
: super(entrypoint);
Future validate() {
- // The types of all fields are validated when the pubspec is parsed.
+ _validateAuthors();
+ _validateFieldIsString('description');
+ _validateFieldIsString('homepage');
+ _validateFieldUrl('homepage');
+ _validateFieldUrl('documentation');
+
+ // Any complex parsing errors in version will be exposed through
+ // [Pubspec.allErrors].
+ _validateFieldIsString('version');
+
+ // Pubspec errors are detected lazily, so we make sure there aren't any
+ // here.
+ for (var error in entrypoint.root.pubspec.allErrors) {
+ errors.add('In your pubspec.yaml, ${error.message}');
+ }
+
+ return new Future.value();
+ }
+
+ /// Adds an error if the "author" or "authors" field doesn't exist or has the
+ /// wrong type.
+ void _validateAuthors() {
var pubspec = entrypoint.root.pubspec;
var author = pubspec.fields['author'];
var authors = pubspec.fields['authors'];
if (author == null && authors == null) {
errors.add('Your pubspec.yaml must have an "author" or "authors" field.');
- } else {
- if (authors == null) authors = [author];
+ return;
+ }
- var hasName = new RegExp(r"^ *[^< ]");
- var hasEmail = new RegExp(r"<[^>]+> *$");
- for (var authorName in authors) {
- if (!hasName.hasMatch(authorName)) {
- warnings.add('Author "$authorName" in pubspec.yaml should have a '
- 'name.');
- }
- if (!hasEmail.hasMatch(authorName)) {
- warnings.add('Author "$authorName" in pubspec.yaml should have an '
- 'email address\n(e.g. "name <email>").');
- }
+ if (author != null && author is! String) {
+ errors.add('Your pubspec.yaml\'s "author" field must be a string, but it '
+ 'was "$author".');
+ return;
+ }
+
+ if (authors != null &&
+ (authors is! List || authors.any((author) => author is! String))) {
+ errors.add('Your pubspec.yaml\'s "authors" field must be a string, but '
+ 'it was "$authors".');
+ return;
+ }
+
+ if (authors == null) authors = [author];
+
+ var hasName = new RegExp(r"^ *[^< ]");
+ var hasEmail = new RegExp(r"<[^>]+> *$");
+ for (var authorName in authors) {
+ if (!hasName.hasMatch(authorName)) {
+ warnings.add('Author "$authorName" in pubspec.yaml should have a '
+ 'name.');
+ }
+ if (!hasEmail.hasMatch(authorName)) {
+ warnings.add('Author "$authorName" in pubspec.yaml should have an '
+ 'email address\n(e.g. "name <email>").');
}
}
+ }
- var homepage = pubspec.fields['homepage'];
- if (homepage == null) {
- errors.add('Your pubspec.yaml is missing a "homepage" field.');
+ /// Adds an error if [field] doesn't exist or isn't a string.
+ void _validateFieldIsString(String field) {
+ var value = entrypoint.root.pubspec.fields[field];
+ if (value == null) {
+ errors.add('Your pubspec.yaml is missing a "$field" field.');
+ } else if (value is! String) {
+ errors.add('Your pubspec.yaml\'s "$field" field must be a string, but '
+ 'it was "$value".');
+ }
+ }
+
+ /// Adds an error if the URL for [field] is invalid.
+ void _validateFieldUrl(String field) {
+ var url = entrypoint.root.pubspec.fields[field];
+ if (url == null) return;
+
+ if (url is! String) {
+ errors.add('Your pubspec.yaml\'s "$field" field must be a string, but '
+ 'it was "$url".');
+ return;
}
- var description = pubspec.fields['description'];
- if (description == null) {
- errors.add('Your pubspec.yaml is missing a "description" field.');
+ var goodScheme = new RegExp(r'^https?:');
+ if (!goodScheme.hasMatch(url)) {
+ errors.add('Your pubspec.yaml\'s "$field" field must be an "http:" or '
+ '"https:" URL, but it was "$url".');
}
-
- var version = pubspec.fields['version'];
- if (version == null) {
- errors.add('Your pubspec.yaml is missing a "version" field.');
- }
-
- return new Future.value();
}
}
diff --git a/sdk/lib/_internal/pub/lib/src/version.dart b/sdk/lib/_internal/pub/lib/src/version.dart
index 0d25c73..969d268 100644
--- a/sdk/lib/_internal/pub/lib/src/version.dart
+++ b/sdk/lib/_internal/pub/lib/src/version.dart
@@ -172,8 +172,8 @@
if (aPart == null) return -1;
if (bPart == null) return 1;
- if (aPart is int) {
- if (bPart is int) {
+ if (aPart is num) {
+ if (bPart is num) {
// Compare two numbers.
return aPart.compareTo(bPart);
} else {
@@ -181,7 +181,7 @@
return -1;
}
} else {
- if (bPart is int) {
+ if (bPart is num) {
// Strings come after numbers.
return 1;
} else {
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index bb850fa..52a7458 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -8,26 +8,6 @@
[ $runtime == vm && $system == windows ]
test/serve/watch_removed_file_test: Pass, Fail # Issue 13026
-# Issue 12837 is a networking issue on the pub-mac buildbot.
-[ $runtime == vm && $system == macos ]
-test/hosted/remove_removed_dependency_test: Pass, Fail # Issue 12837
-test/hosted/remove_removed_transitive_dependency_test: Pass, Fail # Issue 12837
-test/hosted/version_negotiation_test: Pass, Fail # Issue 12837
-test/install/hosted/cached_pubspec_test: Pass, Fail # Issue 12837
-test/install/hosted/do_not_update_on_removed_constraints_test: Pass, Fail # Issue 12837
-test/install/hosted/install_test: Pass, Fail # Issue 12837
-test/install/hosted/install_transitive_test: Pass, Fail # Issue 12837
-test/install/hosted/repair_cache_test: Pass, Fail # Issue 12837
-test/install/hosted/stay_locked_if_compatible_test: Pass, Fail # Issue 12837
-test/install/hosted/stay_locked_if_new_is_satisfied_test: Pass, Fail # Issue 12837
-test/install/hosted/stay_locked_test: Pass, Fail # Issue 12837
-test/install/hosted/resolve_constraints_test: Pass, Fail # Issue 12837
-test/install/hosted/unlock_if_incompatible_test: Pass, Fail # Issue 12837
-test/install/hosted/unlock_if_new_is_unsatisfied_test: Pass, Fail # Issue 12837
-test/install/hosted/version_negotiation_test: Pass, Fail # Issue 12837
-test/serve/installs_first_if_path_dependency_changed_test: Pass, Fail # Issue 12837
-test/serve/serve_from_dependency_asset_test: Pass, Fail # Issue 12837
-
# Pub only runs on the VM, so just rule out all compilers.
[ $compiler == dart2js || $compiler == dart2dart ]
*: Skip
diff --git a/sdk/lib/_internal/pub/test/descriptor.dart b/sdk/lib/_internal/pub/test/descriptor.dart
index 1487aff..11d8ce4 100644
--- a/sdk/lib/_internal/pub/test/descriptor.dart
+++ b/sdk/lib/_internal/pub/test/descriptor.dart
@@ -139,7 +139,7 @@
return dir(cachePath, [
dir('hosted', [
- async(port.then((p) => dir('localhost%58$p', contents)))
+ async(port.then((p) => dir('127.0.0.1%58$p', contents)))
])
]);
}
diff --git a/sdk/lib/_internal/pub/test/hosted/fail_gracefully_on_missing_package_test.dart b/sdk/lib/_internal/pub/test/hosted/fail_gracefully_on_missing_package_test.dart
index bc72cc0..be17fec 100644
--- a/sdk/lib/_internal/pub/test/hosted/fail_gracefully_on_missing_package_test.dart
+++ b/sdk/lib/_internal/pub/test/hosted/fail_gracefully_on_missing_package_test.dart
@@ -17,7 +17,7 @@
d.appDir({"foo": "1.2.3"}).create();
pubCommand(command, error: new RegExp(
- r'Could not find package "foo" at http://localhost:\d+\.$'));
+ r'Could not find package "foo" at http://127\.0\.0\.1:\d+\.$'));
});
});
}
diff --git a/sdk/lib/_internal/pub/test/hosted/version_negotiation_test.dart b/sdk/lib/_internal/pub/test/hosted/version_negotiation_test.dart
index dc62e04..4e88721 100644
--- a/sdk/lib/_internal/pub/test/hosted/version_negotiation_test.dart
+++ b/sdk/lib/_internal/pub/test/hosted/version_negotiation_test.dart
@@ -4,8 +4,6 @@
library pub_tests;
-import 'dart:io';
-
import 'package:scheduled_test/scheduled_server.dart';
import 'package:scheduled_test/scheduled_test.dart';
@@ -65,7 +63,7 @@
pub.shouldExit(1);
expect(pub.remainingStderr(), completion(equals(
- "Pub 0.1.2+3 is incompatible with the current version of localhost.\n"
+ "Pub 0.1.2+3 is incompatible with the current version of 127.0.0.1.\n"
"Upgrade pub to the latest version and try again.")));
});
});
diff --git a/sdk/lib/_internal/pub/test/install/git/dependency_name_match_pubspec_test.dart b/sdk/lib/_internal/pub/test/install/git/dependency_name_match_pubspec_test.dart
index 2d4fef9..c9cb092 100644
--- a/sdk/lib/_internal/pub/test/install/git/dependency_name_match_pubspec_test.dart
+++ b/sdk/lib/_internal/pub/test/install/git/dependency_name_match_pubspec_test.dart
@@ -24,8 +24,7 @@
})
]).create();
- pubInstall(error:
- 'The name you specified for your dependency, "weirdname", doesn\'t '
- 'match the name "foo" in its pubspec.');
+ pubInstall(error: new RegExp(r'"name" field "foo" doesn' "'" r't match '
+ r'expected name "weirdname"\.'));
});
}
diff --git a/sdk/lib/_internal/pub/test/install/git/require_pubspec_name_test.dart b/sdk/lib/_internal/pub/test/install/git/require_pubspec_name_test.dart
index 6baa826..92d35f2 100644
--- a/sdk/lib/_internal/pub/test/install/git/require_pubspec_name_test.dart
+++ b/sdk/lib/_internal/pub/test/install/git/require_pubspec_name_test.dart
@@ -20,10 +20,7 @@
d.appDir({"foo": {"git": "../foo.git"}}).create();
- // TODO(nweiz): clean up this RegExp when either issue 4706 or 4707 is
- // fixed.
- pubInstall(error:
- 'Package "foo"\'s pubspec.yaml file is '
- 'missing the required "name" field (e.g. "name: foo").');
+ pubInstall(error: new RegExp(r'Missing the required "name" field \(e\.g\. '
+ r'"name: foo"\)\.'));
});
}
diff --git a/sdk/lib/_internal/pub/test/install/git/require_pubspec_test.dart b/sdk/lib/_internal/pub/test/install/git/require_pubspec_test.dart
index fd05528..1a317e9 100644
--- a/sdk/lib/_internal/pub/test/install/git/require_pubspec_test.dart
+++ b/sdk/lib/_internal/pub/test/install/git/require_pubspec_test.dart
@@ -18,8 +18,7 @@
d.appDir({"foo": {"git": "../foo.git"}}).create();
- // TODO(nweiz): clean up this RegExp when either issue 4706 or 4707 is
- // fixed.
- pubInstall(error: 'Package "foo" doesn\'t have a pubspec.yaml file.');
+ pubInstall(error: new RegExp(r'Could not find a file named "pubspec\.yaml" '
+ r'in "[^\n]*"\.'));
});
}
diff --git a/sdk/lib/_internal/pub/test/install/hosted/install_test.dart b/sdk/lib/_internal/pub/test/install/hosted/install_test.dart
index 342a5f3..f47a87f 100644
--- a/sdk/lib/_internal/pub/test/install/hosted/install_test.dart
+++ b/sdk/lib/_internal/pub/test/install/hosted/install_test.dart
@@ -26,6 +26,6 @@
d.appDir({"bad name!": "1.2.3"}).create();
pubInstall(error: new RegExp(
- r'Could not find package "bad name!" at http://localhost:\d+\.$'));
+ r'Could not find package "bad name!" at http://127\.0\.0\.1:\d+\.$'));
});
}
diff --git a/sdk/lib/_internal/pub/test/install/hosted/repair_cache_test.dart b/sdk/lib/_internal/pub/test/install/hosted/repair_cache_test.dart
index e456a98..907a6a6 100644
--- a/sdk/lib/_internal/pub/test/install/hosted/repair_cache_test.dart
+++ b/sdk/lib/_internal/pub/test/install/hosted/repair_cache_test.dart
@@ -15,7 +15,7 @@
// Set up a cache with a broken foo package.
d.dir(cachePath, [
d.dir('hosted', [
- d.async(port.then((p) => d.dir('localhost%58$p', [
+ d.async(port.then((p) => d.dir('127.0.0.1%58$p', [
d.dir("foo-1.2.3", [
d.libPubspec("foo", "1.2.3"),
// Note: empty "lib" directory.
@@ -39,7 +39,7 @@
// Set up a cache with a broken foo package.
d.dir(cachePath, [
d.dir('hosted', [
- d.async(port.then((p) => d.dir('localhost%58$p', [
+ d.async(port.then((p) => d.dir('127.0.0.1%58$p', [
d.dir("foo-1.2.3", [
d.libDir("foo")
// Note: no pubspec.
diff --git a/sdk/lib/_internal/pub/test/install/path/no_pubspec_test.dart b/sdk/lib/_internal/pub/test/install/path/no_pubspec_test.dart
index 76ff65c..7abaaf3 100644
--- a/sdk/lib/_internal/pub/test/install/path/no_pubspec_test.dart
+++ b/sdk/lib/_internal/pub/test/install/path/no_pubspec_test.dart
@@ -20,6 +20,7 @@
})
]).create();
- pubInstall(error: 'Package "foo" doesn\'t have a pubspec.yaml file.');
+ pubInstall(error: new RegExp(r'Could not find a file named "pubspec.yaml" '
+ r'in "[^\n]*"\.'));
});
}
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/list_package_dirs/lists_dependency_directories_test.dart b/sdk/lib/_internal/pub/test/list_package_dirs/lists_dependency_directories_test.dart
index 0e8f9f3..6dc7747 100644
--- a/sdk/lib/_internal/pub/test/list_package_dirs/lists_dependency_directories_test.dart
+++ b/sdk/lib/_internal/pub/test/list_package_dirs/lists_dependency_directories_test.dart
@@ -36,7 +36,7 @@
"packages": {
"foo": path.join(sandboxDir, "foo", "lib"),
"bar": port.then((p) => path.join(sandboxDir, cachePath, "hosted",
- "localhost%58$p", "bar-1.0.0", "lib")),
+ "127.0.0.1%58$p", "bar-1.0.0", "lib")),
"myapp": canonicalize(path.join(sandboxDir, appPath, "lib"))
},
"input_files": [
@@ -44,4 +44,4 @@
]
});
});
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/_internal/pub/test/oauth2/utils.dart b/sdk/lib/_internal/pub/test/oauth2/utils.dart
index 019628b..27280b0 100644
--- a/sdk/lib/_internal/pub/test/oauth2/utils.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/utils.dart
@@ -21,7 +21,7 @@
'upload packages on your behalf.')));
expect(pub.nextLine().then((line) {
- var match = new RegExp(r'[?&]redirect_uri=([0-9a-zA-Z%+-]+)[$&]')
+ var match = new RegExp(r'[?&]redirect_uri=([0-9a-zA-Z.%+-]+)[$&]')
.firstMatch(line);
expect(match, isNotNull);
diff --git a/sdk/lib/_internal/pub/test/oauth2/with_a_malformed_credentials_authenticates_again_test.dart b/sdk/lib/_internal/pub/test/oauth2/with_a_malformed_credentials_authenticates_again_test.dart
index 3ef06ec..4977cdd 100644
--- a/sdk/lib/_internal/pub/test/oauth2/with_a_malformed_credentials_authenticates_again_test.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/with_a_malformed_credentials_authenticates_again_test.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.
-import 'dart:io';
-
import 'package:scheduled_test/scheduled_test.dart';
import 'package:scheduled_test/scheduled_server.dart';
diff --git a/sdk/lib/_internal/pub/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart b/sdk/lib/_internal/pub/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart
index 0fd9290..d83570a 100644
--- a/sdk/lib/_internal/pub/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.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.
-import 'dart:io';
-
import 'package:scheduled_test/scheduled_test.dart';
import 'package:scheduled_test/scheduled_server.dart';
diff --git a/sdk/lib/_internal/pub/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart b/sdk/lib/_internal/pub/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
index a7ce025..496e42c 100644
--- a/sdk/lib/_internal/pub/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.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.
-import 'dart:io';
-
import 'package:scheduled_test/scheduled_test.dart';
import 'package:scheduled_test/scheduled_server.dart';
diff --git a/sdk/lib/_internal/pub/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart b/sdk/lib/_internal/pub/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart
index 1e931ce..3eea90e 100644
--- a/sdk/lib/_internal/pub/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.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.
-import 'dart:io';
-
import 'package:scheduled_test/scheduled_test.dart';
import 'package:scheduled_test/scheduled_server.dart';
diff --git a/sdk/lib/_internal/pub/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart b/sdk/lib/_internal/pub/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
index 67e134b..8f9fd0d 100644
--- a/sdk/lib/_internal/pub/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
+++ b/sdk/lib/_internal/pub/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
-import 'dart:io';
import 'package:scheduled_test/scheduled_test.dart';
import 'package:scheduled_test/scheduled_server.dart';
diff --git a/sdk/lib/_internal/pub/test/pub_install_and_update_test.dart b/sdk/lib/_internal/pub/test/pub_install_and_update_test.dart
index 06da50a..f1bbf15 100644
--- a/sdk/lib/_internal/pub/test/pub_install_and_update_test.dart
+++ b/sdk/lib/_internal/pub/test/pub_install_and_update_test.dart
@@ -18,8 +18,8 @@
d.dir(appPath, []).create();
pubCommand(command,
- error: new RegExp(r'^Could not find a file named "pubspec.yaml" '
- r'in the directory .*\.$'));
+ error: new RegExp(r'Could not find a file named "pubspec.yaml" '
+ r'in "[^\n]*"\.'));
});
integration('a pubspec with a "name" key', () {
@@ -27,9 +27,8 @@
d.pubspec({"dependencies": {"foo": null}})
]).create();
- pubCommand(command, error:
- 'pubspec.yaml is missing the required "name" field '
- '(e.g. "name: myapp").');
+ pubCommand(command, error: new RegExp(r'Missing the required "name" '
+ r'field\.'));
});
});
@@ -121,8 +120,8 @@
})
]).create();
- pubCommand(command,
- error: new RegExp("Package 'myapp' cannot depend on itself."));
+ pubCommand(command, error: new RegExp(r'"dependencies.myapp": Package '
+ r'may not list itself as a dependency\.'));
});
integration('does not allow a dev dependency on itself', () {
@@ -135,8 +134,8 @@
})
]).create();
- pubCommand(command,
- error: new RegExp("Package 'myapp' cannot depend on itself."));
+ pubCommand(command, error: new RegExp(r'"dev_dependencies.myapp": '
+ r'Package may not list itself as a dependency\.'));
});
});
}
diff --git a/sdk/lib/_internal/pub/test/pubspec_test.dart b/sdk/lib/_internal/pub/test/pubspec_test.dart
index 4404461..a9d7779 100644
--- a/sdk/lib/_internal/pub/test/pubspec_test.dart
+++ b/sdk/lib/_internal/pub/test/pubspec_test.dart
@@ -29,13 +29,33 @@
var sources = new SourceRegistry();
sources.register(new MockSource());
- expectFormatError(String pubspec) {
- expect(() => new Pubspec.parse(null, pubspec, sources),
- throwsFormatException);
+ var throwsPubspecException =
+ throwsA(new isInstanceOf<PubspecException>('PubspecException'));
+
+ expectPubspecException(String contents, fn(Pubspec pubspec)) {
+ var pubspec = new Pubspec.parse(contents, sources);
+ expect(() => fn(pubspec), throwsPubspecException);
}
+ test("doesn't eagerly throw an error for an invalid field", () {
+ // Shouldn't throw an error.
+ new Pubspec.parse('version: not a semver', sources);
+ });
+
+ test("eagerly throws an error if the pubspec name doesn't match the "
+ "expected name", () {
+ expect(() => new Pubspec.parse("name: foo", sources, expectedName: 'bar'),
+ throwsPubspecException);
+ });
+
+ test("eagerly throws an error if the pubspec doesn't have a name and an "
+ "expected name is passed", () {
+ expect(() => new Pubspec.parse("{}", sources, expectedName: 'bar'),
+ throwsPubspecException);
+ });
+
test("allows a version constraint for dependencies", () {
- var pubspec = new Pubspec.parse(null, '''
+ var pubspec = new Pubspec.parse('''
dependencies:
foo:
mock: ok
@@ -50,7 +70,7 @@
});
test("allows an empty dependencies map", () {
- var pubspec = new Pubspec.parse(null, '''
+ var pubspec = new Pubspec.parse('''
dependencies:
''', sources);
@@ -58,7 +78,7 @@
});
test("allows a version constraint for dev dependencies", () {
- var pubspec = new Pubspec.parse(null, '''
+ var pubspec = new Pubspec.parse('''
dev_dependencies:
foo:
mock: ok
@@ -73,7 +93,7 @@
});
test("allows an empty dev dependencies map", () {
- var pubspec = new Pubspec.parse(null, '''
+ var pubspec = new Pubspec.parse('''
dev_dependencies:
''', sources);
@@ -81,7 +101,7 @@
});
test("allows an unknown source", () {
- var pubspec = new Pubspec.parse(null, '''
+ var pubspec = new Pubspec.parse('''
dependencies:
foo:
unknown: blah
@@ -93,138 +113,90 @@
});
test("throws if a package is in dependencies and dev_dependencies", () {
- expectFormatError('''
+ var contents = '''
dependencies:
foo:
mock: ok
dev_dependencies:
foo:
mock: ok
-''');
+''';
+ expectPubspecException(contents, (pubspec) => pubspec.dependencies);
+ expectPubspecException(contents, (pubspec) => pubspec.devDependencies);
});
test("throws if it dependes on itself", () {
- expectFormatError('''
+ expectPubspecException('''
name: myapp
dependencies:
myapp:
mock: ok
-''');
+''', (pubspec) => pubspec.dependencies);
});
test("throws if it has a dev dependency on itself", () {
- expectFormatError('''
+ expectPubspecException('''
name: myapp
dev_dependencies:
myapp:
mock: ok
-''');
+''', (pubspec) => pubspec.devDependencies);
});
test("throws if the description isn't valid", () {
- expectFormatError('''
+ expectPubspecException('''
dependencies:
foo:
mock: bad
-''');
+''', (pubspec) => pubspec.dependencies);
});
test("throws if dependency version is not a string", () {
- expectFormatError('''
+ expectPubspecException('''
dependencies:
foo:
mock: ok
version: 1.2
-''');
+''', (pubspec) => pubspec.dependencies);
});
test("throws if version is not a version constraint", () {
- expectFormatError('''
+ expectPubspecException('''
dependencies:
foo:
mock: ok
version: not constraint
-''');
+''', (pubspec) => pubspec.dependencies);
});
test("throws if 'name' is not a string", () {
- expectFormatError('name: [not, a, string]');
+ expectPubspecException('name: [not, a, string]',
+ (pubspec) => pubspec.name);
});
test("throws if version is not a string", () {
- expectFormatError('''
-version: 1.0
-''');
+ expectPubspecException('version: 1.0', (pubspec) => pubspec.version);
});
test("throws if version is not a version", () {
- expectFormatError('''
-version: not version
-''');
- });
-
- test("throws if 'homepage' is not a string", () {
- expectFormatError('homepage:');
- expectFormatError('homepage: [not, a, string]');
- });
-
- test("throws if 'homepage' doesn't have an HTTP scheme", () {
- new Pubspec.parse(null, 'homepage: http://ok.com', sources);
- new Pubspec.parse(null, 'homepage: https://also-ok.com', sources);
-
- expectFormatError('homepage: ftp://badscheme.com');
- expectFormatError('homepage: javascript:alert("!!!")');
- expectFormatError('homepage: data:image/png;base64,somedata');
- expectFormatError('homepage: no-scheme.com');
- });
-
- test("throws if 'documentation' is not a string", () {
- expectFormatError('documentation:');
- expectFormatError('documentation: [not, a, string]');
- });
-
- test("throws if 'documentation' doesn't have an HTTP scheme", () {
- new Pubspec.parse(null, 'documentation: http://ok.com', sources);
- new Pubspec.parse(null, 'documentation: https://also-ok.com', sources);
-
- expectFormatError('documentation: ftp://badscheme.com');
- expectFormatError('documentation: javascript:alert("!!!")');
- expectFormatError('documentation: data:image/png;base64,somedata');
- expectFormatError('documentation: no-scheme.com');
- });
-
- test("throws if 'authors' is not a string or a list of strings", () {
- new Pubspec.parse(null, 'authors: ok fine', sources);
- new Pubspec.parse(null, 'authors: [also, ok, fine]', sources);
-
- expectFormatError('authors: 123');
- expectFormatError('authors: {not: {a: string}}');
- expectFormatError('authors: [ok, {not: ok}]');
- });
-
- test("throws if 'author' is not a string", () {
- new Pubspec.parse(null, 'author: ok fine', sources);
-
- expectFormatError('author: 123');
- expectFormatError('author: {not: {a: string}}');
- expectFormatError('author: [not, ok]');
- });
-
- test("throws if both 'author' and 'authors' are present", () {
- expectFormatError('{author: abe, authors: ted}');
+ expectPubspecException('version: not version',
+ (pubspec) => pubspec.version);
});
test("throws if a transformer isn't a string or map", () {
- expectFormatError('{transformers: 12}');
- expectFormatError('{transformers: [12]}');
+ expectPubspecException('transformers: 12',
+ (pubspec) => pubspec.transformers);
+ expectPubspecException('transformers: [12]',
+ (pubspec) => pubspec.transformers);
});
test("throws if a transformer's configuration isn't a map", () {
- expectFormatError('{transformers: {pkg: 12}}');
+ expectPubspecException('transformers: {pkg: 12}',
+ (pubspec) => pubspec.transformers);
});
test("allows comment-only files", () {
- var pubspec = new Pubspec.parse(null, '''
+ var pubspec = new Pubspec.parse('''
# No external dependencies yet
# Including for completeness
# ...and hoping the spec expands to include details about author, version, etc
@@ -236,25 +208,24 @@
group("environment", () {
test("defaults to any SDK constraint if environment is omitted", () {
- var pubspec = new Pubspec.parse(null, '', sources);
+ var pubspec = new Pubspec.parse('', sources);
expect(pubspec.environment.sdkVersion, equals(VersionConstraint.any));
});
test("allows an empty environment map", () {
- var pubspec = new Pubspec.parse(null, '''
+ var pubspec = new Pubspec.parse('''
environment:
''', sources);
expect(pubspec.environment.sdkVersion, equals(VersionConstraint.any));
});
test("throws if the environment value isn't a map", () {
- expectFormatError('''
-environment: []
-''');
+ expectPubspecException('environment: []',
+ (pubspec) => pubspec.environment);
});
test("allows a version constraint for the sdk", () {
- var pubspec = new Pubspec.parse(null, '''
+ var pubspec = new Pubspec.parse('''
environment:
sdk: ">=1.2.3 <2.3.4"
''', sources);
@@ -263,24 +234,15 @@
});
test("throws if the sdk isn't a string", () {
- expectFormatError('''
-environment:
- sdk: []
-''');
+ expectPubspecException('environment: {sdk: []}',
+ (pubspec) => pubspec.environment);
+ expectPubspecException('environment: {sdk: 1.0}',
+ (pubspec) => pubspec.environment);
});
- test("throws if the sdk is not a string", () {
- expectFormatError('''
-environment:
- sdk: 1.0
-''');
- });
-
test("throws if the sdk isn't a valid version constraint", () {
- expectFormatError('''
-environment:
- sdk: "oopies"
-''');
+ expectPubspecException('environment: {sdk: "oopies"}',
+ (pubspec) => pubspec.environment);
});
});
});
diff --git a/sdk/lib/_internal/pub/test/serve/configuration_defaults_to_empty_map_test.dart b/sdk/lib/_internal/pub/test/serve/configuration_defaults_to_empty_map_test.dart
index bad8e52..f23b4ac 100644
--- a/sdk/lib/_internal/pub/test/serve/configuration_defaults_to_empty_map_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/configuration_defaults_to_empty_map_test.dart
@@ -6,8 +6,6 @@
import 'dart:convert';
-import 'package:scheduled_test/scheduled_test.dart';
-
import '../descriptor.dart' as d;
import '../test_pub.dart';
import 'utils.dart';
diff --git a/sdk/lib/_internal/pub/test/serve/detects_a_transformer_cycle.dart b/sdk/lib/_internal/pub/test/serve/detects_a_transformer_cycle.dart
index 1da3080..192b348 100644
--- a/sdk/lib/_internal/pub/test/serve/detects_a_transformer_cycle.dart
+++ b/sdk/lib/_internal/pub/test/serve/detects_a_transformer_cycle.dart
@@ -39,7 +39,7 @@
createLockFile('myapp', sandbox: ['foo'], pkg: ['barback']);
// Use port 0 to get an ephemeral port.
- var process = startPub(args: ["serve", "--port=0"]);
+ var process = startPub(args: ["serve", "--port=0", "--hostname=127.0.0.1"]);
process.shouldExit(1);
expect(process.remainingStderr(), completion(equals(
"Transformer cycle detected:\n"
diff --git a/sdk/lib/_internal/pub/test/serve/detects_an_ordering_dependency_cycle.dart b/sdk/lib/_internal/pub/test/serve/detects_an_ordering_dependency_cycle.dart
index 3316e8d..9c148d4 100644
--- a/sdk/lib/_internal/pub/test/serve/detects_an_ordering_dependency_cycle.dart
+++ b/sdk/lib/_internal/pub/test/serve/detects_an_ordering_dependency_cycle.dart
@@ -55,7 +55,7 @@
createLockFile('myapp', sandbox: ['foo', 'bar', 'baz'], pkg: ['barback']);
// Use port 0 to get an ephemeral port.
- var process = startPub(args: ["serve", "--port=0"]);
+ var process = startPub(args: ["serve", "--port=0", "--hostname=127.0.0.1"]);
process.shouldExit(1);
expect(process.remainingStderr(), completion(equals(
"Transformer cycle detected:\n"
diff --git a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_file_that_defines_no_transforms_test.dart b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_file_that_defines_no_transforms_test.dart
index a636fcd..a4f697b 100644
--- a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_file_that_defines_no_transforms_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_file_that_defines_no_transforms_test.dart
@@ -25,7 +25,7 @@
createLockFile('myapp', pkg: ['barback']);
- var pub = startPub(args: ['serve', '--port=0']);
+ var pub = startPub(args: ['serve', '--port=0', "--hostname=127.0.0.1"]);
expect(pub.nextErrLine(), completion(startsWith('No transformers were '
'defined in ')));
expect(pub.nextErrLine(), completion(startsWith('required by myapp.')));
diff --git a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_non_existent_transform_test.dart b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_non_existent_transform_test.dart
index 31e56aa..da0ee0e 100644
--- a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_non_existent_transform_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_non_existent_transform_test.dart
@@ -19,7 +19,7 @@
})
]).create();
- var pub = startPub(args: ['serve', '--port=0']);
+ var pub = startPub(args: ['serve', '--port=0', "--hostname=127.0.0.1"]);
expect(pub.nextErrLine(), completion(equals(
'Transformer library "package:myapp/transform.dart" not found.')));
pub.shouldExit(1);
diff --git a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_pubspec_with_reserved_transformer_config_test.dart b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_pubspec_with_reserved_transformer_config_test.dart
index 5ba03d8..49da630 100644
--- a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_pubspec_with_reserved_transformer_config_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_pubspec_with_reserved_transformer_config_test.dart
@@ -26,11 +26,12 @@
createLockFile('myapp', pkg: ['barback']);
- var pub = startPub(args: ['serve', '--port=0']);
- expect(pub.nextErrLine(), completion(startsWith('Could not parse ')));
- expect(pub.nextErrLine(), completion(equals('Configuration for '
- 'transformer myapp/src/transformer may not include reserved key '
- '"include".')));
+ var pub = startPub(args: ['serve', '--port=0', "--hostname=127.0.0.1"]);
+ expect(pub.nextErrLine(), completion(equals('Error in pubspec for package '
+ '"myapp" loaded from pubspec.yaml:')));
+ expect(pub.nextErrLine(), completion(equals('Invalid transformer '
+ 'identifier for "transformers.myapp/src/transformer": Transformer '
+ 'configuration may not include reserved key "include".')));
pub.shouldExit(1);
});
}
diff --git a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_from_a_non_dependency_test.dart b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_from_a_non_dependency_test.dart
index 57c3349..3605734 100644
--- a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_from_a_non_dependency_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_from_a_non_dependency_test.dart
@@ -19,11 +19,11 @@
})
]).create();
- var pub = startPub(args: ['serve', '--port=0']);
+ var pub = startPub(args: ['serve', '--port=0', "--hostname=127.0.0.1"]);
// Ignore the line containing the path to the pubspec.
expect(pub.nextErrLine(), completes);
- expect(pub.nextErrLine(),
- completion(equals('Could not find package for transformer "foo".')));
+ expect(pub.nextErrLine(), completion(equals('"transformers.foo" refers to '
+ 'a package that\'s not listed in "dependencies".')));
pub.shouldExit(1);
});
}
diff --git a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_with_a_syntax_error_test.dart b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_with_a_syntax_error_test.dart
index b9b3073..765c93f 100644
--- a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_with_a_syntax_error_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_with_a_syntax_error_test.dart
@@ -27,7 +27,7 @@
createLockFile('myapp', pkg: ['barback']);
- var pub = startPub(args: ['serve', '--port=0']);
+ var pub = startPub(args: ['serve', '--port=0', "--hostname=127.0.0.1"]);
expect(pub.nextErrLine(), completion(startsWith('Error on line')));
pub.shouldExit(1);
expect(pub.remainingStderr(),
diff --git a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_with_an_import_error_test.dart b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_with_an_import_error_test.dart
index 0251159..fbb4281 100644
--- a/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_with_an_import_error_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/fails_to_load_a_transform_with_an_import_error_test.dart
@@ -27,7 +27,7 @@
createLockFile('myapp', pkg: ['barback']);
- var pub = startPub(args: ['serve', '--port=0']);
+ var pub = startPub(args: ['serve', '--port=0', "--hostname=127.0.0.1"]);
expect(pub.nextErrLine(), completion(matches(new RegExp(
r"Error: line 1 pos 1: library handler failed$"))));
pub.shouldExit(1);
diff --git a/sdk/lib/_internal/pub/test/serve/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart b/sdk/lib/_internal/pub/test/serve/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
index 0403641..ee33dde 100644
--- a/sdk/lib/_internal/pub/test/serve/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
@@ -27,7 +27,7 @@
createLockFile('myapp', pkg: ['barback']);
- var pub = startPub(args: ['serve', '--port=0']);
+ var pub = startPub(args: ['serve', '--port=0', "--hostname=127.0.0.1"]);
expect(pub.nextErrLine(), completion(startsWith('No transformers that '
'accept configuration were defined in ')));
pub.shouldExit(1);
diff --git a/sdk/lib/_internal/pub/test/serve/invalid_method_test.dart b/sdk/lib/_internal/pub/test/serve/invalid_method_test.dart
index a543ccc..28a259d 100644
--- a/sdk/lib/_internal/pub/test/serve/invalid_method_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/invalid_method_test.dart
@@ -4,10 +4,6 @@
library pub_tests;
-import 'package:path/path.dart' as path;
-import 'package:scheduled_test/scheduled_test.dart';
-
-import '../../lib/src/io.dart';
import '../descriptor.dart' as d;
import '../test_pub.dart';
import 'utils.dart';
diff --git a/sdk/lib/_internal/pub/test/serve/passes_configuration_to_a_transformer_test.dart b/sdk/lib/_internal/pub/test/serve/passes_configuration_to_a_transformer_test.dart
index e3f68e1..292b624 100644
--- a/sdk/lib/_internal/pub/test/serve/passes_configuration_to_a_transformer_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/passes_configuration_to_a_transformer_test.dart
@@ -6,8 +6,6 @@
import 'dart:convert';
-import 'package:scheduled_test/scheduled_test.dart';
-
import '../descriptor.dart' as d;
import '../test_pub.dart';
import 'utils.dart';
diff --git a/sdk/lib/_internal/pub/test/serve/utils.dart b/sdk/lib/_internal/pub/test/serve/utils.dart
index 46ace9d..6c5f1ec 100644
--- a/sdk/lib/_internal/pub/test/serve/utils.dart
+++ b/sdk/lib/_internal/pub/test/serve/utils.dart
@@ -92,7 +92,7 @@
/// Returns the `pub serve` process.
ScheduledProcess startPubServe({bool shouldInstallFirst: false}) {
// Use port 0 to get an ephemeral port.
- _pubServer = startPub(args: ["serve", "--port=0"]);
+ _pubServer = startPub(args: ["serve", "--port=0", "--hostname=127.0.0.1"]);
if (shouldInstallFirst) {
expect(_pubServer.nextLine(),
@@ -107,10 +107,10 @@
return _pubServer;
}
-/// Parses the port number from the "Serving blah on localhost:1234" line
+/// Parses the port number from the "Serving blah on 127.0.0.1:1234" line
/// printed by pub serve.
void _parsePort(String line) {
- var match = new RegExp(r"localhost:(\d+)").firstMatch(line);
+ var match = new RegExp(r"127\.0\.0\.1:(\d+)").firstMatch(line);
assert(match != null);
_port = int.parse(match[1]);
}
@@ -123,7 +123,7 @@
/// verifies that it responds with [expected].
void requestShouldSucceed(String urlPath, String expected) {
schedule(() {
- return http.get("http://localhost:$_port/$urlPath").then((response) {
+ return http.get("http://127.0.0.1:$_port/$urlPath").then((response) {
expect(response.body, equals(expected));
});
}, "request $urlPath");
@@ -133,7 +133,7 @@
/// verifies that it responds with a 404.
void requestShould404(String urlPath) {
schedule(() {
- return http.get("http://localhost:$_port/$urlPath").then((response) {
+ return http.get("http://127.0.0.1:$_port/$urlPath").then((response) {
expect(response.statusCode, equals(404));
});
}, "request $urlPath");
@@ -143,7 +143,7 @@
/// that it responds with a 405.
void postShould405(String urlPath) {
schedule(() {
- return http.post("http://localhost:$_port/$urlPath").then((response) {
+ return http.post("http://127.0.0.1:$_port/$urlPath").then((response) {
expect(response.statusCode, equals(405));
});
}, "request $urlPath");
diff --git a/sdk/lib/_internal/pub/test/serve/with_configuration_only_instantiates_configurable_transformers_test.dart b/sdk/lib/_internal/pub/test/serve/with_configuration_only_instantiates_configurable_transformers_test.dart
index 6c010bf..8959382 100644
--- a/sdk/lib/_internal/pub/test/serve/with_configuration_only_instantiates_configurable_transformers_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/with_configuration_only_instantiates_configurable_transformers_test.dart
@@ -6,8 +6,6 @@
import 'dart:convert';
-import 'package:scheduled_test/scheduled_test.dart';
-
import '../descriptor.dart' as d;
import '../test_pub.dart';
import 'utils.dart';
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index 897b69e..1f79116 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -94,7 +94,7 @@
schedule(() {
return _closeServer().then((_) {
- return SafeHttpServer.bind("localhost", 0).then((server) {
+ return SafeHttpServer.bind("127.0.0.1", 0).then((server) {
_server = server;
server.listen((request) {
currentSchedule.heartbeat();
@@ -485,7 +485,7 @@
// dependencies will look there.
if (_hasServer) {
return port.then((p) {
- environment['PUB_HOSTED_URL'] = "http://localhost:$p";
+ environment['PUB_HOSTED_URL'] = "http://127.0.0.1:$p";
return environment;
});
}
diff --git a/sdk/lib/_internal/pub/test/update/git/update_to_incompatible_pubspec_test.dart b/sdk/lib/_internal/pub/test/update/git/update_to_incompatible_pubspec_test.dart
index df398de..645646a 100644
--- a/sdk/lib/_internal/pub/test/update/git/update_to_incompatible_pubspec_test.dart
+++ b/sdk/lib/_internal/pub/test/update/git/update_to_incompatible_pubspec_test.dart
@@ -32,8 +32,8 @@
d.libPubspec('zoo', '1.0.0')
]).commit();
- pubUpdate(error: 'The name you specified for your dependency, '
- '"foo", doesn\'t match the name "zoo" in its pubspec.');
+ pubUpdate(error: new RegExp(r'"name" field "zoo" doesn' "'" r't match '
+ r'expected name "foo"\.'));
d.dir(packagesPath, [
d.dir('foo', [
diff --git a/sdk/lib/_internal/pub/test/update/git/update_to_nonexistent_pubspec_test.dart b/sdk/lib/_internal/pub/test/update/git/update_to_nonexistent_pubspec_test.dart
index 8cb8971..6a9213c 100644
--- a/sdk/lib/_internal/pub/test/update/git/update_to_nonexistent_pubspec_test.dart
+++ b/sdk/lib/_internal/pub/test/update/git/update_to_nonexistent_pubspec_test.dart
@@ -31,7 +31,8 @@
repo.runGit(['rm', 'pubspec.yaml']);
repo.runGit(['commit', '-m', 'delete']);
- pubUpdate(error: 'Package "foo" doesn\'t have a pubspec.yaml file.');
+ pubUpdate(error: new RegExp(r'Could not find a file named "pubspec.yaml" '
+ r'in "[^\n]*"\.'));
d.dir(packagesPath, [
d.dir('foo', [
diff --git a/sdk/lib/_internal/pub/test/validator/pubspec_field_test.dart b/sdk/lib/_internal/pub/test/validator/pubspec_field_test.dart
index 15ed04e..9c951a8 100644
--- a/sdk/lib/_internal/pub/test/validator/pubspec_field_test.dart
+++ b/sdk/lib/_internal/pub/test/validator/pubspec_field_test.dart
@@ -28,6 +28,22 @@
d.dir(appPath, [d.pubspec(pkg)]).create();
expectNoValidationError(pubspecField);
});
+
+ integration('has an HTTPS homepage URL', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["homepage"] = "https://pub.dartlang.org";
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectNoValidationError(pubspecField);
+ });
+
+ integration('has an HTTPS documentation URL', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["documentation"] = "https://pub.dartlang.org";
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectNoValidationError(pubspecField);
+ });
});
group('should consider a package invalid if it', () {
@@ -57,6 +73,46 @@
expectValidationError(pubspecField);
});
+ integration('has a non-string "homepage" field', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["homepage"] = 12;
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectValidationError(pubspecField);
+ });
+
+ integration('has a non-string "description" field', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["description"] = 12;
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectValidationError(pubspecField);
+ });
+
+ integration('has a non-string "author" field', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["author"] = 12;
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectValidationError(pubspecField);
+ });
+
+ integration('has a non-list "authors" field', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["authors"] = 12;
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectValidationError(pubspecField);
+ });
+
+ integration('has a non-string member of the "authors" field', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["authors"] = [12];
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectValidationError(pubspecField);
+ });
+
integration('has a single author without an email', () {
var pkg = packageMap("test_pkg", "1.0.0");
pkg["author"] = "Nathan Weizenbaum";
@@ -98,5 +154,21 @@
expectValidationWarning(pubspecField);
});
+
+ integration('has a non-HTTP homepage URL', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["homepage"] = "file:///foo/bar";
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectValidationError(pubspecField);
+ });
+
+ integration('has a non-HTTP documentation URL', () {
+ var pkg = packageMap("test_pkg", "1.0.0");
+ pkg["documentation"] = "file:///foo/bar";
+ d.dir(appPath, [d.pubspec(pkg)]).create();
+
+ expectValidationError(pubspecField);
+ });
});
}
diff --git a/sdk/lib/_internal/pub/test/version_solver_test.dart b/sdk/lib/_internal/pub/test/version_solver_test.dart
index bbe86ac..0a8da4c 100644
--- a/sdk/lib/_internal/pub/test/version_solver_test.dart
+++ b/sdk/lib/_internal/pub/test/version_solver_test.dart
@@ -14,7 +14,6 @@
import '../lib/src/pubspec.dart';
import '../lib/src/sdk.dart' as sdk;
import '../lib/src/source.dart';
-import '../lib/src/source_registry.dart';
import '../lib/src/system_cache.dart';
import '../lib/src/version.dart';
import '../lib/src/solver/version_solver.dart';
@@ -959,7 +958,7 @@
}
description.add('Resolved:\n${_listPackages(result.packages)}\n');
- description.add(state.state);
+ description.add(state['failures']);
return description;
}
@@ -991,7 +990,7 @@
}
if (!failures.isEmpty) {
- state.state = failures.toString();
+ state['failures'] = failures.toString();
return false;
}
@@ -1029,7 +1028,7 @@
Description describeMismatch(SolveResult result,
Description description,
Map state, bool verbose) {
- description.add(state.state);
+ description.add(state['failures']);
return description;
}
@@ -1060,7 +1059,7 @@
}
if (!failures.isEmpty) {
- state.state = failures.toString();
+ state['failures'] = failures.toString();
return false;
}
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index 76c2b42..acf0549 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -18,6 +18,7 @@
library dart.async;
import "dart:collection";
+import "dart:_collection-dev" show deprecated;
part 'async_error.dart';
part 'broadcast_stream_controller.dart';
diff --git a/sdk/lib/async/event_loop.dart b/sdk/lib/async/event_loop.dart
index 9462460..94137da 100644
--- a/sdk/lib/async/event_loop.dart
+++ b/sdk/lib/async/event_loop.dart
@@ -55,8 +55,14 @@
* }
*/
void runAsync(void callback()) {
- _Zone currentZone = _Zone._current;
- currentZone.runAsync(callback, currentZone);
+ if (Zone.current == Zone.ROOT) {
+ // No need to bind the callback. We know that the root's runAsync will
+ // be invoked in the root zone.
+ Zone.current.scheduleMicrotask(callback);
+ return;
+ }
+ Zone.current.scheduleMicrotask(
+ Zone.current.bindCallback(callback, runGuarded: true));
}
class _AsyncRun {
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index ab4b666..7fe2c68 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -194,12 +194,15 @@
// List collecting values from the futures.
// Set to null if an error occurs.
List values;
- void handleError(error) {
+
+ dynamic handleError(error) {
if (values != null) {
values = null;
completer.completeError(error);
}
+ return null;
}
+
// As each future completes, put its value into the corresponding
// position in the list of values.
int remaining = 0;
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index a149161..ad7b9bd 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -76,7 +76,7 @@
/** Whether the future is complete, and as what. */
int _state = _INCOMPLETE;
- final _Zone _zone = _Zone.current.fork();
+ final Zone _zone;
bool get _mayComplete => _state == _INCOMPLETE;
bool get _isChained => _state == _CHAINED;
@@ -140,37 +140,46 @@
=> _isChained ? null : _whenCompleteActionCallback;
_Future()
- : _onValueCallback = null, _errorTestCallback = null,
+ : _zone = Zone.current,
+ _onValueCallback = null, _errorTestCallback = null,
_onErrorCallback = null, _whenCompleteActionCallback = null;
/// Valid types for value: `T` or `Future<T>`.
_Future.immediate(value)
- : _onValueCallback = null, _errorTestCallback = null,
+ : _zone = Zone.current,
+ _onValueCallback = null, _errorTestCallback = null,
_onErrorCallback = null, _whenCompleteActionCallback = null {
_asyncComplete(value);
}
_Future.immediateError(var error, [Object stackTrace])
- : _onValueCallback = null, _errorTestCallback = null,
+ : _zone = Zone.current,
+ _onValueCallback = null, _errorTestCallback = null,
_onErrorCallback = null, _whenCompleteActionCallback = null {
_asyncCompleteError(error, stackTrace);
}
- _Future._then(this._onValueCallback, this._onErrorCallback)
- : _errorTestCallback = null, _whenCompleteActionCallback = null {
- _zone.expectCallback();
- }
+ _Future._then(onValueCallback(value), onErrorCallback(e))
+ : _zone = Zone.current,
+ _onValueCallback = Zone.current.registerUnaryCallback(onValueCallback),
+ _onErrorCallback = Zone.current.registerUnaryCallback(onErrorCallback),
+ _errorTestCallback = null,
+ _whenCompleteActionCallback = null;
- _Future._catchError(this._onErrorCallback, this._errorTestCallback)
- : _onValueCallback = null, _whenCompleteActionCallback = null {
- _zone.expectCallback();
- }
+ _Future._catchError(onErrorCallback(e), bool errorTestCallback(e))
+ : _zone = Zone.current,
+ _onErrorCallback = Zone.current.registerUnaryCallback(onErrorCallback),
+ _errorTestCallback = Zone.current.registerUnaryCallback(errorTestCallback),
+ _onValueCallback = null,
+ _whenCompleteActionCallback = null;
- _Future._whenComplete(this._whenCompleteActionCallback)
- : _onValueCallback = null, _errorTestCallback = null,
- _onErrorCallback = null {
- _zone.expectCallback();
- }
+ _Future._whenComplete(whenCompleteActionCallback())
+ : _zone = Zone.current,
+ _whenCompleteActionCallback =
+ Zone.current.registerCallback(whenCompleteActionCallback),
+ _onValueCallback = null,
+ _errorTestCallback = null,
+ _onErrorCallback = null;
Future then(f(T value), { onError(error) }) {
_Future result;
@@ -224,7 +233,7 @@
assert(listener._nextListener == null);
if (_isComplete) {
// Handle late listeners asynchronously.
- runAsync(() {
+ _zone.scheduleMicrotask(() {
_propagateToListeners(this, listener);
});
} else {
@@ -341,7 +350,7 @@
}
_markPendingCompletion();
- runAsync(() {
+ _zone.scheduleMicrotask(() {
_complete(value);
});
}
@@ -354,7 +363,7 @@
assert(_errorTest == null);
_markPendingCompletion();
- runAsync(() {
+ _zone.scheduleMicrotask(() {
_completeError(error, stackTrace);
});
}
@@ -405,11 +414,11 @@
source._zone.handleUncaughtError(source._error);
return;
}
- if (!identical(_Zone.current, listener._zone)) {
+ if (!identical(Zone.current, listener._zone)) {
// Run the propagation in the listener's zone to avoid
// zone transitions. The idea is that many chained futures will
// be in the same zone.
- listener._zone.executePeriodicCallback(() {
+ listener._zone.run(() {
_propagateToListeners(source, listener);
});
return;
@@ -429,7 +438,7 @@
// zone.
// TODO(floitsch): only run callbacks in the zone, not the whole
// handling code.
- listener._zone.executeCallback(() {
+ listener._zone.run(() {
// TODO(floitsch): mark the listener as pending completion. Currently
// we can't do this, since the markPendingCompletion verifies that
// the future is not already marked (or chained).
@@ -479,8 +488,6 @@
_propagateToListeners(completeResult, listener);
});
isPropagationAborted = true;
- // We will reenter the listener's zone.
- listener._zone.expectCallback();
}
}
} catch (e, s) {
@@ -488,10 +495,6 @@
listenerValueOrError = _asyncError(e, s);
listenerHasValue = false;
}
- if (listenerHasValue && listenerValueOrError is Future) {
- // We are going to reenter the zone to finish what we started.
- listener._zone.expectCallback();
- }
});
if (isPropagationAborted) return;
// If the listener's value is a future we need to chain it.
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 194602e..42ff1eb 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -579,7 +579,7 @@
try {
notificationHandler();
} catch (e, s) {
- _Zone.current.handleUncaughtError(_asyncError(e, s));
+ Zone.current.handleUncaughtError(_asyncError(e, s));
}
}
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index ffab312..ee390cf 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -80,7 +80,7 @@
_DataHandler<T> _onData;
_ErrorHandler _onError;
_DoneHandler _onDone;
- final _Zone _zone = _Zone.current;
+ final Zone _zone = Zone.current;
/** Bit vector based on state-constants above. */
int _state;
@@ -92,15 +92,17 @@
*/
_PendingEvents _pending;
- _BufferingStreamSubscription(this._onData,
- this._onError,
- this._onDone,
+ _BufferingStreamSubscription(void onData(T data),
+ void onError(error),
+ void onDone(),
bool cancelOnError)
- : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) {
+ : _onData = Zone.current.registerUnaryCallback(onData),
+ _onError = Zone.current.registerUnaryCallback(onError),
+ _onDone = Zone.current.registerCallback(onDone),
+ _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) {
assert(_onData != null);
assert(_onError != null);
assert(_onDone != null);
- _zone.expectCallback();
}
/**
@@ -219,7 +221,6 @@
void _cancel() {
_state |= _STATE_CANCELED;
- _zone.cancelCallbackExpectation();
if (_hasPending) {
_pending.cancelSchedule();
}
@@ -322,7 +323,7 @@
assert(!_inCallback);
bool wasInputPaused = _isInputPaused;
_state |= _STATE_IN_CALLBACK;
- _zone.executePeriodicCallbackGuarded(() => _onData(data));
+ _zone.runUnaryGuarded(_onData, data);
_state &= ~_STATE_IN_CALLBACK;
_checkState(wasInputPaused);
}
@@ -333,11 +334,11 @@
assert(!_inCallback);
bool wasInputPaused = _isInputPaused;
_state |= _STATE_IN_CALLBACK;
- if (!_zone.inSameErrorZone(_Zone.current)) {
+ if (!_zone.inSameErrorZone(Zone.current)) {
// Errors are not allowed to traverse zone boundaries.
- _Zone.current.handleUncaughtError(error);
+ Zone.current.handleUncaughtError(error);
} else {
- _zone.executePeriodicCallbackGuarded(() => _onError(error));
+ _zone.runUnaryGuarded(_onError, error);
}
_state &= ~_STATE_IN_CALLBACK;
if (_cancelOnError) {
@@ -351,7 +352,7 @@
assert(!_isPaused);
assert(!_inCallback);
_state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK);
- _zone.executeCallbackGuarded(_onDone);
+ _zone.runGuarded(_onDone);
_onCancel(); // No checkState after cancel, it is always the last event.
_state &= ~_STATE_IN_CALLBACK;
}
@@ -532,7 +533,7 @@
/** Default error handler, reports the error to the global handler. */
void _nullErrorHandler(error) {
- _Zone.current.handleUncaughtError(error);
+ Zone.current.handleUncaughtError(error);
}
/** Default done handler, does nothing. */
@@ -723,18 +724,18 @@
final Stream<T> _source;
final _broadcastCallback _onListenHandler;
final _broadcastCallback _onCancelHandler;
- final _Zone _zone;
+ final Zone _zone;
_AsBroadcastStreamController<T> _controller;
StreamSubscription<T> _subscription;
_AsBroadcastStream(this._source,
- this._onListenHandler,
- this._onCancelHandler)
- : _zone = _Zone.current {
+ void onListenHandler(StreamSubscription subscription),
+ void onCancelHandler(StreamSubscription subscription))
+ : _onListenHandler = Zone.current.registerUnaryCallback(onListenHandler),
+ _onCancelHandler = Zone.current.registerUnaryCallback(onCancelHandler),
+ _zone = Zone.current {
_controller = new _AsBroadcastStreamController<T>(_onListen, _onCancel);
- // Keep zone alive until we are done doing callbacks.
- _zone.expectCallback();
}
bool get isBroadcast => true;
@@ -763,22 +764,19 @@
void _onCancel() {
bool shutdown = (_controller == null) || _controller.isClosed;
if (_onCancelHandler != null) {
- _zone.executePeriodicCallbackGuarded(
- () => _onCancelHandler(new _BroadcastSubscriptionWrapper(this)));
+ _zone.runUnary(_onCancelHandler, new _BroadcastSubscriptionWrapper(this));
}
if (shutdown) {
if (_subscription != null) {
_subscription.cancel();
_subscription = null;
}
- _zone.cancelCallbackExpectation();
}
}
void _onListen() {
if (_onListenHandler != null) {
- _zone.executePeriodicCallbackGuarded(
- () => _onListenHandler(new _BroadcastSubscriptionWrapper(this)));
+ _zone.runUnary(_onListenHandler, new _BroadcastSubscriptionWrapper(this));
}
}
@@ -788,9 +786,6 @@
// Called by [_controller] when it has no subscribers left.
StreamSubscription subscription = _subscription;
_subscription = null;
- if (_controller._isEmpty) {
- _zone.cancelCallbackExpectation();
- }
_controller = null; // Marks the stream as no longer listenable.
subscription.cancel();
}
diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart
index 6c15c4b..0fb0cea 100644
--- a/sdk/lib/async/timer.dart
+++ b/sdk/lib/async/timer.dart
@@ -32,7 +32,7 @@
*
* Note: If Dart code using Timer is compiled to JavaScript, the finest
* granularity available in the browser is 4 milliseconds.
- *
+ *
* See [Stopwatch] for measuring elapsed time.
*/
abstract class Timer {
@@ -44,7 +44,13 @@
*
*/
factory Timer(Duration duration, void callback()) {
- return _Zone.current.createTimer(duration, callback);
+ if (Zone.current == Zone.ROOT) {
+ // No need to bind the callback. We know that the root's timer will
+ // be invoked in the root zone.
+ return Zone.current.createTimer(duration, callback);
+ }
+ return Zone.current.createTimer(
+ duration, Zone.current.bindCallback(callback, runGuarded: true));
}
/**
@@ -55,7 +61,13 @@
*/
factory Timer.periodic(Duration duration,
void callback(Timer timer)) {
- return _Zone.current.createPeriodicTimer(duration, callback);
+ if (Zone.current == Zone.ROOT) {
+ // No need to bind the callback. We know that the root's timer will
+ // be invoked in the root zone.
+ return Zone.current.createPeriodicTimer(duration, callback);
+ }
+ return Zone.current.createPeriodicTimer(
+ duration, Zone.current.bindUnaryCallback(callback, runGuarded: true));
}
/**
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 87741a0..ac6bacd 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -4,101 +4,275 @@
part of dart.async;
+typedef dynamic ZoneCallback();
+typedef dynamic ZoneUnaryCallback(arg);
+
+typedef dynamic HandleUncaughtErrorHandler(
+ Zone self, ZoneDelegate parent, Zone zone, e);
+typedef dynamic RunHandler(Zone self, ZoneDelegate parent, Zone zone, f());
+typedef dynamic RunUnaryHandler(
+ Zone self, ZoneDelegate parent, Zone zone, f(arg), arg);
+typedef ZoneCallback RegisterCallbackHandler(
+ Zone self, ZoneDelegate parent, Zone zone, f());
+typedef ZoneUnaryCallback RegisterUnaryCallbackHandler(
+ Zone self, ZoneDelegate parent, Zone zone, f(arg));
+typedef void ScheduleMicrotaskHandler(
+ Zone self, ZoneDelegate parent, Zone zone, f());
+typedef Timer CreateTimerHandler(
+ Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f());
+typedef Timer CreatePeriodicTimerHandler(
+ Zone self, ZoneDelegate parent, Zone zone,
+ Duration period, void f(Timer timer));
+typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone,
+ ZoneSpecification specification,
+ Map<Symbol, dynamic> zoneValues);
+
+/**
+ * This class provides the specification for a forked zone.
+ *
+ * When forking a new zone (see [Zone.fork]) one can override the default
+ * behavior of the zone by providing callbacks. These callbacks must be
+ * given in an instance of this class.
+ *
+ * Handlers have the same signature as the same-named methods on [Zone] but
+ * receive three additional arguments:
+ *
+ * 1. the zone the handlers are attached to (the "self" zone).
+ * 2. a [ZoneDelegate] to the parent zone.
+ * 3. the zone that first received the request (before the request was
+ * bubbled up).
+ *
+ * Handlers can either stop propagation the request (by simply not calling the
+ * parent handler), or forward to the parent zone, potentially modifying the
+ * arguments on the way.
+ */
+abstract class ZoneSpecification {
+ /**
+ * Creates a specification with the provided handlers.
+ */
+ const factory ZoneSpecification({
+ void handleUncaughtError(
+ Zone self, ZoneDelegate parent, Zone zone, e): null,
+ dynamic run(Zone self, ZoneDelegate parent, Zone zone, f()): null,
+ dynamic runUnary(
+ Zone self, ZoneDelegate parent, Zone zone, f(arg), arg): null,
+ ZoneCallback registerCallback(
+ Zone self, ZoneDelegate parent, Zone zone, f()): null,
+ ZoneUnaryCallback registerUnaryCallback(
+ Zone self, ZoneDelegate parent, Zone zone, f(arg)): null,
+ void scheduleMicrotask(
+ Zone self, ZoneDelegate parent, Zone zone, f()): null,
+ Timer createTimer(Zone self, ZoneDelegate parent, Zone zone,
+ Duration duration, void f()): null,
+ Timer createPeriodicTimer(Zone self, ZoneDelegate parent, Zone zone,
+ Duration period, void f(Timer timer)): null,
+ Zone fork(Zone self, ZoneDelegate parent, Zone zone,
+ ZoneSpecification specification, Map zoneValues): null
+ }) = _ZoneSpecification;
+
+ /**
+ * Creates a specification from [other] with the provided handlers overriding
+ * the ones in [other].
+ */
+ factory ZoneSpecification.from(ZoneSpecification other, {
+ void handleUncaughtError(
+ Zone self, ZoneDelegate parent, Zone zone, e): null,
+ dynamic run(Zone self, ZoneDelegate parent, Zone zone, f()): null,
+ dynamic runUnary(
+ Zone self, ZoneDelegate parent, Zone zone, f(arg), arg): null,
+ ZoneCallback registerCallback(
+ Zone self, ZoneDelegate parent, Zone zone, f()): null,
+ ZoneUnaryCallback registerUnaryCallback(
+ Zone self, ZoneDelegate parent, Zone zone, f(arg)): null,
+ void scheduleMicrotask(
+ Zone self, ZoneDelegate parent, Zone zone, f()): null,
+ Timer createTimer(Zone self, ZoneDelegate parent, Zone zone,
+ Duration duration, void f()): null,
+ Timer createPeriodicTimer(Zone self, ZoneDelegate parent, Zone zone,
+ Duration period, void f(Timer timer)): null,
+ Zone fork(Zone self, ZoneDelegate parent, Zone zone,
+ ZoneSpecification specification,
+ Map<Symbol, dynamic> zoneValues): null
+ }) {
+ return new ZoneSpecification(
+ handleUncaughtError: handleUncaughtError != null
+ ? handleUncaughtError
+ : other.handleUncaughtError,
+ run: run != null ? run : other.run,
+ runUnary: runUnary != null ? runUnary : other.runUnary,
+ registerCallback: registerCallback != null
+ ? registerCallback
+ : other.registerCallback,
+ registerUnaryCallback: registerUnaryCallback != null
+ ? registerUnaryCallback
+ : other.registerUnaryCallback,
+ scheduleMicrotask: scheduleMicrotask != null
+ ? scheduleMicrotask
+ : other.scheduleMicrotask,
+ createTimer : createTimer != null ? createTimer : other.createTimer,
+ createPeriodicTimer: createPeriodicTimer != null
+ ? createPeriodicTimer
+ : other.createPeriodicTimer,
+ fork: fork != null ? fork : other.fork);
+ }
+
+ HandleUncaughtErrorHandler get handleUncaughtError;
+ RunHandler get run;
+ RunUnaryHandler get runUnary;
+ RegisterCallbackHandler get registerCallback;
+ RegisterUnaryCallbackHandler get registerUnaryCallback;
+ ScheduleMicrotaskHandler get scheduleMicrotask;
+ CreateTimerHandler get createTimer;
+ CreatePeriodicTimerHandler get createPeriodicTimer;
+ ForkHandler get fork;
+}
+
+/**
+ * Internal [ZoneSpecification] class.
+ *
+ * The implementation wants to rely on the fact that the getters cannot change
+ * dynamically. We thus require users to go through the redirecting
+ * [ZoneSpecification] constructor which instantiates this class.
+ */
+class _ZoneSpecification implements ZoneSpecification {
+ const _ZoneSpecification({
+ this.handleUncaughtError: null,
+ this.run: null,
+ this.runUnary: null,
+ this.registerCallback: null,
+ this.registerUnaryCallback: null,
+ this.scheduleMicrotask: null,
+ this.createTimer: null,
+ this.createPeriodicTimer: null,
+ this.fork: null
+ });
+
+ // TODO(13406): Enable types when dart2js supports it.
+ final /*HandleUncaughtErrorHandler*/ handleUncaughtError;
+ final /*RunHandler*/ run;
+ final /*RunUnaryHandler*/ runUnary;
+ final /*RegisterCallbackHandler*/ registerCallback;
+ final /*RegisterUnaryCallbackHandler*/ registerUnaryCallback;
+ final /*ScheduleMicrotaskHandler*/ scheduleMicrotask;
+ final /*CreateTimerHandler*/ createTimer;
+ final /*CreatePeriodicTimerHandler*/ createPeriodicTimer;
+ final /*ForkHandler*/ fork;
+}
+
+/**
+ * This class wraps zones for delegation.
+ *
+ * When forwarding to parent zones one can't just invoke the parent zone's
+ * exposed functions (like [Zone.run]), but one needs to provide more
+ * information (like the zone the `run` was initiated). Zone callbacks thus
+ * receive more information including this [ZoneDelegate] class. When delegating
+ * to the parent zone one should go through the given instance instead of
+ * directly invoking the parent zone.
+ */
+abstract class ZoneDelegate {
+ /// The [Zone] this class wraps.
+ Zone get _zone;
+
+ dynamic handleUncaughtError(Zone zone, e);
+ dynamic run(Zone zone, f());
+ dynamic runUnary(Zone zone, f(arg), arg);
+ ZoneCallback registerCallback(Zone zone, f());
+ ZoneUnaryCallback registerUnaryCallback(Zone zone, f(arg));
+ void scheduleMicrotask(Zone zone, f());
+ Timer createTimer(Zone zone, Duration duration, void f());
+ Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer));
+ Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues);
+}
+
/**
* A Zone represents the asynchronous version of a dynamic extent. Asynchronous
* callbacks are executed in the zone they have been queued in. For example,
* the callback of a `future.then` is executed in the same zone as the one where
* the `then` was invoked.
*/
-abstract class _Zone {
+abstract class Zone {
+ // Private constructor so that it is not possible instantiate a Zone class.
+ Zone._();
+
+ /// The root zone that is implicitly created.
+ static const Zone ROOT = _ROOT_ZONE;
+
/// The currently running zone.
- static _Zone _current = new _DefaultZone();
+ static Zone _current = _ROOT_ZONE;
- static _Zone get current => _current;
+ static Zone get current => _current;
- void handleUncaughtError(error);
+ dynamic handleUncaughtError(error);
+
+ /**
+ * Returns the parent zone.
+ *
+ * Returns `null` if `this` is the [ROOT] zone.
+ */
+ Zone get parent;
/**
* Returns true if `this` and [otherZone] are in the same error zone.
+ *
+ * Two zones are in the same error zone if they share the same
+ * [handleUncaughtError] callback.
*/
- bool inSameErrorZone(_Zone otherZone);
+ bool inSameErrorZone(Zone otherZone);
/**
- * Returns a zone for reentry in the zone.
- *
- * The returned zone is equivalent to `this` (and frequently is indeed
- * `this`).
- *
- * The main purpose of this method is to allow `this` to attach debugging
- * information to the returned zone.
+ * Creates a new zone as a child of `this`.
*/
- _Zone fork();
+ Zone fork({ ZoneSpecification specification,
+ Map<Symbol, dynamic> zoneValues });
/**
- * Tells the zone that it needs to wait for one more callback before it is
- * done.
- *
- * Use [executeCallback] or [cancelCallbackExpectation] when the callback is
- * executed (or canceled).
+ * Executes the given function [f] in this zone.
*/
- void expectCallback();
+ dynamic run(f());
/**
- * Tells the zone not to wait for a callback anymore.
- *
- * Prefer calling [executeCallback], instead. This method is mostly useful
- * for repeated callbacks (for example with [Timer.periodic]). In this case
- * one should should call [expectCallback] when the repeated callback is
- * initiated, and [cancelCallbackExpectation] when the [Timer] is canceled.
+ * Executes the given callback [f] with argument [arg] in this zone.
*/
- void cancelCallbackExpectation();
+ dynamic runUnary(f(arg), var arg);
+
+ /**
+ * Executes the given function [f] in this zone.
+ *
+ * Same as [run] but catches uncaught errors and gives them to
+ * [handleUncaughtError].
+ */
+ dynamic runGuarded(f());
/**
* Executes the given callback [f] in this zone.
*
- * Decrements the number of callbacks this zone is waiting for (see
- * [expectCallback]).
- */
- void executeCallback(void f());
-
- /**
- * Same as [executeCallback] but catches uncaught errors and gives them to
+ * Same as [runUnary] but catches uncaught errors and gives them to
* [handleUncaughtError].
*/
- void executeCallbackGuarded(void f());
+ dynamic runUnaryGuarded(f(arg), var arg);
+
+ ZoneCallback registerCallback(f());
+ ZoneUnaryCallback registerUnaryCallback(f(arg));
/**
- * Same as [executeCallback] but does not decrement the number of
- * callbacks this zone is waiting for (see [expectCallback]).
- */
- void executePeriodicCallback(void f());
-
- /**
- * Same as [executePeriodicCallback] but catches uncaught errors and gives
- * them to [handleUncaughtError].
- */
- void executePeriodicCallbackGuarded(void f());
-
- /**
- * Executes [f] in `this` zone.
+ * Equivalent to:
*
- * The behavior of this method should be the same as
- * [executePeriodicCallback] except that it can have a return value.
+ * ZoneCallback registered = registerCallback(f);
+ * return () => this.run(registered);
+ */
+ ZoneCallback bindCallback(f(), { bool runGuarded });
+ /**
+ * Equivalent to:
*
- * Returns the result of the invocation.
+ * ZoneCallback registered = registerCallback1(f);
+ * return (arg) => this.run1(registered, arg);
*/
- dynamic runFromChildZone(f());
+ ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded });
/**
- * Same as [runFromChildZone] but catches uncaught errors and gives them to
- * [handleUncaughtError].
+ * Runs [f] asynchronously.
*/
- dynamic runFromChildZoneGuarded(f());
-
- /**
- * Runs [f] asynchronously in [zone].
- */
- void runAsync(void f(), _Zone zone);
+ void scheduleMicrotask(void f());
/**
* Creates a Timer where the callback is executed in this zone.
@@ -108,362 +282,315 @@
/**
* Creates a periodic Timer where the callback is executed in this zone.
*/
- Timer createPeriodicTimer(Duration duration, void callback(Timer timer));
+ Timer createPeriodicTimer(Duration period, void callback(Timer timer));
/**
* The error zone is the one that is responsible for dealing with uncaught
* errors. Errors are not allowed to cross zones with different error-zones.
*/
- _Zone get _errorZone;
+ Zone get _errorZone;
/**
- * Adds [child] as a child of `this`.
+ * Retrieves the zone-value associated with [key].
*
- * This usually means that the [child] is in the asynchronous dynamic extent
- * of `this`.
+ * If this zone does not contain the value looks up the same key in the
+ * parent zone. If the [key] is not found returns `null`.
*/
- void _addChild(_Zone child);
-
- /**
- * Removes [child] from `this`' children.
- *
- * This usually means that the [child] has finished executing and is done.
- */
- void _removeChild(_Zone child);
+ operator[](Symbol key);
}
+class _ZoneDelegate implements ZoneDelegate {
+ final _CustomizedZone _degelationTarget;
+
+ Zone get _zone => _degelationTarget;
+
+ const _ZoneDelegate(this._degelationTarget);
+
+ dynamic handleUncaughtError(Zone zone, e) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.handleUncaughtError == null) {
+ parent = parent.parent;
+ }
+ return (parent._specification.handleUncaughtError)(
+ parent, new _ZoneDelegate(parent.parent), zone, e);
+ }
+
+ dynamic run(Zone zone, f()) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.run == null) {
+ parent = parent.parent;
+ }
+ return (parent._specification.run)(
+ parent, new _ZoneDelegate(parent.parent), zone, f);
+ }
+
+ dynamic runUnary(Zone zone, f(arg), arg) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.runUnary == null) {
+ parent = parent.parent;
+ }
+ return (parent._specification.runUnary)(
+ parent, new _ZoneDelegate(parent.parent), zone, f, arg);
+ }
+
+ ZoneCallback registerCallback(Zone zone, f()) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.registerCallback == null) {
+ parent = parent.parent;
+ }
+ return (parent._specification.registerCallback)(
+ parent, new _ZoneDelegate(parent.parent), zone, f);
+ }
+
+ ZoneUnaryCallback registerUnaryCallback(Zone zone, f(arg)) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.registerUnaryCallback == null) {
+ parent = parent.parent;
+ }
+ return (parent._specification.registerUnaryCallback)(
+ parent, new _ZoneDelegate(parent.parent), zone, f);
+ }
+
+ void scheduleMicrotask(Zone zone, f()) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.scheduleMicrotask == null) {
+ parent = parent.parent;
+ }
+ _ZoneDelegate grandParent = new _ZoneDelegate(parent.parent);
+ (parent._specification.scheduleMicrotask)(parent, grandParent, zone, f);
+ }
+
+ Timer createTimer(Zone zone, Duration duration, void f()) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.createTimer == null) {
+ parent = parent.parent;
+ }
+ return (parent._specification.createTimer)(
+ parent, new _ZoneDelegate(parent.parent), zone, duration, f);
+ }
+
+ Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.createPeriodicTimer == null) {
+ parent = parent.parent;
+ }
+ return (parent._specification.createPeriodicTimer)(
+ parent, new _ZoneDelegate(parent.parent), zone, period, f);
+ }
+
+ Zone fork(Zone zone, ZoneSpecification specification,
+ Map<Symbol, dynamic> zoneValues) {
+ _CustomizedZone parent = _degelationTarget;
+ while (parent._specification.fork == null) {
+ parent = parent.parent;
+ }
+ _ZoneDelegate grandParent = new _ZoneDelegate(parent.parent);
+ return (parent._specification.fork)(
+ parent, grandParent, zone, specification, zoneValues);
+ }
+}
+
+
/**
- * Basic implementation of a [_Zone]. This class is intended for subclassing.
+ * Default implementation of a [Zone].
*/
-class _ZoneBase implements _Zone {
- /// The parent zone. [null] if `this` is the default zone.
- final _Zone _parentZone;
+class _CustomizedZone implements Zone {
+ /// The parent zone.
+ final _CustomizedZone parent;
+ /// The zone's handlers.
+ final ZoneSpecification _specification;
+ /// The zone's value map.
+ final Map<Symbol, dynamic> _map;
- /// The number of children of this zone. A child's [_parentZone] is `this`.
- int _childCount = 0;
+ const _CustomizedZone(this.parent, this._specification, this._map);
- /// The number of outstanding (asynchronous) callbacks. As long as the
- /// number is greater than 0 it means that the zone is not done yet.
- int _openCallbacks = 0;
-
- bool _isExecutingCallback = false;
-
- _ZoneBase(this._parentZone) {
- _parentZone._addChild(this);
+ Zone get _errorZone {
+ if (_specification.handleUncaughtError != null) return this;
+ return parent._errorZone;
}
- _ZoneBase._defaultZone() : _parentZone = null {
- assert(this is _DefaultZone);
- }
+ bool inSameErrorZone(Zone otherZone) => _errorZone == otherZone._errorZone;
- _Zone get _errorZone => _parentZone._errorZone;
-
- void handleUncaughtError(error) {
- _parentZone.handleUncaughtError(error);
- }
-
- bool inSameErrorZone(_Zone otherZone) => _errorZone == otherZone._errorZone;
-
- _Zone fork() => this;
-
- expectCallback() => _openCallbacks++;
-
- cancelCallbackExpectation() {
- _openCallbacks--;
- _checkIfDone();
- }
-
- /**
- * Cleans up this zone when it is done.
- *
- * This releases internal memore structures that are no longer necessary.
- *
- * A zone is done when its dynamic extent has finished executing and
- * there are no outstanding asynchronous callbacks.
- */
- void _dispose() {
- if (_parentZone != null) {
- _parentZone._removeChild(this);
- }
- }
-
- /**
- * Checks if the zone is done and doesn't have any outstanding callbacks
- * anymore.
- *
- * This method is called when an operation has decremented the
- * outstanding-callback count, or when a child has been removed.
- */
- void _checkIfDone() {
- if (!_isExecutingCallback && _openCallbacks == 0 && _childCount == 0) {
- _dispose();
- }
- }
-
- void executeCallback(void f()) {
- _openCallbacks--;
- this._runUnguarded(f);
- }
-
- void executeCallbackGuarded(void f()) {
- _openCallbacks--;
- this._runGuarded(f);
- }
-
- void executePeriodicCallback(void f()) {
- this._runUnguarded(f);
- }
-
- void executePeriodicCallbackGuarded(void f()) {
- this._runGuarded(f);
- }
-
- dynamic runFromChildZone(f()) => this._runUnguarded(f);
- dynamic runFromChildZoneGuarded(f()) => this._runGuarded(f);
-
- dynamic _runInZone(f(), bool handleUncaught) {
- if (identical(_Zone._current, this)
- && !handleUncaught
- && _isExecutingCallback) {
- // No need to go through a try/catch.
- return f();
- }
-
- _Zone oldZone = _Zone._current;
- _Zone._current = this;
- // While we are executing the function we don't want to have other
- // synchronous calls to think that they closed the zone. By incrementing
- // the _openCallbacks count we make sure that their test will fail.
- // As a side effect it will make nested calls faster since they are
- // (probably) in the same zone and have an _openCallbacks > 0.
- bool oldIsExecuting = _isExecutingCallback;
- _isExecutingCallback = true;
- // TODO(430): remove second try when VM bug is fixed.
+ dynamic runGuarded(f()) {
try {
- try {
- return f();
- } catch(e, s) {
- if (handleUncaught) {
- handleUncaughtError(_asyncError(e, s));
- } else {
- rethrow;
- }
- }
- } finally {
- _isExecutingCallback = oldIsExecuting;
- _Zone._current = oldZone;
- _checkIfDone();
+ return run(f);
+ } catch (e, s) {
+ return handleUncaughtError(_asyncError(e, s));
}
}
- /**
- * Runs the function and catches uncaught errors.
- *
- * Uncaught errors are given to [handleUncaughtError].
- */
- dynamic _runGuarded(void f()) {
- return _runInZone(f, true);
- }
-
- /**
- * Runs the function but doesn't catch uncaught errors.
- */
- dynamic _runUnguarded(void f()) {
- return _runInZone(f, false);
- }
-
- void runAsync(void f(), _Zone zone) => _parentZone.runAsync(f, zone);
-
- // TODO(floitsch): the zone should just forward to the parent zone. The
- // default zone should then create the _ZoneTimer.
- Timer createTimer(Duration duration, void callback()) {
- return new _ZoneTimer(this, duration, callback);
- }
-
- // TODO(floitsch): the zone should just forward to the parent zone. The
- // default zone should then create the _ZoneTimer.
- Timer createPeriodicTimer(Duration duration, void callback(Timer timer)) {
- return new _PeriodicZoneTimer(this, duration, callback);
- }
-
- void _addChild(_Zone child) {
- _childCount++;
- }
-
- void _removeChild(_Zone child) {
- assert(_childCount != 0);
- _childCount--;
- _checkIfDone();
- }
-}
-
-/**
- * The default-zone that conceptually surrounds the `main` function.
- */
-class _DefaultZone extends _ZoneBase {
- _DefaultZone() : super._defaultZone();
-
- _Zone get _errorZone => this;
-
- void handleUncaughtError(error) {
- _scheduleAsyncCallback(() {
- print("Uncaught Error: ${error}");
- var trace = getAttachedStackTrace(error);
- _attachStackTrace(error, null);
- if (trace != null) {
- print("Stack Trace:\n$trace\n");
- }
- throw error;
- });
- }
-
- void runAsync(void f(), _Zone zone) {
- if (identical(this, zone)) {
- // No need to go through the zone when it's the default zone anyways.
- _scheduleAsyncCallback(f);
- return;
- }
- zone.expectCallback();
- _scheduleAsyncCallback(() {
- zone.executeCallbackGuarded(f);
- });
- }
-}
-
-typedef void _CompletionCallback();
-
-/**
- * A zone that executes a callback when the zone is dead.
- */
-class _WaitForCompletionZone extends _ZoneBase {
- final _CompletionCallback _onDone;
-
- _WaitForCompletionZone(_Zone parentZone, this._onDone) : super(parentZone);
-
- /**
- * Runs the given function.
- *
- * Executes the [_onDone] callback when the zone is done.
- */
- dynamic runWaitForCompletion(void f()) {
- return this._runUnguarded(f);
- }
-
- void _dispose() {
- super._dispose();
- _onDone();
- }
-
- String toString() => "WaitForCompletion ${super.toString()}";
-}
-
-typedef void _HandleErrorCallback(error);
-
-/**
- * A zone that collects all uncaught errors and provides them in a stream.
- * The stream is closed when the zone is done.
- */
-class _CatchErrorsZone extends _WaitForCompletionZone {
- final _HandleErrorCallback _handleError;
-
- _CatchErrorsZone(_Zone parentZone, this._handleError, void onDone())
- : super(parentZone, onDone);
-
- _Zone get _errorZone => this;
-
- void handleUncaughtError(error) {
+ dynamic runUnaryGuarded(f(arg), arg) {
try {
- _handleError(error);
- } catch(e, s) {
- if (identical(e, error)) {
- _parentZone.handleUncaughtError(error);
- } else {
- _parentZone.handleUncaughtError(_asyncError(e, s));
- }
+ return runUnary(f, arg);
+ } catch (e, s) {
+ return handleUncaughtError(_asyncError(e, s));
}
}
- /**
- * Runs the given function asynchronously. Executes the [_onDone] callback
- * when the zone is done.
- */
- dynamic runWaitForCompletion(void f()) {
- return this._runGuarded(f);
+ ZoneCallback bindCallback(f(), { bool runGuarded }) {
+ ZoneCallback registered = registerCallback(f);
+ if (runGuarded) {
+ return () => this.runGuarded(registered);
+ } else {
+ return () => this.run(registered);
+ }
}
- String toString() => "CatchErrors ${super.toString()}";
+ ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded }) {
+ ZoneUnaryCallback registered = registerUnaryCallback(f);
+ if (runGuarded) {
+ return (arg) => this.runUnaryGuarded(registered, arg);
+ } else {
+ return (arg) => this.runUnary(registered, arg);
+ }
+ }
+
+ operator [](Symbol key) {
+ var result = _map[key];
+ if (result != null || _map.containsKey(key)) return result;
+ // If we are not the root zone look up in the parent zone.
+ if (parent != null) return parent[key];
+ assert(this == Zone.ROOT);
+ return null;
+ }
+
+ // Methods that can be customized by the zone specification.
+
+ dynamic handleUncaughtError(error) {
+ return new _ZoneDelegate(this).handleUncaughtError(this, error);
+ }
+
+ Zone fork({ZoneSpecification specification, Map zoneValues}) {
+ return new _ZoneDelegate(this).fork(this, specification, zoneValues);
+ }
+
+ dynamic run(f()) {
+ return new _ZoneDelegate(this).run(this, f);
+ }
+
+ dynamic runUnary(f(arg), arg) {
+ return new _ZoneDelegate(this).runUnary(this, f, arg);
+ }
+
+ ZoneCallback registerCallback(f()) {
+ return new _ZoneDelegate(this).registerCallback(this, f);
+ }
+
+ ZoneUnaryCallback registerUnaryCallback(f(arg)) {
+ return new _ZoneDelegate(this).registerUnaryCallback(this, f);
+ }
+
+ void scheduleMicrotask(void f()) {
+ new _ZoneDelegate(this).scheduleMicrotask(this, f);
+ }
+
+ Timer createTimer(Duration duration, void f()) {
+ return new _ZoneDelegate(this).createTimer(this, duration, f);
+ }
+
+ Timer createPeriodicTimer(Duration duration, void f(Timer timer)) {
+ return new _ZoneDelegate(this).createPeriodicTimer(this, duration, f);
+ }
}
-typedef void _RunAsyncInterceptor(void callback());
+void _rootHandleUncaughtError(
+ Zone self, ZoneDelegate parent, Zone zone, error) {
+ _scheduleAsyncCallback(() {
+ print("Uncaught Error: ${error}");
+ var trace = getAttachedStackTrace(error);
+ _attachStackTrace(error, null);
+ if (trace != null) {
+ print("Stack Trace:\n$trace\n");
+ }
+ throw error;
+ });
+}
-class _RunAsyncZone extends _ZoneBase {
- final _RunAsyncInterceptor _runAsyncInterceptor;
+dynamic _rootRun(Zone self, ZoneDelegate parent, Zone zone, f()) {
+ if (Zone._current == zone) return f();
- _RunAsyncZone(_Zone parentZone, this._runAsyncInterceptor)
- : super(parentZone);
+ Zone old = Zone._current;
+ try {
+ Zone._current = zone;
+ return f();
+ } finally {
+ Zone._current = old;
+ }
+}
- void runAsync(void callback(), _Zone zone) {
- zone.expectCallback();
- _parentZone.runFromChildZone(() {
- _runAsyncInterceptor(() => zone.executeCallbackGuarded(callback));
+dynamic _rootRunUnary(Zone self, ZoneDelegate parent, Zone zone, f(arg), arg) {
+ if (Zone._current == zone) return f(arg);
+
+ Zone old = Zone._current;
+ try {
+ Zone._current = zone;
+ return f(arg);
+ } finally {
+ Zone._current = old;
+ }
+}
+
+ZoneCallback _rootRegisterCallback(
+ Zone self, ZoneDelegate parent, Zone zone, f()) {
+ return f;
+}
+
+ZoneUnaryCallback _rootRegisterUnaryCallback(
+ Zone self, ZoneDelegate parent, Zone zone, f(arg)) {
+ return f;
+}
+
+void _rootScheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, f()) {
+ _scheduleAsyncCallback(f);
+}
+
+Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone,
+ Duration duration, void callback()) {
+ return _createTimer(duration, callback);
+}
+
+Timer _rootCreatePeriodicTimer(
+ Zone self, ZoneDelegate parent, Zone zone,
+ Duration duration, void callback(Timer timer)) {
+ return _createPeriodicTimer(duration, callback);
+}
+
+Zone _rootFork(Zone self, ZoneDelegate parent, Zone zone,
+ ZoneSpecification specification,
+ Map<Symbol, dynamic> zoneValues) {
+ if (specification == null) {
+ specification = const ZoneSpecification();
+ } else if (specification is! _ZoneSpecification) {
+ throw new ArgumentError("ZoneSpecifications must be instantiated"
+ " with the provided constructor.");
+ }
+ Map<Symbol, dynamic> copiedMap = new HashMap();
+ if (zoneValues != null) {
+ zoneValues.forEach((Symbol key, value) {
+ if (key == null) {
+ throw new ArgumentError("ZoneValue key must not be null");
+ }
+ copiedMap[key] = value;
});
}
+ return new _CustomizedZone(zone, specification, copiedMap);
}
-typedef void _TimerCallback();
+const _ROOT_SPECIFICATION = const ZoneSpecification(
+ handleUncaughtError: _rootHandleUncaughtError,
+ run: _rootRun,
+ runUnary: _rootRunUnary,
+ registerCallback: _rootRegisterCallback,
+ registerUnaryCallback: _rootRegisterUnaryCallback,
+ scheduleMicrotask: _rootScheduleMicrotask,
+ createTimer: _rootCreateTimer,
+ createPeriodicTimer: _rootCreatePeriodicTimer,
+ fork: _rootFork
+);
-/**
- * A [Timer] class that takes zones into account.
- */
-class _ZoneTimer implements Timer {
- final _Zone _zone;
- final _TimerCallback _callback;
- Timer _timer;
+const _ROOT_ZONE =
+ const _CustomizedZone(null, _ROOT_SPECIFICATION, const <Symbol, dynamic>{});
- _ZoneTimer(this._zone, Duration duration, this._callback) {
- _zone.expectCallback();
- _timer = _createTimer(duration, this._run);
- }
-
- void _run() {
- _zone.executeCallbackGuarded(_callback);
- }
-
- void cancel() {
- if (_timer.isActive) _zone.cancelCallbackExpectation();
- _timer.cancel();
- }
-
- bool get isActive => _timer.isActive;
-}
-
-typedef void _PeriodicTimerCallback(Timer timer);
-
-/**
- * A [Timer] class for periodic callbacks that takes zones into account.
- */
-class _PeriodicZoneTimer implements Timer {
- final _Zone _zone;
- final _PeriodicTimerCallback _callback;
- Timer _timer;
-
- _PeriodicZoneTimer(this._zone, Duration duration, this._callback) {
- _zone.expectCallback();
- _timer = _createPeriodicTimer(duration, this._run);
- }
-
- void _run(Timer timer) {
- assert(identical(_timer, timer));
- _zone.executePeriodicCallbackGuarded(() { _callback(this); });
- }
-
- void cancel() {
- if (_timer.isActive) _zone.cancelCallbackExpectation();
- _timer.cancel();
- }
-
- bool get isActive => _timer.isActive;
-}
/**
* Runs [body] in its own zone.
@@ -472,32 +599,6 @@
* errors, synchronous or asynchronous, in the zone are caught and handled
* by the callback.
*
- * The [onDone] handler (if non-null) is invoked when the zone has no more
- * outstanding callbacks. *Deprecated*: this method is less useful than it
- * seems, because it assumes that every registered callback is always invoked.
- * There are, however, many *valid* reasons not to complete futures or to abort
- * a future-chain. In general it is a bad idea to rely on `onDone`.
- *
- * The [onRunAsync] handler (if non-null) is invoked when the [body] executes
- * [runAsync]. The handler is invoked in the outer zone and can therefore
- * execute [runAsync] without recursing. The given callback must be
- * executed eventually. Otherwise the nested zone will not complete. It must be
- * executed only once.
- *
- * Examples:
- *
- * runZonedExperimental(() {
- * new Future(() { throw "asynchronous error"; });
- * }, onError: print); // Will print "asynchronous error".
- *
- * The following example prints "1", "2", "3", "4" in this order.
- *
- * runZonedExperimental(() {
- * print(1);
- * new Future.value(3).then(print);
- * }, onDone: () { print(4); });
- * print(2);
- *
* Errors may never cross error-zone boundaries. This is intuitive for leaving
* a zone, but it also applies for errors that would enter an error-zone.
* Errors that try to cross error-zone boundaries are considered uncaught.
@@ -510,6 +611,56 @@
* }, onError: (e) { print("unused error handler"); });
* }, onError: (e) { print("catches error of first error-zone."); });
*
+ * Example:
+ *
+ * runZonedExperimental(() {
+ * new Future(() { throw "asynchronous error"; });
+ * }, onError: print); // Will print "asynchronous error".
+ */
+dynamic runZoned(body(),
+ { Map<Symbol, dynamic> zoneValues,
+ ZoneSpecification zoneSpecification,
+ void onError(error) }) {
+ HandleUncaughtErrorHandler errorHandler;
+ if (onError != null) {
+ errorHandler = (Zone self, ZoneDelegate parent, Zone zone, error) {
+ try {
+ return self.parent.runUnary(onError, error);
+ } catch(e, s) {
+ if (identical(e, error)) {
+ return parent.handleUncaughtError(zone, error);
+ } else {
+ return parent.handleUncaughtError(zone, _asyncError(e, s));
+ }
+ }
+ };
+ }
+ if (zoneSpecification == null) {
+ zoneSpecification =
+ new ZoneSpecification(handleUncaughtError: errorHandler);
+ } else if (errorHandler != null) {
+ zoneSpecification =
+ new ZoneSpecification.from(zoneSpecification,
+ handleUncaughtError: errorHandler);
+ }
+ Zone zone = Zone.current.fork(specification: zoneSpecification,
+ zoneValues: zoneValues);
+ if (onError != null) {
+ return zone.runGuarded(body);
+ } else {
+ return zone.run(body);
+ }
+}
+
+/**
+ * Deprecated. Use `runZoned` instead or create your own [ZoneSpecification].
+ *
+ * The [onRunAsync] handler (if non-null) is invoked when the [body] executes
+ * [runAsync]. The handler is invoked in the outer zone and can therefore
+ * execute [runAsync] without recursing. The given callback must be
+ * executed eventually. Otherwise the nested zone will not complete. It must be
+ * executed only once.
+ *
* The following example prints the stack trace whenever a callback is
* registered using [runAsync] (which is also used by [Completer]s and
* [StreamController]s.
@@ -519,26 +670,44 @@
* printStackTrace();
* runAsync(callback);
* });
+ *
+ * Note: the `onDone` handler is ignored.
*/
+@deprecated
runZonedExperimental(body(),
{ void onRunAsync(void callback()),
void onError(error),
void onDone() }) {
+ if (onRunAsync == null) {
+ return runZoned(body, onError: onError);
+ }
+ HandleUncaughtErrorHandler errorHandler;
+ if (onError != null) {
+ errorHandler = (Zone self, ZoneDelegate parent, Zone zone, error) {
+ try {
+ return self.parent.runUnary(onError, error);
+ } catch(e, s) {
+ if (identical(e, error)) {
+ return parent.handleUncaughtError(zone, error);
+ } else {
+ return parent.handleUncaughtError(zone, _asyncError(e, s));
+ }
+ }
+ };
+ }
+ ScheduleMicrotaskHandler asyncHandler;
if (onRunAsync != null) {
- _RunAsyncZone zone = new _RunAsyncZone(_Zone._current, onRunAsync);
- return zone._runUnguarded(() {
- return runZonedExperimental(body, onError: onError, onDone: onDone);
- });
+ asyncHandler = (Zone self, ZoneDelegate parent, Zone zone, f()) {
+ self.parent.runUnary(onRunAsync, () => zone.runGuarded(f));
+ };
}
-
- // TODO(floitsch): we probably still want to install a new Zone.
- if (onError == null && onDone == null) return body();
- if (onError == null) {
- _WaitForCompletionZone zone =
- new _WaitForCompletionZone(_Zone._current, onDone);
- return zone.runWaitForCompletion(body);
+ ZoneSpecification specification =
+ new ZoneSpecification(handleUncaughtError: errorHandler,
+ scheduleMicrotask: asyncHandler);
+ Zone zone = Zone.current.fork(specification: specification);
+ if (onError != null) {
+ return zone.runGuarded(body);
+ } else {
+ return zone.run(body);
}
- if (onDone == null) onDone = _nullDoneHandler;
- _CatchErrorsZone zone = new _CatchErrorsZone(_Zone._current, onError, onDone);
- return zone.runWaitForCompletion(body);
}
diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart
index bcca966..7759046 100644
--- a/sdk/lib/collection/hash_map.dart
+++ b/sdk/lib/collection/hash_map.dart
@@ -63,6 +63,15 @@
bool isValidKey(potentialKey)});
/**
+ * Creates an unordered identity-based map.
+ *
+ * Effectively a shorthand for:
+ *
+ * new HashMap(equals: identical, hashCode: identityHashCodeOf)
+ */
+ external factory HashMap.identity();
+
+ /**
* Creates a [HashMap] that contains all key value pairs of [other].
*/
factory HashMap.from(Map<K, V> other) {
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index f1241a8..b60653a 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -110,6 +110,15 @@
bool isValidKey(potentialKey) });
/**
+ * Creates an unordered identity-based set.
+ *
+ * Effectively a shorthand for:
+ *
+ * new HashSet(equals: identical, hashCode: identityHashCodeOf)
+ */
+ external factory HashSet.identity();
+
+ /**
* Create a hash set containing the elements of [iterable].
*
* Creates a hash set as by `new HashSet<E>()` and adds each element of
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index 34744d0..924077c 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -24,6 +24,15 @@
bool isValidKey(potentialKey) });
/**
+ * Creates an insertion-ordered identity-based map.
+ *
+ * Effectively a shorthand for:
+ *
+ * new LinkedHashMap(equals: identical, hashCode: identityHashCodeOf)
+ */
+ external factory LinkedHashMap.identity();
+
+ /**
* Creates a [LinkedHashMap] that contains all key value pairs of [other].
*/
factory LinkedHashMap.from(Map<K, V> other) {
diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart
index d9aadf2..7a79991 100644
--- a/sdk/lib/collection/linked_hash_set.dart
+++ b/sdk/lib/collection/linked_hash_set.dart
@@ -27,6 +27,16 @@
int hashCode(E e),
bool isValidKey(potentialKey) });
+ /**
+ * Creates an insertion-ordered identity-based set.
+ *
+ * Effectively a shorthand for:
+ *
+ * new LinkedHashSet(equals: identical, hashCode: identityHashCodeOf)
+ */
+ external factory LinkedHashSet.identity();
+
+
factory LinkedHashSet.from(Iterable<E> iterable) {
return new LinkedHashSet<E>()..addAll(iterable);
}
diff --git a/sdk/lib/convert/html_escape.dart b/sdk/lib/convert/html_escape.dart
index dd9f3e7..6e9c5c1 100644
--- a/sdk/lib/convert/html_escape.dart
+++ b/sdk/lib/convert/html_escape.dart
@@ -12,22 +12,23 @@
final bool escapeLtGt;
final bool escapeQuot;
final bool escapeApos;
+ final bool escapeSlash;
// TODO(floitsch) - Document - Issue 13097
static const HtmlEscapeMode UNKNOWN =
- const HtmlEscapeMode._('unknown', true, true, true);
+ const HtmlEscapeMode._('unknown', true, true, true, true);
// TODO(floitsch) - Document - Issue 13097
static const HtmlEscapeMode ATTRIBUTE =
- const HtmlEscapeMode._('attribute', false, true, false);
+ const HtmlEscapeMode._('attribute', false, true, false, false);
// TODO(floitsch) - Document - Issue 13097
static const HtmlEscapeMode ELEMENT =
- const HtmlEscapeMode._('element', true, false, false);
+ const HtmlEscapeMode._('element', true, false, false, true);
// TODO(floitsch) - Document - Issue 13097
const HtmlEscapeMode._(this._name, this.escapeLtGt, this.escapeQuot,
- this.escapeApos);
+ this.escapeApos, this.escapeSlash);
String toString() => _name;
}
@@ -55,9 +56,10 @@
case '&': replace = '&'; break;
case '\u00A0'/*NO-BREAK SPACE*/: replace = ' '; break;
case '"': if (mode.escapeQuot) replace = '"'; break;
- case "'": if (mode.escapeApos) replace = '''; break;
+ case "'": if (mode.escapeApos) replace = '''; break;
case '<': if (mode.escapeLtGt) replace = '<'; break;
case '>': if (mode.escapeLtGt) replace = '>'; break;
+ case '/': if (mode.escapeSlash) replace = '/'; break;
}
if (replace != null) {
if (result == null) result = new StringBuffer(text.substring(start, i));
diff --git a/sdk/lib/core/identical.dart b/sdk/lib/core/identical.dart
index 236ce20..cc00c30 100644
--- a/sdk/lib/core/identical.dart
+++ b/sdk/lib/core/identical.dart
@@ -8,3 +8,14 @@
* Check whether two references are to the same object.
*/
external bool identical(Object a, Object b);
+
+/**
+ * Returns the identity hash code of `object`.
+ *
+ * Returns the same value as `object.hashCode` if [object] has not overridden
+ * [Object.hashCode]. Returns the value that [Object.hashCode] would return
+ * on this object, even if `hashCode` has been overridden.
+ *
+ * This hash code is compatible with [identical].
+ */
+external int identityHashCode(Object object);
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index fd3fd01..db187f5 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -22,6 +22,11 @@
factory Map.from(Map<K, V> other) = LinkedHashMap<K, V>.from;
/**
+ * Creates an identity map with the default implementation.
+ */
+ factory Map.identity() = LinkedHashMap<K, V>.identity;
+
+ /**
* Creates a Map instance
* where the keys and values are computed from the [iterable].
*
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index bd6aded..19be402 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -8,7 +8,7 @@
* A collection of objects in which each object can occur only once.
*
* That is, for each object of the element type, the object is either considered
- * to be in the set, or to _not_ be in the set.
+ * to be in the set, or to _not_ be in the set.
*
* Set implementations may consider some elements indistinguishable. These
* elements are treated as being the same for any operation on the set.
@@ -24,11 +24,19 @@
/**
* Creates an empty [Set].
*
- * The created `Set` is a [HashSet]. As such, it considers elements that
- * are equal (using `==`) to be undistinguishable, and requires them to
+ * The created `Set` is a [LinkedHashSet]. As such, it considers elements that
+ * are equal (using `==`) to be indistinguishable, and requires them to
* have a compatible [Object.hashCode] implementation.
*/
- factory Set() => new HashSet<E>();
+ factory Set() = LinkedHashSet<E>;
+
+ /**
+ * Creates an empty identity [Set].
+ *
+ * The created `Set` is a [LinkedHashSet] that uses identity as equality
+ * relation.
+ */
+ factory Set.identity() = LinkedHashSet<E>.identity;
/**
* Creates a [Set] that contains all elements of [other].
@@ -37,7 +45,7 @@
* are equal (using `==`) to be undistinguishable, and requires them to
* have a compatible [Object.hashCode] implementation.
*/
- factory Set.from(Iterable<E> other) => new HashSet<E>.from(other);
+ factory Set.from(Iterable<E> other) = LinkedHashSet<E>.from;
/**
* Returns true if [value] is in the set.
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 2e0259e..488078d 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -5,45 +5,119 @@
part of dart.core;
/**
- * A class for working with a sequence of characters.
+ * A sequence of characters.
+ *
+ * A string can be either single or multiline. Single line strings are
+ * written using matching single or double quotes, and multiline strings are
+ * written using triple quotes. The following are all valid Dart strings:
+ *
+ * 'Single quotes';
+ * "Double quotes";
+ * 'Double quotes in "single" quotes';
+ * "Single quotes in 'double' quotes";
+ *
+ * '''A
+ * multiline
+ * string''';
+ *
+ * """
+ * Another
+ * multiline
+ * string""";
+ *
+ * Strings are immutable. Although you cannot change a string, you can perform
+ * an operation on a string and assign the result to a new string:
+ *
+ * var string = 'Dart is fun';
+ * var newString = string.substring(0, 5);
+ *
+ * You can use the plus (`+`) operator to concatenate strings:
+ *
+ * 'Dart ' + 'is ' + 'fun!'; // 'Dart is fun!'
+ *
+ * You can also use adjacent string literals for concatenation:
+ *
+ * 'Dart ' 'is ' 'fun!'; // 'Dart is fun!'
+ *
+ * You can use `${}` to interpolate the value of Dart expressions
+ * within strings. The curly braces can be omitted when evaluating identifiers:
+ *
+ * string = 'dartlang';
+ * '$string has ${string.length} letters'; // 'dartlang has 8 letters'
*
* A string is represented by a sequence of Unicode UTF-16 code units
- * accessible through the [codeUnitAt] or the [codeUnits] members. Their
- * string representation is accessible through the index-operator.
+ * accessible through the [codeUnitAt] or the [codeUnits] members:
+ *
+ * string = 'Dart';
+ * string.codeUnitAt(0); // 68
+ * string.codeUnits; // [68, 97, 114, 116]
+ *
+ * The string representation of code units is accessible through the index
+ * operator:
+ *
+ * string[0]; // 'D'
*
* The characters of a string are encoded in UTF-16. Decoding UTF-16, which
* combines surrogate pairs, yields Unicode code points. Following a similar
- * terminology to Go we use the name "rune" for an integer representing a
- * Unicode code point. The runes of a string are accessible through the [runes]
- * getter.
+ * terminology to Go, we use the name 'rune' for an integer representing a
+ * Unicode code point. Use the [runes] property to get the runes of a string:
*
- * Strings are immutable.
+ * string.runes.toList(); // [68, 97, 114, 116]
*
- * It is a compile-time error for a class to attempt to extend or implement
- * String.
+ * For a character outside the Basic Multilingual Plane (plane 0) that is
+ * composed of a surrogate pair, [runes] combines the pair and returns a
+ * single integer. For example, the Unicode character for a
+ * musical G-clef ('𝄞') with rune value 0x1D11E consists of a UTF-16 surrogate
+ * pair: `0xD834` and `0xDD1E`. Using [codeUnits] returns the surrogate pair,
+ * and using `runes` returns their combined value:
*
- * For concatenating strings efficiently, use the [StringBuffer] class. For
- * working with regular expressions, use the [RegExp] class.
+ * var clef = '\u{1D11E}';
+ * clef.codeUnits; // [0xD834, 0xDD1E]
+ * clef.runes.toList(); // [0x1D11E]
+ *
+ * The String class can not be extended or implemented. Attempting to do so
+ * yields a compile-time error.
+ *
+ * ## Other resources
+ *
+ * See [StringBuffer] to efficiently build a string incrementally. See
+ * [RegExp] to work with regular expressions.
+ *
+ * Also see:
+
+ * * [Dart Cookbook](https://www.dartlang.org/docs/cookbook/#strings)
+ * for String examples and recipes.
+ * * [Dart Up and Running]
+ * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-strings-and-regular-expressions)
*/
abstract class String implements Comparable<String>, Pattern {
/**
* Allocates a new String for the specified [charCodes].
*
* The [charCodes] can be UTF-16 code units or runes. If a char-code value is
- * 16-bit it is copied verbatim. If it is greater than 16 bits it is
- * decomposed into a surrogate pair.
+ * 16-bit, it is copied verbatim:
+ *
+ * new String.fromCharCodes([68]); // 'D'
+ *
+ * If a char-code value is greater than 16-bits, it is decomposed into a
+ * surrogate pair:
+ *
+ * var clef = new String.fromCharCodes([0x1D11E]);
+ * clef.codeUnitAt(0); // 0xD834
+ * clef.codeUnitAt(1); // 0xDD1E
*/
external factory String.fromCharCodes(Iterable<int> charCodes);
/**
* Allocates a new String for the specified [charCode].
*
- * The new string contains a single code unit if the [charCode] can be
- * represented by a single UTF-16 code unit. Otherwise the [length] is 2 and
- * the code units form a surrogate pair.
+ * If the [charCode] can be represented by a single UTF-16 code unit, the new
+ * string contains a single code unit. Otherwise, the [length] is 2 and
+ * the code units form a surrogate pair. See documentation for
+ * [fromCharCodes].
*
- * It is allowed (though generally discouraged) to create a String with only
- * one half of a surrogate pair.
+ * Creating a String with half of a surrogate pair is legal but generally
+ * discouraged.
*/
factory String.fromCharCode(int charCode) {
List<int> charCodes = new List<int>.filled(1, charCode);
@@ -53,22 +127,14 @@
/**
* Gets the character (as a single-code-unit [String]) at the given [index].
*
- * The returned string represents exactly one UTF-16 code unit which may be
- * half of a surrogate pair. For example the Unicode character for a
- * musical G-clef ("𝄞") with rune value 0x1D11E consists of a UTF-16 surrogate
- * pair: `0xD834` and `0xDD1E`. Using the index-operator on this string yields
- * a String with half of a surrogate pair:
+ * The returned string represents exactly one UTF-16 code unit, which may be
+ * half of a surrogate pair. A single member of a surrogate pair is an
+ * invalid UTF-16 string:
*
- * var clef = "\u{1D11E}";
- * clef.length; // => 2
- * clef.runes.first == 0x1D11E; // => true
- * clef.runes.length; // => 1
- * clef.codeUnitAt(0); // => 0xD834
- * clef.codeUnitAt(1); // => 0xDD1E
- * // The following strings are halves of a UTF-16 surrogate pair and
- * // thus invalid UTF-16 strings:
- * clef[0]; // => a string of length 1 with code-unit value 0xD834.
- * clef[1]; // => a string of length 1 with code-unit value 0xDD1E.
+ * var clef = '\u{1D11E}';
+ * // These represent invalid UTF-16 strings.
+ * clef[0].codeUnits; // [0xD834]
+ * clef[1].codeUnits; // [0xDD1E]
*
* This method is equivalent to
* `new String.fromCharCode(this.codeUnitAt(index))`.
@@ -84,101 +150,137 @@
* The length of the string.
*
* Returns the number of UTF-16 code units in this string. The number
- * of [runes] might be less, if the string contains characters outside
- * the basic multilingual plane (plane 0).
+ * of [runes] might be fewer, if the string contains characters outside
+ * the Basic Multilingual Plane (plane 0):
+ *
+ * 'Dart'.length; // 4
+ * 'Dart'.runes.length; // 4
+ *
+ * var clef = '\u{1D11E}';
+ * clef.length; // 2
+ * clef.runes.length; // 1
*/
int get length;
/**
- * Returns whether the two strings are equal.
+ * Returns true if the two strings are equal. False, otherwise.
*
* This method compares each individual code unit of the strings.
- * Equivalently (for strings that are well-formed UTF-16) it compares each
- * individual rune (code point). It does not check for Unicode equivalence.
- * For example the two following strings both represent the string "Amélie"
- * but, due to their different encoding will not return equal.
+ * It does not check for Unicode equivalence.
+ * For example, both the following strings represent the string 'Amélie',
+ * but due to their different encoding, are not equal:
*
- * "Am\xe9lie"
- * "Ame\u{301}lie"
+ * 'Am\xe9lie' == 'Ame\u{301}lie'; // false
*
- * In the first string the "é" is encoded as a single unicode code unit (also
- * a single rune), whereas the second string encodes it as "e" with the
- * combining accent character "◌́".
+ * The first string encodes 'é' as a single unicode code unit (also
+ * a single rune), whereas the second string encodes it as 'e' with the
+ * combining accent character '◌́'.
*/
bool operator ==(var other);
/**
- * Returns whether this string ends with [other].
+ * Returns true if this string ends with [other]. For example:
+ *
+ * 'Dart'.endsWith('t'); // true
*/
bool endsWith(String other);
/**
- * Returns whether this string starts with a match of [pattern].
+ * Returns true if this string starts with a match of [pattern].
*
- * If [index] is provided, instead check if the substring starting
- * at that index starts with a match of [pattern].
+ * var string = 'Dart';
+ * string.startsWith('D'); // true
+ * string.startsWith(new RegExp(r'[A-Z][a-z]')); // true
*
- * It is an error if [index] is negative or greater than [length].
+ * If [index] is provided, this method checks if the substring starting
+ * at that index starts with a match of [pattern]:
*
- * A [RegExp] containing "^" will not match if the [index] is greater than
+ * string.startsWith('art', 1); // true
+ * string.startsWith(new RegExp(r'\w{3}')); // true
+ *
+ * [index] must not be negative or greater than [length].
+ *
+ * A [RegExp] containing '^' does not match if the [index] is greater than
* zero. The pattern works on the string as a whole, and does not extract
- * a substring starting at [index] first. That is.
- * "abc".startsWith(new RegExp("^.", 1)) == false
+ * a substring starting at [index] first:
+ *
+ * string.startsWith(new RegExp(r'^art'), 1); // false
+ * string.startsWith(new RegExp(r'art'), 1); // true
*/
bool startsWith(Pattern pattern, [int index = 0]);
/**
- * Returns the first position of a match of [pattern] in this string,
- * starting at [start] (inclusive).
+ * Returns the position of the first match of [pattern] in this string,
+ * starting at [start], inclusive:
*
- * Returns -1 if a match could not be found.
+ * var string = 'Dartisans';
+ * string.indexOf('art'); // 1
+ * string.indexOf(new RegExp(r'[A-Z][a-z]')); // 0
*
- * It is an error if start is negative or greater than [length].
+ * Returns -1 if no match is found:
+ *
+ * string.indexOf(new RegExp(r'dart')); // -1
+ *
+ * [start] must not be negative or greater than [length].
*/
int indexOf(Pattern pattern, [int start]);
/**
- * Returns the last position of a match [pattern] in this string, searching
- * backward starting at [start] (inclusive).
+ * Returns the position of the last match [pattern] in this string, searching
+ * backward starting at [start], inclusive:
+ *
+ * var string = 'Dartisans';
+ * string.lastIndexOf('a'); // 6
+ * string.lastIndexOf(new RegExp(r'a(r|n)')); // 6
*
* Returns -1 if [other] could not be found.
*
- * It is an error if start is negative or greater than [length].
+ * string.lastIndexOf(new RegExp(r'DART')); // -1
+ *
+ * [start] must not be negative or greater than [length].
*/
int lastIndexOf(Pattern pattern, [int start]);
/**
- * Returns whether this string is empty.
+ * Returns true if this string is empty.
*/
bool get isEmpty;
/**
- * Returns whether this string is not empty.
+ * Returns true if this string is not empty.
*/
bool get isNotEmpty;
/**
* Creates a new string by concatenating this string with [other].
*
- * A sequence of strings can be concatenated by using [Iterable.join]:
- *
- * var strings = ['foo', 'bar', 'geez'];
- * var concatenated = strings.join();
+ * 'dart' + 'lang'; // 'dartlang'
*/
String operator +(String other);
/**
- * Returns a substring of this string in the given range.
- * [startIndex] is inclusive and [endIndex] is exclusive.
+ * Returns the substring of this string that extends from [startIndex],
+ * inclusive, to [endIndex], exclusive.
+ *
+ * var string = 'dartlang';
+ * string.substring(1); // 'artlang'
+ * string.substring(1, 4); // 'art'
*/
String substring(int startIndex, [int endIndex]);
/**
* Removes leading and trailing whitespace from a string.
*
- * If the string contains leading or trailing whitespace a new string with no
- * leading and no trailing whitespace is returned. Otherwise, the string
- * itself is returned.
+ * If the string contains leading or trailing whitespace, a new string with no
+ * leading and no trailing whitespace is returned:
+ *
+ * '\tDart is fun\n'.trim(); // 'Dart is fun'
+ *
+ * Otherwise, the original string itself is returned:
+ *
+ * var str1 = 'Dart';
+ * var str2 = str1.trim();
+ * identical(str1, str2); // true
*
* Whitespace is defined by the Unicode White_Space property (as defined in
* version 6.2 or later) and the BOM character, 0xFEFF.
@@ -203,28 +305,39 @@
String trim();
/**
- * Returns whether this string contains a match of [other].
+ * Returns true if this string contains a match of [other]:
*
- * If [startIndex] is provided, only matches at or after that index
- * are considered.
+ * var string = 'Dart strings';
+ * string.contains('D'); // true
+ * string.contains(new RegExp(r'[A-Z]')); // true
*
- * It is an error if [startIndex] is negative or greater than [length].
+ * If [startIndex] is provided, this method matches only at or after that
+ * index:
+ *
+ * string.contains('X', 1); // false
+ * string.contains(new RegExp(r'[A-Z]'), 1); // false
+ *
+ * [startIndex] must not be negative or greater than [length].
*/
bool contains(Pattern other, [int startIndex = 0]);
/**
- * Returns a new string where the first occurence of [from] in this string
- * is replaced with [to].
+ * Returns a new string in which the first occurence of [from] in this string
+ * is replaced with [to]:
+ *
+ * '0.0001'.replaceFirst(new RegExp(r'0'), ''); // '.0001'
*/
String replaceFirst(Pattern from, String to);
/**
- * Replaces all substrings matching [from] with [replace].
+ * Replaces all substrings that match [from] with [replace].
*
- * Returns a new string where the non-overlapping substrings that match
+ * Returns a new string in which the non-overlapping substrings matching
* [from] (the ones iterated by `from.allMatches(thisString)`) are replaced
* by the literal string [replace].
*
+ * 'resume'.replaceAll(new RegExp(r'e'), 'é'); // 'résumé'
+ *
* Notice that the [replace] string is not interpreted. If the replacement
* depends on the match (for example on a [RegExp]'s capture groups), use
* the [replaceAllMapped] method instead.
@@ -232,50 +345,61 @@
String replaceAll(Pattern from, String replace);
/**
- * Replace all substrings matching [from] by a string computed from the match.
+ * Replace all substrings that match [from] by a string computed from the
+ * match.
*
- * Returns a new string where the non-overlapping substrings that match
+ * Returns a new string in which the non-overlapping substrings that match
* [from] (the ones iterated by `from.allMatches(thisString)`) are replaced
* by the result of calling [replace] on the corresponding [Match] object.
*
* This can be used to replace matches with new content that depends on the
* match, unlike [replaceAll] where the replacement string is always the same.
*
- * Example (simplified pig latin):
+ * The [replace] function is called with the [Match] generated
+ * by the pattern, and its result is used as replacement.
+ *
+ * The function defined below converts each word in a string to simplified
+ * 'pig latin' using [replaceAllMapped]:
+ *
* pigLatin(String words) => words.replaceAllMapped(
- * new RegExp(r"\b(\w*?)([aeiou]\w*)", caseSensitive: false),
+ * new RegExp(r'\b(\w*?)([aeiou]\w*)', caseSensitive: false),
* (Match m) => "${m[2]}${m[1]}${m[1].isEmpty ? 'way' : 'ay'}");
*
- * This would convert each word of a text to "pig-latin", so for example
- * `pigLatin("I have a secret now!")`
- * returns
- * `"Iway avehay away ecretsay ownay!"`
+ * pigLatin('I have a secret now!'); // 'Iway avehay away ecretsay ownay!'
*/
String replaceAllMapped(Pattern from, String replace(Match match));
/**
- * Splits the string around matches of [pattern]. Returns
+ * Splits the string at matches of [pattern]. Returns
* a list of substrings.
*
- * Splitting with an empty string pattern (`""`) splits at UTF-16 code unit
- * boundaries and not at rune boundaries. The following two expressions
- * are hence equivalent:
+ * Splitting with an empty string pattern (`''`) splits at UTF-16 code unit
+ * boundaries and not at rune boundaries:
*
- * string.split("")
- * string.codeUnits.map((unit) => new String.fromCharCode(unit))
+ * var string = 'Pub';
+ * string.split(''); // ['P', 'u', 'b']
*
- * Unless it guaranteed that the string is in the basic multilingual plane
- * (meaning that each code unit represents a rune) it is often better to
- * map the runes instead:
+ * string.codeUnits.map((unit) {
+ * return new String.fromCharCode(unit);
+ * }).toList(); // ['P', 'u', 'b']
*
- * string.runes.map((rune) => new String.fromCharCode(rune))
+ * // String made up of two code units, but one rune.
+ * string = '\u{1D11E}';
+ * string.split('').length; // 2
+ *
+ * You should [map] the runes unless you are certain that the string is in
+ * the basic multilingual plane (meaning that each code unit represents a
+ * rune):
+ *
+ * string.runes.map((rune) => new String.fromCharCode(rune));
*/
List<String> split(Pattern pattern);
/**
- * Splits the string on the [pattern], then converts each part and each match.
+ * Splits the string, converts its parts, and combines them into a new
+ * string.
*
- * The pattern is used to split the string into parts and separating matches.
+ * [pattern] is used to split the string into parts and separating matches.
*
* Each match is converted to a string by calling [onMatch]. If [onMatch]
* is omitted, the matched string is used.
@@ -284,6 +408,10 @@
* [onNonMatch] is omitted, the non-matching part is used.
*
* Then all the converted parts are combined into the resulting string.
+ *
+ * 'Eats shoots leaves'.splitMapJoin((new RegExp(r'shoots')),
+ * onMatch: (m) => '${m.group(0)}',
+ * onNonMatch: (n) => '*'); // *shoots*
*/
String splitMapJoin(Pattern pattern,
{String onMatch(Match match),
@@ -295,24 +423,36 @@
List<int> get codeUnits;
/**
- * Returns an iterable of Unicode code-points of this string.
+ * Returns an [Iterable] of Unicode code-points of this string.
*
- * If the string contains surrogate pairs, they will be combined and returned
+ * If the string contains surrogate pairs, they are combined and returned
* as one integer by this iterator. Unmatched surrogate halves are treated
* like valid 16-bit code-units.
*/
Runes get runes;
/**
- * If this string is not already all lower case, returns a new string
- * where all characters are made lower case. Returns [:this:] otherwise.
+ * Converts all characters in this string to lower case.
+ * If the string is already in all lower case, this method returns [:this:].
+ *
+ * 'ALPHABET'.toLowerCase(); // 'alphabet'
+ * 'abc'.toLowerCase(); // 'abc'
+ *
+ * This function uses the language independent Unicode mapping and thus only
+ * works in some languages.
*/
// TODO(floitsch): document better. (See EcmaScript for description).
String toLowerCase();
/**
- * If this string is not already all upper case, returns a new string
- * where all characters are made upper case. Returns [:this:] otherwise.
+ * Converts all characters in this string to upper case.
+ * If the string is already in all upper case, this method returns [:this:].
+ *
+ * 'alphabet'.toUpperCase(); // 'ALPHABET'
+ * 'ABC'.toUpperCase(); // 'ABC'
+ *
+ * This function uses the language independent Unicode mapping and thus only
+ * works in some languages.
*/
// TODO(floitsch): document better. (See EcmaScript for description).
String toUpperCase();
@@ -329,7 +469,7 @@
int get last {
if (string.length == 0) {
- throw new StateError("No elements.");
+ throw new StateError('No elements.');
}
int length = string.length;
int code = string.codeUnitAt(length - 1);
@@ -401,7 +541,7 @@
if (index > 0 && index < string.length &&
_isLeadSurrogate(string.codeUnitAt(index - 1)) &&
_isTrailSurrogate(string.codeUnitAt(index))) {
- throw new ArgumentError("Index inside surrogate pair: $index");
+ throw new ArgumentError('Index inside surrogate pair: $index');
}
}
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 328b995..f645d2c 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -358,6 +358,17 @@
return windows ? _makeWindowsFileUrl(path) : _makeFileUri(path);
}
+ /**
+ * Returns the natural base URI for the current platform.
+ *
+ * When running in a browser this is the current URL (from
+ * `window.location.href`).
+ *
+ * When not running in a browser this is the file URI referencing
+ * the current working directory.
+ */
+ external static Uri get base;
+
external static bool get _isWindows;
static _checkNonWindowsPathReservedCharacters(List<String> segments,
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 21dbe97..f1199d0 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -7169,10 +7169,10 @@
@DocsEditable()
DocumentFragment createDocumentFragment() native;
- /// Deprecated: use new Element.tag(tagName) instead.
+ @JSName('createElement')
@DomName('Document.createElement')
@DocsEditable()
- Element createElement(String localName_OR_tagName, [String typeExtension]) native;
+ Element _createElement(String localName_OR_tagName, [String typeExtension]) native;
@DomName('Document.createElementNS')
@DocsEditable()
@@ -7626,6 +7626,11 @@
bool get supportsRegister {
return JS('bool', '("register" in #)', this);
}
+
+ @DomName('Document.createElement')
+ Element createElement(String tagName, [String typeExtension]) {
+ return _createElement(tagName, typeExtension);
+ }
}
// 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
@@ -9146,6 +9151,20 @@
@Experimental()
void created() {}
+ /**
+ * Called by the DOM when this element has been inserted into the live
+ * document.
+ */
+ @Experimental()
+ void enteredView() {}
+
+ /**
+ * Called by the DOM when this element has been removed from the live
+ * document.
+ */
+ @Experimental()
+ void leftView() {}
+
// Hooks to support custom WebComponents.
@Creates('Null') // Set from Dart code; does not instantiate a native type.
@@ -12813,9 +12832,9 @@
* * UListElement
* * VideoElement
*/
- void register(String tag, Type customElementClass, {String nativeTagName}) {
+ void register(String tag, Type customElementClass, {String extendsTag}) {
_registerCustomElement(JS('', 'window'), this, tag, customElementClass,
- nativeTagName);
+ extendsTag);
}
@Creates('Null') // Set from Dart code; does not instantiate a native type.
@@ -12949,8 +12968,9 @@
/**
* Makes a server POST request with the specified data encoded as form data.
*
- * This is similar to sending a FormData object with broader browser
- * support but limited to string values.
+ * This is roughly the POST equivalent of getString. This method is similar
+ * to sending a FormData object with broader browser support but limited to
+ * String values.
*
* See also:
*
@@ -12983,11 +13003,15 @@
/**
* Creates a URL request for the specified [url].
*
- * By default this will do an HTTP GET request, this can be overridden with
- * [method].
+ * By default `request` will perform an HTTP GET request, but a different
+ * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
+ * [method] parameter.
*
* The Future is completed when the response is available.
*
+ * If specified, `sendData` will send data in the form of a [ByteBuffer],
+ * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
+ *
* The [withCredentials] parameter specified that credentials such as a cookie
* (already) set in the header or
* [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
@@ -13380,6 +13404,11 @@
*
* Calling `open` again on a currently active request is equivalent to
* calling `abort`.
+ *
+ * Note: Most simple HTTP requests can be accomplished using the [getString],
+ * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
+ * `open` method is intended only for more complext HTTP requests where
+ * finer-grained control is needed.
*/
@DomName('XMLHttpRequest.open')
@DocsEditable()
@@ -13402,6 +13431,11 @@
/**
* Send the request with any given `data`.
*
+ * Note: Most simple HTTP requests can be accomplished using the [getString],
+ * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
+ * `send` method is intended only for more complext HTTP requests where
+ * finer-grained control is needed.
+ *
* See also:
*
* * [send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
@@ -13430,32 +13464,6 @@
@DocsEditable()
-@DomName('XMLHttpRequestProgressEvent')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-@Experimental() // nonstandard
-class HttpRequestProgressEvent extends ProgressEvent native "XMLHttpRequestProgressEvent" {
- // To suppress missing implicit constructor warnings.
- factory HttpRequestProgressEvent._() { throw new UnsupportedError("Not supported"); }
-
- /// Checks if this type is supported on the current platform.
- static bool get supported => Device.isEventTypeSupported('XMLHttpRequestProgressEvent');
-
- @DomName('XMLHttpRequestProgressEvent.position')
- @DocsEditable()
- final int position;
-
- @DomName('XMLHttpRequestProgressEvent.totalSize')
- @DocsEditable()
- final int totalSize;
-}
-// Copyright (c) 2012, 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.
-
-
-@DocsEditable()
@DomName('XMLHttpRequestUpload')
// http://xhr.spec.whatwg.org/#xmlhttprequestupload
@Experimental()
@@ -27574,6 +27582,18 @@
// BSD-style license that can be found in the LICENSE file.
+@DocsEditable()
+@DomName('XMLHttpRequestProgressEvent')
+@Experimental() // nonstandard
+abstract class _XMLHttpRequestProgressEvent extends ProgressEvent native "XMLHttpRequestProgressEvent" {
+ // To suppress missing implicit constructor warnings.
+ factory _XMLHttpRequestProgressEvent._() { throw new UnsupportedError("Not supported"); }
+}
+// Copyright (c) 2012, 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.
+
+
abstract class _AttributeMap implements Map<String, String> {
final Element _element;
@@ -28623,11 +28643,17 @@
var _onData;
final bool _useCapture;
- _EventStreamSubscription(this._target, this._eventType, this._onData,
- this._useCapture) {
+ _EventStreamSubscription(this._target, this._eventType, onData,
+ this._useCapture) : _onData = _wrapZone(onData) {
_tryResume();
}
+ static _wrapZone(callback) {
+ // For performance reasons avoid wrapping if we are in the root zone.
+ if (Zone.current == Zone.ROOT) return callback;
+ return Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ }
+
void cancel() {
if (_canceled) return;
@@ -28646,7 +28672,7 @@
// Remove current event listener.
_unlisten();
- _onData = handleData;
+ _onData = _wrapZone(handleData);
_tryResume();
}
@@ -32037,14 +32063,22 @@
return receiver.created();
}
-_makeCreatedCallbackMethod() {
+_callEnteredView(receiver) {
+ return receiver.enteredView();
+}
+
+_callLeftView(receiver) {
+ return receiver.leftView();
+}
+
+_makeCallbackMethod(callback) {
return JS('',
'''((function(invokeCallback) {
return function() {
return invokeCallback(this);
};
})(#))''',
- convertDartClosureToJS(_callCreated, 1));
+ convertDartClosureToJS(callback, 1));
}
const _typeNameToTag = const {
@@ -32106,10 +32140,18 @@
var properties = JS('=Object', '{}');
- var jsCreatedCallback = _makeCreatedCallbackMethod();
-
JS('void', '#.createdCallback = #', properties,
- JS('=Object', '{value: #}', jsCreatedCallback));
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callCreated)));
+ JS('void', '#.enteredViewCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
+ JS('void', '#.leftViewCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
+
+ // TODO(blois): Bug 13220- remove once transition is complete
+ JS('void', '#.enteredDocumentCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
+ JS('void', '#.leftDocumentCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
var baseProto = JS('=Object', '#.prototype', baseConstructor);
var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 4a62082..106ac6c 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -7707,33 +7707,13 @@
@DocsEditable()
DocumentFragment createDocumentFragment() native "Document_createDocumentFragment_Callback";
- Element createElement(String localName_OR_tagName, [String typeExtension]) {
- if ((localName_OR_tagName is String || localName_OR_tagName == null) && typeExtension == null) {
- return _createElement_1(localName_OR_tagName);
- }
- if ((typeExtension is String || typeExtension == null) && (localName_OR_tagName is String || localName_OR_tagName == null)) {
- return _createElement_2(localName_OR_tagName, typeExtension);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
+ @DomName('Document.createElement')
+ @DocsEditable()
+ Element _createElement(String localName_OR_tagName, [String typeExtension]) native "Document_createElement_Callback";
- Element _createElement_1(localName_OR_tagName) native "Document__createElement_1_Callback";
-
- Element _createElement_2(localName_OR_tagName, typeExtension) native "Document__createElement_2_Callback";
-
- Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
- if ((qualifiedName is String || qualifiedName == null) && (namespaceURI is String || namespaceURI == null) && typeExtension == null) {
- return _createElementNS_1(namespaceURI, qualifiedName);
- }
- if ((typeExtension is String || typeExtension == null) && (qualifiedName is String || qualifiedName == null) && (namespaceURI is String || namespaceURI == null)) {
- return _createElementNS_2(namespaceURI, qualifiedName, typeExtension);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
-
- Element _createElementNS_1(namespaceURI, qualifiedName) native "Document__createElementNS_1_Callback";
-
- Element _createElementNS_2(namespaceURI, qualifiedName, typeExtension) native "Document__createElementNS_2_Callback";
+ @DomName('Document.createElementNS')
+ @DocsEditable()
+ Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) native "Document_createElementNS_Callback";
@DomName('Document.createEvent')
@DocsEditable()
@@ -8187,6 +8167,16 @@
bool get supportsRegister {
return true;
}
+
+ @DomName('Document.createElement')
+ Element createElement(String tagName, [String typeExtension]) {
+ if (typeExtension != null) {
+ return _createElement(tagName, typeExtension);
+ } else {
+ // Fast-path for Dartium when typeExtension is not needed.
+ return _Utils.createElement(this, tagName);
+ }
+ }
}
// 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
@@ -9729,6 +9719,20 @@
@Experimental()
void created() {}
+ /**
+ * Called by the DOM when this element has been inserted into the live
+ * document.
+ */
+ @Experimental()
+ void enteredView() {}
+
+ /**
+ * Called by the DOM when this element has been removed from the live
+ * document.
+ */
+ @Experimental()
+ void leftView() {}
+
// Hooks to support custom WebComponents.
Element _xtag;
@@ -13352,8 +13356,8 @@
* * UListElement
* * VideoElement
*/
- void register(String tag, Type customElementClass, {String nativeTagName}) {
- _Utils.register(tag, customElementClass);
+ void register(String tag, Type customElementClass, {String extendsTag}) {
+ _Utils.register(this, tag, customElementClass, extendsTag);
}
// Note: used to polyfill <template>
@@ -13634,8 +13638,9 @@
/**
* Makes a server POST request with the specified data encoded as form data.
*
- * This is similar to sending a FormData object with broader browser
- * support but limited to string values.
+ * This is roughly the POST equivalent of getString. This method is similar
+ * to sending a FormData object with broader browser support but limited to
+ * String values.
*
* See also:
*
@@ -13668,11 +13673,15 @@
/**
* Creates a URL request for the specified [url].
*
- * By default this will do an HTTP GET request, this can be overridden with
- * [method].
+ * By default `request` will perform an HTTP GET request, but a different
+ * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
+ * [method] parameter.
*
* The Future is completed when the response is available.
*
+ * If specified, `sendData` will send data in the form of a [ByteBuffer],
+ * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
+ *
* The [withCredentials] parameter specified that credentials such as a cookie
* (already) set in the header or
* [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
@@ -14045,6 +14054,11 @@
*
* Calling `open` again on a currently active request is equivalent to
* calling `abort`.
+ *
+ * Note: Most simple HTTP requests can be accomplished using the [getString],
+ * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
+ * `open` method is intended only for more complext HTTP requests where
+ * finer-grained control is needed.
*/
@DomName('XMLHttpRequest.open')
@DocsEditable()
@@ -14067,6 +14081,11 @@
/**
* Send the request with any given `data`.
*
+ * Note: Most simple HTTP requests can be accomplished using the [getString],
+ * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
+ * `send` method is intended only for more complext HTTP requests where
+ * finer-grained control is needed.
+ *
* See also:
*
* * [send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
@@ -14097,35 +14116,6 @@
@DocsEditable()
-@DomName('XMLHttpRequestProgressEvent')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-@Experimental() // nonstandard
-class HttpRequestProgressEvent extends ProgressEvent {
- // To suppress missing implicit constructor warnings.
- factory HttpRequestProgressEvent._() { throw new UnsupportedError("Not supported"); }
-
- /// Checks if this type is supported on the current platform.
- static bool get supported => true;
-
- @DomName('XMLHttpRequestProgressEvent.position')
- @DocsEditable()
- int get position native "XMLHttpRequestProgressEvent_position_Getter";
-
- @DomName('XMLHttpRequestProgressEvent.totalSize')
- @DocsEditable()
- int get totalSize native "XMLHttpRequestProgressEvent_totalSize_Getter";
-
-}
-// Copyright (c) 2012, 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
@DomName('XMLHttpRequestUpload')
// http://xhr.spec.whatwg.org/#xmlhttprequestupload
@Experimental()
@@ -26124,13 +26114,13 @@
if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
return _createObjectURL_1(blob_OR_source_OR_stream);
}
- if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
+ if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
return _createObjectURL_2(blob_OR_source_OR_stream);
}
- if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
+ if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
return _createObjectURL_3(blob_OR_source_OR_stream);
}
- if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
+ if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
return _createObjectURL_4(blob_OR_source_OR_stream);
}
throw new ArgumentError("Incorrect number or type of arguments");
@@ -29679,6 +29669,21 @@
// 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.
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable()
+@DomName('XMLHttpRequestProgressEvent')
+@Experimental() // nonstandard
+abstract class _XMLHttpRequestProgressEvent extends ProgressEvent {
+ // To suppress missing implicit constructor warnings.
+ factory _XMLHttpRequestProgressEvent._() { throw new UnsupportedError("Not supported"); }
+
+}
+// Copyright (c) 2012, 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.
+
abstract class _AttributeMap implements Map<String, String> {
final Element _element;
@@ -30729,11 +30734,17 @@
var _onData;
final bool _useCapture;
- _EventStreamSubscription(this._target, this._eventType, this._onData,
- this._useCapture) {
+ _EventStreamSubscription(this._target, this._eventType, onData,
+ this._useCapture) : _onData = _wrapZone(onData) {
_tryResume();
}
+ static _wrapZone(callback) {
+ // For performance reasons avoid wrapping if we are in the root zone.
+ if (Zone.current == Zone.ROOT) return callback;
+ return Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ }
+
void cancel() {
if (_canceled) return;
@@ -30752,7 +30763,7 @@
// Remove current event listener.
_unlisten();
- _onData = handleData;
+ _onData = _wrapZone(handleData);
_tryResume();
}
@@ -34469,7 +34480,7 @@
class _ConsoleVariables {
Map<String, Object> _data = new Map<String, Object>();
-
+
/**
* Forward member accesses to the backing JavaScript object.
*/
@@ -34485,7 +34496,7 @@
return Function.apply(_data[member], invocation.positionalArguments, invocation.namedArguments);
}
}
-
+
void clear() => _data.clear();
/**
@@ -34556,6 +34567,17 @@
return new UnsupportedError('[info: $fileName:$lineNo]');
}
+ static bool isTypeSubclassOf(Type type, Type other) {
+ if (type == other) {
+ return true;
+ }
+ var superclass = reflectClass(type).superclass;
+ if (superclass != null) {
+ return isTypeSubclassOf(superclass.reflectedType, other);
+ }
+ return false;
+ }
+
static window() native "Utils_window";
static forwardingPrint(String message) native "Utils_forwardingPrint";
static void spawnDomFunction(Function f, int replyTo) native "Utils_spawnDomFunction";
@@ -34624,13 +34646,13 @@
sb.write("final $arg");
args[arg] = value;
}
-
+
addArg("\$var", _consoleTempVariables);
-
+
for (int i = 0; i < locals.length; i+= 2) {
addArg(locals[i], locals[i+1]);
}
- sb..write(')=>\n$expression');
+ sb..write(')=>\n$expression');
return [sb.toString(), args.values.toList(growable: false)];
}
@@ -34647,10 +34669,10 @@
* prepended to disambuguate. This scheme is simplistic but easy to encode and
* decode. The use case for this method is displaying all map keys in a human
* readable way in debugging tools.
- */
+ */
static List<String> getEncodedMapKeyList(dynamic obj) {
if (obj is! Map) return null;
-
+
var ret = new List<String>();
int i = 0;
return obj.keys.map((key) {
@@ -34734,40 +34756,20 @@
return libName.startsWith('dart:');
}
- static void register(String tag, Type type) {
+ static void register(Document document, String tag, Type type,
+ String extendsTagName) {
// TODO(vsm): Move these checks into native code.
- if (type == null) {
- throw new UnsupportedError("Invalid null type.");
- }
ClassMirror cls = reflectClass(type);
if (_isBuiltinType(cls)) {
throw new UnsupportedError("Invalid custom element from $libName.");
}
- ClassMirror superClass = cls.superclass;
-
- Symbol objectName = reflectClass(Object).qualifiedName;
- bool isRoot(ClassMirror cls) =>
- cls == null || cls.qualifiedName == objectName;
- // TODO(vsm): Support extending SvgElement as well.
- Symbol elementName = reflectClass(HtmlElement).qualifiedName;
- bool isElement(ClassMirror cls) =>
- cls != null && cls.qualifiedName == elementName;
-
- ClassMirror nativeClass = _isBuiltinType(superClass) ? superClass : null;
- while(!isRoot(superClass) && !isElement(superClass)) {
- superClass = superClass.superclass;
- if (nativeClass == null && _isBuiltinType(superClass)) {
- nativeClass = superClass;
- }
- }
-
- if (isRoot(superClass)) {
- throw new UnsupportedError("Invalid custom element doesn't inherit from HtmlElement.");
- }
- _register(tag, type, nativeClass.reflectedType);
+ _register(document, tag, type, extendsTagName);
}
- static void _register(String tag, Type customType, Type nativeType) native "Utils_register";
+ static void _register(Document document, String tag, Type customType,
+ String extendsTagName) native "Utils_register";
+
+ static Element createElement(Document document, String tagName) native "Utils_createElement";
}
class _NPObject extends NativeFieldWrapperClass1 {
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 8e4cf12..671064c 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -54,7 +54,7 @@
* directory once it has been created. If the directory cannot be
* created the future completes with an exception.
*/
- Future<Directory> create({recursive: false});
+ Future<Directory> create({bool recursive: false});
/**
* Synchronously creates the directory with this name.
@@ -65,7 +65,7 @@
*
* If the directory cannot be created an exception is thrown.
*/
- void createSync({recursive: false});
+ void createSync({bool recursive: false});
/**
* Creates a temporary directory with a name based on the current
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 61a226a..d1258fb 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -15,7 +15,6 @@
static const RENAME_REQUEST = 7;
final String path;
- SendPort _directoryService;
_Directory(String this.path) {
if (path is! String) {
@@ -32,7 +31,6 @@
external static _deleteNative(String path, bool recursive);
external static _rename(String path, String newPath);
external static List _list(String path, bool recursive, bool followLinks);
- external static SendPort _newServicePort();
static Directory get current {
var result = _current();
@@ -54,11 +52,7 @@
}
Future<bool> exists() {
- _ensureDirectoryService();
- List request = new List(2);
- request[0] = EXISTS_REQUEST;
- request[1] = path;
- return _directoryService.call(request).then((response) {
+ return _IOService.dispatch(_DIRECTORY_EXISTS, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionOrErrorFromResponse(response, "Exists failed");
}
@@ -131,13 +125,9 @@
});
}
- Future<Directory> create({recursive: false}) {
+ Future<Directory> create({bool recursive: false}) {
if (recursive) return createRecursively();
- _ensureDirectoryService();
- List request = new List(2);
- request[0] = CREATE_REQUEST;
- request[1] = path;
- return _directoryService.call(request).then((response) {
+ return _IOService.dispatch(_DIRECTORY_CREATE, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionOrErrorFromResponse(response, "Creation failed");
}
@@ -160,7 +150,7 @@
}
}
- void createSync({recursive: false}) {
+ void createSync({bool recursive: false}) {
if (recursive) return createRecursivelySync();
var result = _create(path);
if (result is OSError) {
@@ -169,11 +159,7 @@
}
Future<Directory> createTemp() {
- _ensureDirectoryService();
- List request = new List(2);
- request[0] = CREATE_TEMP_REQUEST;
- request[1] = path;
- return _directoryService.call(request).then((response) {
+ return _IOService.dispatch(_DIRECTORY_CREATE_TEMP, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionOrErrorFromResponse(
response, "Creation of temporary directory failed");
@@ -192,21 +178,17 @@
return new Directory(result);
}
- Future<Directory> _delete({recursive: false}) {
- _ensureDirectoryService();
- List request = new List(3);
- request[0] = DELETE_REQUEST;
- request[1] = path;
- request[2] = recursive;
- return _directoryService.call(request).then((response) {
- if (_isErrorResponse(response)) {
- throw _exceptionOrErrorFromResponse(response, "Deletion failed");
- }
- return this;
- });
+ Future<Directory> _delete({bool recursive: false}) {
+ return _IOService.dispatch(_DIRECTORY_DELETE, [path, recursive])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionOrErrorFromResponse(response, "Deletion failed");
+ }
+ return this;
+ });
}
- void _deleteSync({recursive: false}) {
+ void _deleteSync({bool recursive: false}) {
var result = _deleteNative(path, recursive);
if (result is OSError) {
throw new DirectoryException("Deletion failed", path, result);
@@ -214,17 +196,13 @@
}
Future<Directory> rename(String newPath) {
- _ensureDirectoryService();
- List request = new List(3);
- request[0] = RENAME_REQUEST;
- request[1] = path;
- request[2] = newPath;
- return _directoryService.call(request).then((response) {
- if (_isErrorResponse(response)) {
- throw _exceptionOrErrorFromResponse(response, "Rename failed");
- }
- return new Directory(newPath);
- });
+ return _IOService.dispatch(_DIRECTORY_RENAME, [path, newPath])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionOrErrorFromResponse(response, "Rename failed");
+ }
+ return new Directory(newPath);
+ });
}
Directory renameSync(String newPath) {
@@ -275,12 +253,6 @@
return new Exception("Unknown error");
}
}
-
- void _ensureDirectoryService() {
- if (_directoryService == null) {
- _directoryService = _newServicePort();
- }
- }
}
class _AsyncDirectoryLister {
@@ -317,8 +289,7 @@
Stream get stream => controller.stream;
void onListen() {
- var request = [_Directory.LIST_START_REQUEST, path, recursive, followLinks];
- _Directory._newServicePort().call(request)
+ _IOService.dispatch(_DIRECTORY_LIST_START, [path, recursive, followLinks])
.then((response) {
if (response is int) {
id = response;
@@ -351,46 +322,44 @@
if (controller.isPaused) return;
assert(!nextRunning);
nextRunning = true;
- _Directory._newServicePort().call([_Directory.LIST_NEXT_REQUEST, id])
- .then((result) {
- if (result is List) {
- assert(result.length % 2 == 0);
- for (int i = 0; i < result.length; i++) {
- assert(i % 2 == 0);
- switch (result[i++]) {
- case LIST_FILE:
- controller.add(new File(result[i]));
- break;
- case LIST_DIRECTORY:
- controller.add(new Directory(result[i]));
- break;
- case LIST_LINK:
- controller.add(new Link(result[i]));
- break;
- case LIST_ERROR:
- error(result[i]);
- break;
- case LIST_DONE:
- close();
- return;
- }
- }
- } else {
- controller.addError(new DirectoryException("Internal error"));
+ _IOService.dispatch(_DIRECTORY_LIST_NEXT, [id]).then((result) {
+ if (result is List) {
+ assert(result.length % 2 == 0);
+ for (int i = 0; i < result.length; i++) {
+ assert(i % 2 == 0);
+ switch (result[i++]) {
+ case LIST_FILE:
+ controller.add(new File(result[i]));
+ break;
+ case LIST_DIRECTORY:
+ controller.add(new Directory(result[i]));
+ break;
+ case LIST_LINK:
+ controller.add(new Link(result[i]));
+ break;
+ case LIST_ERROR:
+ error(result[i]);
+ break;
+ case LIST_DONE:
+ close();
+ return;
}
- nextRunning = false;
- next();
- });
+ }
+ } else {
+ controller.addError(new DirectoryException("Internal error"));
+ }
+ nextRunning = false;
+ next();
+ });
}
void close() {
if (closed) return;
if (id == null) return;
closed = true;
- _Directory._newServicePort().call([_Directory.LIST_STOP_REQUEST, id])
- .then((_) {
- controller.close();
- });
+ _IOService.dispatch(_DIRECTORY_LIST_STOP, [id]).then((_) {
+ controller.close();
+ });
}
void error(message) {
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 1ec4b11..1dce796 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -17,6 +17,7 @@
RandomAccessFile _openedFile;
int _position;
int _end;
+ final Completer _closeCompleter = new Completer();
// Has the stream been paused or unsubscribed?
bool _paused = false;
@@ -58,14 +59,16 @@
}
Future _closeFile() {
- Future closeFuture;
- if (_openedFile != null) {
- Future closeFuture = _openedFile.close();
- _openedFile = null;
- return closeFuture;
- } else {
- return new Future.value();
+ if (_readInProgress) {
+ return _closeCompleter.future;
}
+ if (_openedFile != null) {
+ _openedFile.close()
+ .then(_closeCompleter.complete,
+ onError: _closeCompleter.completeError);
+ _openedFile = null;
+ }
+ return _closeCompleter.future;
}
void _readBlock() {
@@ -76,6 +79,7 @@
if (_end != null) {
readBytes = min(readBytes, _end - _position);
if (readBytes < 0) {
+ _readInProgress = false;
if (!_unsubscribed) {
_controller.addError(new RangeError("Bad end position: $_end"));
_closeFile().then((_) { _controller.close(); });
@@ -85,8 +89,14 @@
}
}
_openedFile.read(readBytes)
- .then((block) {
+ .whenComplete(() {
_readInProgress = false;
+ })
+ .then((block) {
+ if (_unsubscribed) {
+ _closeFile();
+ return;
+ }
if (block.length == 0) {
if (!_unsubscribed) {
_closeFile().then((_) { _controller.close(); });
@@ -199,44 +209,9 @@
}
-const int _EXISTS_REQUEST = 0;
-const int _CREATE_REQUEST = 1;
-const int _DELETE_REQUEST = 2;
-const int _RENAME_REQUEST = 3;
-const int _OPEN_REQUEST = 4;
-const int _RESOLVE_SYMBOLIC_LINKS_REQUEST = 5;
-const int _CLOSE_REQUEST = 6;
-const int _POSITION_REQUEST = 7;
-const int _SET_POSITION_REQUEST = 8;
-const int _TRUNCATE_REQUEST = 9;
-const int _LENGTH_REQUEST = 10;
-const int _LENGTH_FROM_PATH_REQUEST = 11;
-const int _LAST_MODIFIED_REQUEST = 12;
-const int _FLUSH_REQUEST = 13;
-const int _READ_BYTE_REQUEST = 14;
-const int _WRITE_BYTE_REQUEST = 15;
-const int _READ_REQUEST = 16;
-const int _READ_LIST_REQUEST = 17;
-const int _WRITE_LIST_REQUEST = 18;
-const int _CREATE_LINK_REQUEST = 19;
-const int _DELETE_LINK_REQUEST = 20;
-const int _RENAME_LINK_REQUEST = 21;
-const int _LINK_TARGET_REQUEST = 22;
-const int _TYPE_REQUEST = 23;
-const int _IDENTICAL_REQUEST = 24;
-const int _STAT_REQUEST = 25;
-
-// TODO(ager): The only reason for this class is that the patching
-// mechanism doesn't seem to like patching a private top level
-// function.
-class _FileUtils {
- external static SendPort _newServicePort();
-}
-
// Class for encapsulating the native implementation of files.
class _File extends FileSystemEntity implements File {
final String path;
- SendPort _fileService;
// Constructor for file.
_File(String this.path) {
@@ -247,11 +222,7 @@
}
Future<bool> exists() {
- _ensureFileService();
- List request = new List(2);
- request[0] = _EXISTS_REQUEST;
- request[1] = path;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_EXISTS, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Cannot check existence", path);
}
@@ -274,11 +245,7 @@
FileStat statSync() => FileStat.statSync(path);
Future<File> create() {
- _ensureFileService();
- List request = new List(2);
- request[0] = _CREATE_REQUEST;
- request[1] = path;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_CREATE, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Cannot create file", path);
}
@@ -301,11 +268,7 @@
if (recursive) {
return new Directory(path).delete(recursive: true).then((_) => this);
}
- _ensureFileService();
- List request = new List(2);
- request[0] = _DELETE_REQUEST;
- request[1] = path;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_DELETE, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Cannot delete file", path);
}
@@ -326,12 +289,7 @@
}
Future<File> rename(String newPath) {
- _ensureFileService();
- List request = new List(3);
- request[0] = _RENAME_REQUEST;
- request[1] = path;
- request[2] = newPath;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_RENAME, [path, newPath]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(
response, "Cannot rename file to '$newPath'", path);
@@ -356,17 +314,12 @@
}
Future<RandomAccessFile> open({FileMode mode: FileMode.READ}) {
- _ensureFileService();
if (mode != FileMode.READ &&
mode != FileMode.WRITE &&
mode != FileMode.APPEND) {
return new Future.error(new ArgumentError());
}
- List request = new List(3);
- request[0] = _OPEN_REQUEST;
- request[1] = path;
- request[2] = mode._mode; // Direct int value for serialization.
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_OPEN, [path, mode._mode]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Cannot open file", path);
}
@@ -375,11 +328,7 @@
}
Future<int> length() {
- _ensureFileService();
- List request = new List(2);
- request[0] = _LENGTH_FROM_PATH_REQUEST;
- request[1] = path;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_LENGTH_FROM_PATH, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"Cannot retrieve length of file",
@@ -399,11 +348,7 @@
}
Future<DateTime> lastModified() {
- _ensureFileService();
- List request = new List(2);
- request[0] = _LAST_MODIFIED_REQUEST;
- request[1] = path;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_LAST_MODIFIED, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"Cannot retrieve modification time",
@@ -466,7 +411,6 @@
}
Future<List<int>> readAsBytes() {
- _ensureFileService();
Completer<List<int>> completer = new Completer<List<int>>();
var builder = new BytesBuilder();
openRead().listen(
@@ -502,7 +446,6 @@
}
Future<String> readAsString({Encoding encoding: UTF8}) {
- _ensureFileService();
return readAsBytes().then((bytes) {
return _tryDecode(bytes, encoding);
});
@@ -532,7 +475,6 @@
}
Future<List<String>> readAsLines({Encoding encoding: UTF8}) {
- _ensureFileService();
return readAsBytes().then((bytes) {
return _decodeLines(bytes, encoding);
});
@@ -578,12 +520,6 @@
String toString() => "File: '$path'";
- void _ensureFileService() {
- if (_fileService == null) {
- _fileService = _FileUtils._newServicePort();
- }
- }
-
static throwIfError(Object result, String msg, String path) {
if (result is OSError) {
throw new FileException(msg, path, result);
@@ -601,14 +537,11 @@
Future<RandomAccessFile> close() {
if (closed) return _closedException();
- _ensureFileService();
- List request = new List(2);
- request[0] = _CLOSE_REQUEST;
- request[1] = _id;
// Set the id_ to 0 (NULL) to ensure the no more async requests
// can be issued for this file.
+ int id = _id;
_id = 0;
- return _fileService.call(request).then((result) {
+ return _IOService.dispatch(_FILE_CLOSE, [id]).then((result) {
if (result != -1) {
_id = result;
return this;
@@ -630,12 +563,8 @@
}
Future<int> readByte() {
- _ensureFileService();
if (closed) return _closedException();
- List request = new List(2);
- request[0] = _READ_BYTE_REQUEST;
- request[1] = _id;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_READ_BYTE, [_id]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "readByte failed", path);
}
@@ -655,16 +584,11 @@
}
Future<List<int>> read(int bytes) {
- _ensureFileService();
if (bytes is !int) {
throw new ArgumentError(bytes);
}
if (closed) return _closedException();
- List request = new List(3);
- request[0] = _READ_REQUEST;
- request[1] = _id;
- request[2] = bytes;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_READ, [_id, bytes]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "read failed", path);
}
@@ -687,20 +611,16 @@
}
Future<int> readInto(List<int> buffer, [int start, int end]) {
- _ensureFileService();
if (buffer is !List ||
(start != null && start is !int) ||
(end != null && end is !int)) {
throw new ArgumentError();
}
if (closed) return _closedException();
- List request = new List(3);
if (start == null) start = 0;
if (end == null) end = buffer.length;
- request[0] = _READ_LIST_REQUEST;
- request[1] = _id;
- request[2] = end - start;
- return _fileService.call(request).then((response) {
+ int length = end - start;
+ return _IOService.dispatch(_FILE_READ_INTO, [_id, length]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "readInto failed", path);
}
@@ -740,16 +660,11 @@
}
Future<RandomAccessFile> writeByte(int value) {
- _ensureFileService();
if (value is !int) {
throw new ArgumentError(value);
}
if (closed) return _closedException();
- List request = new List(3);
- request[0] = _WRITE_BYTE_REQUEST;
- request[1] = _id;
- request[2] = value;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "writeByte failed", path);
}
@@ -772,7 +687,6 @@
}
Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) {
- _ensureFileService();
if ((buffer is !List && buffer is !ByteData) ||
(start != null && start is !int) ||
(end != null && end is !int)) {
@@ -788,13 +702,12 @@
return new Future.error(e);
}
- List request = new List(5);
- request[0] = _WRITE_LIST_REQUEST;
- request[1] = _id;
- request[2] = result.buffer;
- request[3] = result.start;
- request[4] = end - (start - result.start);
- return _fileService.call(request).then((response) {
+ List request = new List(4);
+ request[0] = _id;
+ request[1] = result.buffer;
+ request[2] = result.start;
+ request[3] = end - (start - result.start);
+ return _IOService.dispatch(_FILE_WRITE_FROM, request).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "writeFrom failed", path);
}
@@ -844,12 +757,8 @@
}
Future<int> position() {
- _ensureFileService();
if (closed) return _closedException();
- List request = new List(2);
- request[0] = _POSITION_REQUEST;
- request[1] = _id;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_POSITION, [_id]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "position failed", path);
}
@@ -869,18 +778,14 @@
}
Future<RandomAccessFile> setPosition(int position) {
- _ensureFileService();
if (closed) return _closedException();
- List request = new List(3);
- request[0] = _SET_POSITION_REQUEST;
- request[1] = _id;
- request[2] = position;
- return _fileService.call(request).then((response) {
- if (_isErrorResponse(response)) {
- throw _exceptionFromResponse(response, "setPosition failed", path);
- }
- return this;
- });
+ return _IOService.dispatch(_FILE_SET_POSITION, [_id, position])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionFromResponse(response, "setPosition failed", path);
+ }
+ return this;
+ });
}
external static _setPosition(int id, int position);
@@ -894,13 +799,8 @@
}
Future<RandomAccessFile> truncate(int length) {
- _ensureFileService();
if (closed) return _closedException();
- List request = new List(3);
- request[0] = _TRUNCATE_REQUEST;
- request[1] = _id;
- request[2] = length;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_TRUNCATE, [_id, length]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "truncate failed", path);
}
@@ -919,12 +819,8 @@
}
Future<int> length() {
- _ensureFileService();
if (closed) return _closedException();
- List request = new List(2);
- request[0] = _LENGTH_REQUEST;
- request[1] = _id;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_LENGTH, [_id]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "length failed", path);
}
@@ -944,12 +840,8 @@
}
Future<RandomAccessFile> flush() {
- _ensureFileService();
if (closed) return _closedException();
- List request = new List(2);
- request[0] = _FLUSH_REQUEST;
- request[1] = _id;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_FLUSH, [_id]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"flush failed",
@@ -969,12 +861,6 @@
}
}
- void _ensureFileService() {
- if (_fileService == null) {
- _fileService = _FileUtils._newServicePort();
- }
- }
-
bool get closed => _id == 0;
void _checkNotClosed() {
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index 10d632b..fdeb923 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -71,12 +71,7 @@
* .type set to FileSystemEntityType.NOT_FOUND and the other fields invalid.
*/
static Future<FileStat> stat(String path) {
- // Get a new file service port for each request. We could also cache one.
- var service = _FileUtils._newServicePort();
- List request = new List(2);
- request[0] = _STAT_REQUEST;
- request[1] = path;
- return service.call(request).then((response) {
+ return _IOService.dispatch(_FILE_STAT, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"Error getting stat",
@@ -241,19 +236,15 @@
* since [resolve] removes '..' segments.
*/
Future<String> resolveSymbolicLinks() {
- // Get a new file service port for each request. We could also cache one.
- var service = _FileUtils._newServicePort();
- List request = new List(2);
- request[0] = _RESOLVE_SYMBOLIC_LINKS_REQUEST;
- request[1] = path;
- return service.call(request).then((response) {
- if (_isErrorResponse(response)) {
- throw _exceptionFromResponse(response,
- "Cannot resolve symbolic links",
- path);
- }
- return response;
- });
+ return _IOService.dispatch(_FILE_RESOLVE_SYMBOLIC_LINKS, [path])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionFromResponse(response,
+ "Cannot resolve symbolic links",
+ path);
+ }
+ return response;
+ });
}
/**
@@ -325,7 +316,7 @@
* [FileSystemEntity] when the deletion is done. If the [FileSystemEntity]
* cannot be deleted, the future completes with an exception.
*/
- Future<FileSystemEntity> delete({recursive: false})
+ Future<FileSystemEntity> delete({bool recursive: false})
=> _delete(recursive: recursive);
/**
@@ -344,7 +335,7 @@
*
* Throws an exception if the [FileSystemEntity] cannot be deleted.
*/
- void deleteSync({recursive: false})
+ void deleteSync({bool recursive: false})
=> _deleteSync(recursive: recursive);
@@ -374,8 +365,8 @@
events,
recursive).stream;
- Future<FileSystemEntity> _delete({recursive: false});
- void _deleteSync({recursive: false});
+ Future<FileSystemEntity> _delete({bool recursive: false});
+ void _deleteSync({bool recursive: false});
/**
* Checks whether two paths refer to the same object in the
@@ -390,13 +381,7 @@
* to an object that does not exist.
*/
static Future<bool> identical(String path1, String path2) {
- // Get a new file service port for each request. We could also cache one.
- var service = _FileUtils._newServicePort();
- List request = new List(3);
- request[0] = _IDENTICAL_REQUEST;
- request[1] = path1;
- request[2] = path2;
- return service.call(request).then((response) {
+ return _IOService.dispatch(_FILE_IDENTICAL, [path1, path2]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"Error in FileSystemEntity.identical($path1, $path2)", "");
@@ -552,13 +537,7 @@
}
static Future<int> _getTypeAsync(String path, bool followLinks) {
- // Get a new file service port for each request. We could also cache one.
- var service = _FileUtils._newServicePort();
- List request = new List(3);
- request[0] = _TYPE_REQUEST;
- request[1] = path;
- request[2] = followLinks;
- return service.call(request).then((response) {
+ return _IOService.dispatch(_FILE_TYPE, [path, followLinks]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Error getting type", path);
}
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index c5897ef..99c2806 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -474,7 +474,7 @@
Future<T> get done => _dataSink.done;
- Future _writeHeaders({drainRequest: true}) {
+ Future _writeHeaders({bool drainRequest: true}) {
if (_headersWritten) return new Future.value();
_headersWritten = true;
headers._synchronize(); // Be sure the 'chunked' option is updated.
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index c44f101..e2fb691 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -41,6 +41,7 @@
part 'http_parser.dart';
part 'http_session.dart';
part 'io_sink.dart';
+part 'io_service.dart';
part 'link.dart';
part 'options.dart';
part 'path.dart';
diff --git a/sdk/lib/io/io_service.dart b/sdk/lib/io/io_service.dart
new file mode 100644
index 0000000..760d022
--- /dev/null
+++ b/sdk/lib/io/io_service.dart
@@ -0,0 +1,48 @@
+// 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.
+
+part of dart.io;
+
+const int _FILE_EXISTS = 0;
+const int _FILE_CREATE = 1;
+const int _FILE_DELETE = 2;
+const int _FILE_RENAME = 3;
+const int _FILE_OPEN = 4;
+const int _FILE_RESOLVE_SYMBOLIC_LINKS = 5;
+const int _FILE_CLOSE = 6;
+const int _FILE_POSITION = 7;
+const int _FILE_SET_POSITION = 8;
+const int _FILE_TRUNCATE = 9;
+const int _FILE_LENGTH = 10;
+const int _FILE_LENGTH_FROM_PATH = 11;
+const int _FILE_LAST_MODIFIED = 12;
+const int _FILE_FLUSH = 13;
+const int _FILE_READ_BYTE = 14;
+const int _FILE_WRITE_BYTE = 15;
+const int _FILE_READ = 16;
+const int _FILE_READ_INTO = 17;
+const int _FILE_WRITE_FROM = 18;
+const int _FILE_CREATE_LINK = 19;
+const int _FILE_DELETE_LINK = 20;
+const int _FILE_RENAME_LINK = 21;
+const int _FILE_LINK_TARGET = 22;
+const int _FILE_TYPE = 23;
+const int _FILE_IDENTICAL = 24;
+const int _FILE_STAT = 25;
+const int _SOCKET_LOOKUP = 26;
+const int _SOCKET_LIST_INTERFACES = 27;
+const int _SOCKET_REVERSE_LOOKUP = 28;
+const int _DIRECTORY_CREATE = 29;
+const int _DIRECTORY_DELETE = 30;
+const int _DIRECTORY_EXISTS = 31;
+const int _DIRECTORY_CREATE_TEMP = 32;
+const int _DIRECTORY_LIST_START = 33;
+const int _DIRECTORY_LIST_NEXT = 34;
+const int _DIRECTORY_LIST_STOP = 35;
+const int _DIRECTORY_RENAME = 36;
+const int _SSL_PROCESS_FILTER = 37;
+
+class _IOService {
+ external static Future dispatch(int request, List data);
+}
diff --git a/sdk/lib/io/iolib_sources.gypi b/sdk/lib/io/iolib_sources.gypi
index 9f15096..4c7bdbe1 100644
--- a/sdk/lib/io/iolib_sources.gypi
+++ b/sdk/lib/io/iolib_sources.gypi
@@ -21,6 +21,7 @@
'http_parser.dart',
'http_session.dart',
'io_sink.dart',
+ 'io_service.dart',
'link.dart',
'options.dart',
'path.dart',
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index c889a70..ab3ba64 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -125,8 +125,6 @@
class _Link extends FileSystemEntity implements Link {
final String path;
- SendPort _fileService;
-
_Link(String this.path) {
if (path is! String) {
throw new ArgumentError('${Error.safeToString(path)} '
@@ -148,21 +146,17 @@
FileStat statSync() => FileStat.statSync(path);
Future<Link> create(String target) {
- _ensureFileService();
if (Platform.operatingSystem == 'windows') {
target = _makeWindowsLinkTarget(target);
}
- List request = new List(3);
- request[0] = _CREATE_LINK_REQUEST;
- request[1] = path;
- request[2] = target;
- return _fileService.call(request).then((response) {
- if (_isErrorResponse(response)) {
- throw _exceptionFromResponse(
- response, "Cannot create link to target '$target'", path);
- }
- return this;
- });
+ return _IOService.dispatch(_FILE_CREATE_LINK, [path, target])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionFromResponse(
+ response, "Cannot create link to target '$target'", path);
+ }
+ return this;
+ });
}
void createSync(String target) {
@@ -209,11 +203,7 @@
if (recursive) {
return new Directory(path).delete(recursive: true).then((_) => this);
}
- _ensureFileService();
- List request = new List(2);
- request[0] = _DELETE_LINK_REQUEST;
- request[1] = path;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_DELETE_LINK, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Cannot delete link", path);
}
@@ -230,18 +220,14 @@
}
Future<Link> rename(String newPath) {
- _ensureFileService();
- List request = new List(3);
- request[0] = _RENAME_LINK_REQUEST;
- request[1] = path;
- request[2] = newPath;
- return _fileService.call(request).then((response) {
- if (_isErrorResponse(response)) {
- throw _exceptionFromResponse(
- response, "Cannot rename link to '$newPath'", path);
- }
- return new Link(newPath);
- });
+ return _IOService.dispatch(_FILE_RENAME_LINK, [path, newPath])
+ .then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionFromResponse(
+ response, "Cannot rename link to '$newPath'", path);
+ }
+ return new Link(newPath);
+ });
}
Link renameSync(String newPath) {
@@ -251,11 +237,7 @@
}
Future<String> target() {
- _ensureFileService();
- List request = new List(2);
- request[0] = _LINK_TARGET_REQUEST;
- request[1] = path;
- return _fileService.call(request).then((response) {
+ return _IOService.dispatch(_FILE_LINK_TARGET, [path]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(
response, "Cannot get target of link", path);
@@ -280,12 +262,6 @@
return response is List && response[0] != _SUCCESS_RESPONSE;
}
- void _ensureFileService() {
- if (_fileService == null) {
- _fileService = _FileUtils._newServicePort();
- }
- }
-
_exceptionFromResponse(response, String message, String path) {
assert(_isErrorResponse(response));
switch (response[_ERROR_RESPONSE_ERROR_TYPE]) {
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 0916023..ef686fd 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -447,7 +447,6 @@
_SecureFilter _secureFilter = new _SecureFilter();
int _filterPointer;
- SendPort _filterService;
static Future<_RawSecureSocket> connect(
host,
@@ -988,23 +987,22 @@
}
Future<_FilterStatus> _pushAllFilterStages() {
- if (_filterService == null) {
- _filterService = _SecureFilter._newServicePort();
- }
- List args = [_filterPointer, _status != CONNECTED];
+ bool wasInHandshake = _status != CONNECTED;
+ List args = new List(2 + NUM_BUFFERS * 2);
+ args[0] = _filterPointer;
+ args[1] = wasInHandshake;
var bufs = _secureFilter.buffers;
for (var i = 0; i < NUM_BUFFERS; ++i) {
- args.add(bufs[i].start);
- args.add(bufs[i].end);
+ args[2 * i + 2] = bufs[i].start;
+ args[2 * i + 3] = bufs[i].end;
}
- return _filterService.call(args).then((response) {
+ return _IOService.dispatch(_SSL_PROCESS_FILTER, args).then((response) {
if (response.length == 2) {
_reportError(new TlsException('${response[1]} error ${response[0]}'));
}
- bool wasInHandshake = response[1];
- int start(int index) => response[2 * index + 2];
- int end(int index) => response[2 * index + 3];
+ int start(int index) => response[2 * index];
+ int end(int index) => response[2 * index + 1];
_FilterStatus status = new _FilterStatus();
// Compute writeEmpty as "write plaintext buffer and write encrypted
@@ -1196,8 +1194,6 @@
abstract class _SecureFilter {
external factory _SecureFilter();
- external static SendPort _newServicePort();
-
void connect(String hostName,
Uint8List addr,
int port,
diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart
index 93ec416..4cffa8f 100644
--- a/sdk/lib/math/math.dart
+++ b/sdk/lib/math/math.dart
@@ -61,6 +61,12 @@
* is returned.
*/
num min(num a, num b) {
+ // These partially redundant type checks improve code quality for dart2js.
+ // Most of the improvement is at call sites from the inferred non-null num
+ // return type.
+ if (a is! num) throw new ArgumentError(a);
+ if (b is! num) throw new ArgumentError(b);
+
if (a > b) return b;
if (a < b) return a;
if (b is double) {
@@ -90,6 +96,12 @@
* then it is unspecified which of the two arguments is returned.
*/
num max(num a, num b) {
+ // These partially redundant type checks improve code quality for dart2js.
+ // Most of the improvement is at call sites from the inferred non-null num
+ // return type.
+ if (a is! num) throw new ArgumentError(a);
+ if (b is! num) throw new ArgumentError(b);
+
if (a > b) return a;
if (a < b) return b;
if (b is double) {
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index f6fc7fa..0b9ebe5 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -339,6 +339,19 @@
* in a scope that has access to the private members
* of *o* (if *o* is a class or library) or the private members of the
* class of *o* (otherwise).
+ *
+ * If this mirror is an [InstanceMirror], and [fieldName] denotes an instance
+ * method on its reflectee, the result of the invocation is an instance
+ * mirror on a closure corresponding to that method.
+ *
+ * If this mirror is a [LibraryMirror], and [fieldName] denotes a top-level
+ * method in the corresponding library, the result of the invocation is an
+ * instance mirror on a closure corresponding to that method.
+ *
+ * If this mirror is a [ClassMirror], and [fieldName] denotes a static method
+ * in the corresponding class, the result of the invocation is an instance
+ * mirror on a closure corresponding to that method.
+ *
* If the invocation returns a result *r*, this method returns
* the result of calling [reflect](*r*).
* If the invocation causes a compilation error
@@ -421,6 +434,19 @@
* in a scope that has access to the private members
* of *o* (if *o* is a class or library) or the private members of the
* class of *o*(otherwise).
+ *
+ * If this mirror is an [InstanceMirror], and [fieldName] denotes an instance
+ * method on its reflectee, the result of the invocation is an instance
+ * mirror on a closure corresponding to that method.
+ *
+ * If this mirror is a [LibraryMirror], and [fieldName] denotes a top-level
+ * method in the corresponding library, the result of the invocation is an
+ * instance mirror on a closure corresponding to that method.
+ *
+ * If this mirror is a [ClassMirror], and [fieldName] denotes a static method
+ * in the corresponding class, the result of the invocation is an instance
+ * mirror on a closure corresponding to that method.
+ *
* The method returns a future *k*.
* If the invocation returns a result *r*, *k* will be completed
* with the result of calling [reflect](*r*).
@@ -600,7 +626,7 @@
* The returned value is the result of invoking the method [reflect] on
* *v*.
*/
- Future<InstanceMirror> findInContext(Symbol name);
+ InstanceMirror findInContext(Symbol name, {ifAbsent: null});
}
/**
diff --git a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
index f04e918..4b7ea7b 100644
--- a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
@@ -811,6 +811,14 @@
_storage[3] = v;
}
Float32x4.zero();
+ /// Returns a bit-wise copy of [x] as a Float32x4.
+ Float32x4.fromUint32x4Bits(Uint32x4 x) {
+ var view = new Float32List.view(x._storage.buffer);
+ _storage[0] = view[0];
+ _storage[1] = view[1];
+ _storage[2] = view[2];
+ _storage[3] = view[3];
+ }
/// Addition operator.
Float32x4 operator+(Float32x4 other) {
@@ -961,14 +969,15 @@
double _y = _storage[1];
double _z = _storage[2];
double _w = _storage[3];
- _x = _x < _lx ? _lx : _x;
+ // MAX(MIN(self, upper), lower).
_x = _x > _ux ? _ux : _x;
- _y = _y < _ly ? _ly : _y;
_y = _y > _uy ? _uy : _y;
- _z = _z < _lz ? _lz : _z;
_z = _z > _uz ? _uz : _z;
- _w = _w < _lw ? _lw : _w;
_w = _w > _uw ? _uw : _w;
+ _x = _x < _lx ? _lx : _x;
+ _y = _y < _ly ? _ly : _y;
+ _z = _z < _lz ? _lz : _z;
+ _w = _w < _lw ? _lw : _w;
return new Float32x4(_x, _y, _z, _w);
}
@@ -1399,12 +1408,6 @@
double _w = Math.sqrt(1.0 / _storage[3]);
return new Float32x4(_x, _y, _z, _w);
}
-
- /// Returns a bit-wise copy of [this] as a [Uint32x4].
- Uint32x4 toUint32x4() {
- var view = new Uint32List.view(_storage.buffer);
- return new Uint32x4(view[0], view[1], view[2], view[3]);
- }
}
@@ -1425,6 +1428,15 @@
_storage[3] = w == true ? 0xFFFFFFFF : 0x0;
}
+ /// Returns a bit-wise copy of [x] as a Uint32x4.
+ Uint32x4.fromFloat32x4Bits(Float32x4 x) {
+ var view = new Uint32List.view(x._storage.buffer);
+ _storage[0] = view[0];
+ _storage[1] = view[1];
+ _storage[2] = view[2];
+ _storage[3] = view[3];
+ }
+
/// The bit-wise or operator.
Uint32x4 operator|(Uint32x4 other) {
int _x = _storage[0] | other._storage[0];
@@ -1599,10 +1611,4 @@
rView[3] = _w;
return r;
}
-
- /// Returns a bit-wise copy of [this] as a [Float32x4].
- Float32x4 toFloat32x4() {
- var view = new Float32List.view(_storage.buffer);
- return new Float32x4(view[0], view[1], view[2], view[3]);
- }
}
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 61577b2..e18433e 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -834,6 +834,7 @@
external factory Float32x4(double x, double y, double z, double w);
external factory Float32x4.splat(double v);
external factory Float32x4.zero();
+ external factory Float32x4.fromUint32x4Bits(Uint32x4 x);
/// Addition operator.
Float32x4 operator+(Float32x4 other);
@@ -1183,9 +1184,6 @@
/// Returns the square root of the reciprocal of [this].
Float32x4 reciprocalSqrt();
-
- /// Returns a bit-wise copy of [this] as a [Uint32x4].
- Uint32x4 toUint32x4();
}
@@ -1197,6 +1195,7 @@
abstract class Uint32x4 {
external factory Uint32x4(int x, int y, int z, int w);
external factory Uint32x4.bool(bool x, bool y, bool z, bool w);
+ external factory Uint32x4.fromFloat32x4Bits(Float32x4 x);
/// The bit-wise or operator.
Uint32x4 operator|(Uint32x4 other);
@@ -1252,7 +1251,4 @@
/// Select bit from [trueValue] when bit in [this] is on.
/// Select bit from [falseValue] when bit in [this] is off.
Float32x4 select(Float32x4 trueValue, Float32x4 falseValue);
-
- /// Returns a bit-wise copy of [this] as a [Float32x4].
- Float32x4 toFloat32x4();
}
diff --git a/tests/chrome/chrome.status b/tests/_chrome/_chrome.status
similarity index 100%
rename from tests/chrome/chrome.status
rename to tests/_chrome/_chrome.status
diff --git a/tests/chrome/sample_test.dart b/tests/_chrome/sample_test.dart
similarity index 76%
rename from tests/chrome/sample_test.dart
rename to tests/_chrome/sample_test.dart
index 219a600..eb51d5c 100644
--- a/tests/chrome/sample_test.dart
+++ b/tests/_chrome/sample_test.dart
@@ -5,19 +5,19 @@
library sample_test;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:chrome' as chrome;
+import 'dart:_chrome' as _chrome;
main() {
useHtmlConfiguration();
test('access', () {
- var window = chrome.app.window;
- expect(window is chrome.WindowModule, true);
+ var window = _chrome.app.window;
+ expect(window is _chrome.WindowModule, true);
});
test('fails from browser', () {
// APIs should not work in standard browser apps.
expect(() {
- chrome.app.window.create('foo.html');
+ _chrome.app.window.create('foo.html');
}, throws);
});
}
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index 845974e..c911f20 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -48,13 +48,6 @@
LibTest/core/Set/isSubsetOf_A01_t01: fail, OK
LibTest/core/Set/isSubsetOf_A01_t02: fail, OK
-# co19 issue #424, Uninitialized finals are warnings not errors
-Language/05_Variables/05_Variables_A07_t05: fail, OK
-Language/05_Variables/05_Variables_A07_t06: fail, OK
-Language/05_Variables/05_Variables_A07_t07: fail, OK
-Language/05_Variables/05_Variables_A07_t08: fail, OK
-Language/05_Variables/05_Variables_A08_t01: fail, OK
-
# co19 issue #425, Only static fields can be declared as 'const'
Language/05_Variables/05_Variables_A12_t01: fail, OK
Language/05_Variables/05_Variables_A12_t06: fail, OK
@@ -117,8 +110,10 @@
Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
-Language/07_Classes/1_Instance_Methods_A03_t06: fail # co19-roll r587: Please triage this failure
-Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail # co19-roll r587: Please triage this failure
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # co19-roll r587: Please triage this failure
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # co19-roll r587: Please triage this failure
+# co19 issue #596: initializing final variable at declaration and in constructor
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail, OK
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail, OK
+
+# co19 issue #597: concrete class with abstract method
+Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail, OK
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 8a26565..4a00538 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -29,6 +29,13 @@
Language/15_Types/4_Interface_Types_A11_t01: Skip
Language/15_Types/4_Interface_Types_A11_t02: Skip
+# TBF: Hence, a static warning will not be issued if f has no declared return type, since the return type would be dynamic and dynamic may be assigned to void.
+Language/13_Statements/11_Return_A07_t01: fail
+
+# TBF: typedef int func2(int); - "int is not a type"
+Language/15_Types/6_Type_dynamic_A03_t01: fail
+Language/15_Types/6_Type_dynamic_A04_t01: fail
+
LibTest/core/Uri/decodeQueryComponent_A02_t01: fail # co19 Issue 591
@@ -38,13 +45,8 @@
# co19 issue #400, collection library reorg
LibTest/core/String/concat_A01_t01: fail, OK
LibTest/core/String/concat_A02_t01: fail, OK
-
-# co19 issue #424, Uninitialized finals are warnings not errors
-Language/05_Variables/05_Variables_A07_t05: fail, OK
-Language/05_Variables/05_Variables_A07_t06: fail, OK
-Language/05_Variables/05_Variables_A07_t07: fail, OK
-Language/05_Variables/05_Variables_A07_t08: fail, OK
-Language/05_Variables/05_Variables_A08_t01: fail, OK
+LibTest/core/Set/isSubsetOf_A01_t01: fail, OK
+LibTest/core/Set/isSubsetOf_A01_t02: fail, OK
# co19 issue #425, Only static fields can be declared as 'const'
Language/05_Variables/05_Variables_A12_t01: fail, OK
@@ -64,10 +66,21 @@
# co19 issue #513, rules for finals were loosened, contradiction in spec was fixed
Language/07_Classes/6_Constructors/1_Generative_Constructors_A21_t01: fail, OK
+# co19 issue #515, it is a compile-time error if there is more than one entity with the same name declared in the same scope
+Language/07_Classes/3_Setters_A08_t03: fail, OK
+
+# co19 issue #593: Conditional expressions are now allowed as constant expressions
+Language/12_Expressions/01_Constants_A15_t16: fail, OK
+
# co19 issue #438, Static variables are initialized lazily, need not be constants
Language/12_Expressions/01_Constants_A16_t01: fail, OK
Language/12_Expressions/01_Constants_A16_t02: fail, OK
+# co19 issue #420, "throw" requires expression, "rethrow" should be used instead
+Language/12_Expressions/08_Throw_A05_t01: fail, OK
+Language/12_Expressions/08_Throw_A05_t02: fail, OK
+Language/12_Expressions/08_Throw_A05_t03: fail, OK
+
# co19 issue #454 (wrongly closed)
Language/12_Expressions/12_Instance_Creation/1_New_A01_t04: fail, OK
@@ -87,19 +100,20 @@
# co19 issue #543: invocation of a non-function
Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
-Language/07_Classes/1_Instance_Methods_A03_t06: fail # co19-roll r587: Please triage this failure
-Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail # co19-roll r587: Please triage this failure
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # co19-roll r587: Please triage this failure
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # co19-roll r587: Please triage this failure
-Language/13_Statements/11_Return_A07_t01: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t47: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t67: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/2_Exports_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail # co19-roll r546: Please triage this failure
-Language/15_Types/6_Type_dynamic_A03_t01: fail # co19-roll r546: Please triage this failure
-Language/15_Types/6_Type_dynamic_A04_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Future/asStream_A01_t02: pass # co19-roll r546: Please triage this failure
-LibTest/async/Future/asStream_A02_t01: pass # co19-roll r546: Please triage this failure
-LibTest/async/Future/whenComplete_A03_t01: pass # co19-roll r546: Please triage this failure
+# co19 issue #562: malformed superclass
+Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail, OK
+
+# co19 issue #563: implicitly named libraries are allowed
+Language/14_Libraries_and_Scripts/2_Exports_A05_t01: fail, OK
+
+# co19 issue #564: URI can be any number adjacent string literals
+Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
+Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
+
+# co19 issue #596: initializing final variable at declaration and in constructor
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail, OK
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail, OK
+
+# co19 issue #597: concrete class with abstract method
+Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail, OK
+
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index d2a26cd..3bd647f 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -96,7 +96,7 @@
LibTest/core/String/concat_A01_t01: Fail # co19 issue 561
LibTest/core/String/concat_A02_t01: Fail # co19 issue 561
-[ $compiler != dartanalyzer ]
+[ $compiler != dartanalyzer && $compiler != dart2analyzer ]
# Dart2js/Dart2dart succeedes due to a bug in their parser (issue 13223).
Language/12_Expressions/21_Bitwise_Expressions_A01_t01: Fail # co19 Issue 595
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 4d70e82..94ab233 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -7,30 +7,18 @@
Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t03: Fail # TODO(dart2dart-team): Please triage this failure.
-Language/03_Overview/1_Scoping_A01_t39: Fail # http://dartbug.com/7202
-
Language/03_Overview/2_Privacy_A01_t19: Fail # Calling unresolved class constructor.
Language/03_Overview/2_Privacy_A01_t20: Fail # Calling unresolved class constructor.
Language/07_Classes/6_Constructors_A03_t03: Fail # Calling unresolved class constructor.
-Language/03_Overview/1_Scoping_A01_t39: Fail # http://dartbug.com/5519
-Language/03_Overview/1_Scoping_A01_t40: Fail # http://dartbug.com/5519
-Language/03_Overview/1_Scoping_A01_t41: Fail # http://dartbug.com/5519
Language/03_Overview/1_Scoping_A02_t05: Fail # Inherited from dart2js
Language/03_Overview/1_Scoping_A02_t06: Fail # inherited from dart2js
-Language/05_Variables/05_Variables_A01_t04: Fail # http://dartbug.com/5519
-Language/05_Variables/05_Variables_A01_t05: Fail # http://dartbug.com/5519
-Language/05_Variables/05_Variables_A01_t08: Fail # http://dartbug.com/5519
-Language/05_Variables/05_Variables_A01_t12: Fail # http://dartbug.com/5519
-Language/05_Variables/05_Variables_A01_t13: Fail # http://dartbug.com/5519
-Language/05_Variables/05_Variables_A01_t14: Fail # http://dartbug.com/5519
Language/05_Variables/05_Variables_A07_t07: Fail # Inherited from dart2js
Language/05_Variables/05_Variables_A07_t08: Fail # Inherited from dart2js
Language/05_Variables/05_Variables_A08_t01: Fail # Inherited from dart2js
Language/05_Variables/05_Variables_A08_t02: Fail # Inherited from dart2js
Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Inherited from VM (circular initialization?).
Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Inherited from dart2js
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # http://dartbug.com/5519
Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: Fail # http://dartbug.com/5519
Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: Fail # http://dartbug.com/5519
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A02_t01: Fail # http://dartbug.com/5519
@@ -81,6 +69,12 @@
LibTest/math/exp_A01_t01: Fail # Issue co19 - 44
LibTest/math/sin_A01_t01: Fail # Inherited from VM.
LibTest/math/tan_A01_t01: Fail # Issue co19 - 44
+LibTest/typed_data/Float32x4/toUint32x4_A01_t01: Fail # co19 Issue 601
+LibTest/typed_data/Float32x4/toUint32x4_A01_t02: Fail # co19 Issue 601
+LibTest/typed_data/Uint32x4/toFloat32x4_A01_t01: Fail # co19 Issue 601
+LibTest/typed_data/Uint32x4/toFloat32x4_A01_t02: Fail # co19 Issue 601
+LibTest/typed_data/Float32x4/clamp_A02_t01: RuntimeError # co19 Issue 600
+LibTest/typed_data/Float32x4/clamp_A01_t01: RuntimeError # co19 Issue 600
[ $compiler == dart2dart && $system == windows ]
@@ -118,15 +112,10 @@
Language/07_Classes/1_Instance_Methods/2_Operators_A09_t01: fail # co19-roll r587: Please triage this failure
Language/07_Classes/1_Instance_Methods_A01_t01: Fail # co19-roll r559: Please triage this failure
Language/07_Classes/1_Instance_Methods_A01_t02: Fail # co19-roll r559: Please triage this failure
-Language/07_Classes/1_Instance_Methods_A01_t03: Fail # co19-roll r559: Please triage this failure
-Language/07_Classes/1_Instance_Methods_A01_t04: Fail # co19-roll r559: Please triage this failure
-Language/07_Classes/1_Instance_Methods_A01_t05: Fail # co19-roll r559: Please triage this failure
-Language/07_Classes/1_Instance_Methods_A01_t06: Fail # co19-roll r559: Please triage this failure
Language/07_Classes/4_Abstract_Instance_Members_A03_t01: Fail # co19-roll r559: Please triage this failure
Language/07_Classes/4_Abstract_Instance_Members_A03_t02: Fail # co19-roll r559: Please triage this failure
Language/07_Classes/4_Abstract_Instance_Members_A03_t03: Fail # co19-roll r559: Please triage this failure
Language/07_Classes/4_Abstract_Instance_Members_A03_t04: Fail # co19-roll r559: Please triage this failure
-Language/07_Classes/4_Abstract_Instance_Members_A03_t05: Fail # co19-roll r559: Please triage this failure
Language/07_Classes/6_Constructors/2_Factories_A10_t01: crash # co19-roll r587: Please triage this failure
Language/07_Classes/6_Constructors/2_Factories_A10_t04: crash # co19-roll r587: Please triage this failure
Language/12_Expressions/01_Constants_A03_t02: fail # co19-roll r546: Please triage this failure
@@ -178,7 +167,6 @@
Language/12_Expressions/05_Strings/1_String_Interpolation_A01_t09: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/05_Strings_A02_t46: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/05_Strings_A02_t48: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/05_Strings_A20_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/06_Lists_A03_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/06_Lists_A03_t02: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/07_Maps_A02_t01: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index b8db1bf..2860893 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -2,11 +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.
-[ $compiler == dart2js && $runtime == drt ]
-LibTest/core/List/sort_A01_t02: Pass, Fail # v8 bug: Issue 12293
-LibTest/core/List/sort_A01_t03: Pass, Fail # v8 bug: Issue 12293
-LibTest/core/Map/Map_class_A01_t04: Pass, Fail # v8 bug: Issue 12293
-
[ $compiler == dart2js && $runtime == jsshell ]
LibTest/isolate/isolate_api/spawnUri_A02_t01: Crash # TODO(ahe): Please triage this crash.
LibTest/core/List/sort_A01_t04: Fail, Pass, Timeout # Must be a bug in jsshell, test sometimes times out.
@@ -19,15 +14,14 @@
# Crashes first, please. Then untriaged bugs. There is a section below
# for co19 bugs.
[ $compiler == dart2js ]
-Language/03_Overview/1_Scoping_A02_t05: Fail # TODO(ahe): Please triage this failure.
-Language/03_Overview/1_Scoping_A02_t06: Fail # TODO(ahe): Please triage this failure.
+Language/03_Overview/1_Scoping_A02_t05: CompileTimeError # TODO(ahe): Please triage this failure.
+Language/03_Overview/1_Scoping_A02_t06: CompileTimeError # TODO(ahe): Please triage this failure.
Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: fail # co19-roll r576: Please triage this failure
Language/13_Statements/11_Try_A07_t03: fail # co19-roll r576: Please triage this failure
-LibTest/core/double/INFINITY_A01_t04: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/double/NEGATIVE_INFINITY_A01_t04: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/List/List_A03_t01: Fail # TODO(kasperl): Please triage this failure.
+LibTest/core/double/INFINITY_A01_t04: RuntimeError # TODO(ahe): Please triage this failure.
+LibTest/core/double/NEGATIVE_INFINITY_A01_t04: RuntimeError # TODO(ahe): Please triage this failure.
+LibTest/core/List/List_A03_t01: RuntimeError # TODO(kasperl): Please triage this failure.
LibTest/core/List/sort_A01_t04: Pass, Slow # http://dartbug.com/11846
-LibTest/math/pow_A18_t01: FAIL, OK # co19 issue 507
LibTest/typed_data/ByteData/getFloat32_A02_t02: fail # co19-roll r569: Please triage this failure
LibTest/typed_data/ByteData/getFloat64_A02_t02: fail # co19-roll r569: Please triage this failure
@@ -74,9 +68,9 @@
[ $compiler == dart2js ]
-LibTest/core/List/removeAt_A02_t01: Fail # Issue 1533
+LibTest/core/List/removeAt_A02_t01: RuntimeError # Issue 1533
-LibTest/isolate/ReceivePort/receive_A01_t02: Fail # Issue 6750
+LibTest/isolate/ReceivePort/receive_A01_t02: RuntimeError # Issue 6750
[ $compiler == dart2js && $runtime == ie9 ]
LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Issue 8920
@@ -111,49 +105,48 @@
[ $compiler == dart2js && $checked ]
Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t03: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t04: Fail # TODO(ahe): Please triage this failure.
[ $compiler == dart2js ]
-LibTest/core/int/operator_GT_A01_t01: Fail, OK # co19 issue 200
-LibTest/core/int/operator_LT_A01_t01: Fail, OK # co19 issue 200
-LibTest/core/int/operator_addition_A01_t01: Fail, OK # co19 issue 200
-LibTest/core/int/toDouble_A01_t01: Fail, OK # co19 issue 200
+LibTest/core/int/operator_GT_A01_t01: RuntimeError, OK # co19 issue 200
+LibTest/core/int/operator_LT_A01_t01: RuntimeError, OK # co19 issue 200
+LibTest/core/int/operator_addition_A01_t01: RuntimeError, OK # co19 issue 200
+LibTest/core/int/toDouble_A01_t01: RuntimeError, OK # co19 issue 200
LibTest/core/List/sort_A01_t06: Slow, Pass # Slow tests that needs extra time to finish.
-LibTest/core/List/getRange_A03_t01: Fail, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
+LibTest/core/List/getRange_A03_t01: RuntimeError, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: Fail, OK # These tests need to be updated for new optional parameter syntax and semantics, co19 issue 258:
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: RuntimeError, OK # These tests need to be updated for new optional parameter syntax and semantics, co19 issue 258:
-LibTest/isolate/SendPort/send_A02_t04: Fail, Pass, OK # co19 issue 293 Passes on IE
+LibTest/isolate/SendPort/send_A02_t04: RuntimeError, Pass, OK # co19 issue 293 Passes on IE
-LibTest/core/RegExp/firstMatch_A01_t01: Fail, OK # co19 issue 294
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: Fail, OK # co19 issue 294
+LibTest/core/RegExp/firstMatch_A01_t01: RuntimeError, OK # co19 issue 294
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: RuntimeError, OK # co19 issue 294
-LibTest/core/int/isOdd_A01_t01: Fail, OK # co19 issue 277
-LibTest/core/int/isEven_A01_t01: Fail, OK # co19 issue 277
+LibTest/core/int/isOdd_A01_t01: RuntimeError, OK # co19 issue 277
+LibTest/core/int/isEven_A01_t01: RuntimeError, OK # co19 issue 277
[ $compiler == dart2js ]
-LibTest/isolate/SendPort/send_A02_t01: Fail # Compile-time error: error: not a compile-time constant
+LibTest/isolate/SendPort/send_A02_t01: CompileTimeError # Compile-time error: error: not a compile-time constant
-LibTest/isolate/isolate_api/spawnUri_A02_t01: Fail # Runtime error: Expect.throws() fails
-LibTest/isolate/isolate_api/spawnUri_A01_t01: Fail # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
-LibTest/isolate/isolate_api/spawnUri_A01_t02: Fail # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
-LibTest/isolate/isolate_api/spawnUri_A01_t03: Fail # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
-LibTest/isolate/isolate_api/spawnUri_A01_t04: Fail # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
-LibTest/isolate/isolate_api/spawnUri_A01_t05: Fail # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
-LibTest/isolate/SendPort/send_A02_t04: Fail # Runtime error: TypeError: Cannot call method 'toSendPort$0' of undefined.
+LibTest/isolate/isolate_api/spawnUri_A02_t01: RuntimeError # Runtime error: Expect.throws() fails
+LibTest/isolate/isolate_api/spawnUri_A01_t01: RuntimeError # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
+LibTest/isolate/isolate_api/spawnUri_A01_t02: RuntimeError # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
+LibTest/isolate/isolate_api/spawnUri_A01_t03: RuntimeError # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
+LibTest/isolate/isolate_api/spawnUri_A01_t04: RuntimeError # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
+LibTest/isolate/isolate_api/spawnUri_A01_t05: RuntimeError # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
+LibTest/isolate/SendPort/send_A02_t04: RuntimeError # Runtime error: TypeError: Cannot call method 'toSendPort$0' of undefined.
-LibTest/core/int/operator_NOT_A01_t01: Fail, OK # Expects negative result from bit-operation.
-LibTest/core/int/operator_XOR_A01_t01: Fail, OK # Requires bigints.
-LibTest/core/int/operator_AND_A01_t01: Fail, OK # Requires bigints.
-LibTest/core/int/operator_right_shift_A01_t01: Fail, OK # Expects negative result from bit-operation.
-LibTest/core/int/operator_OR_A01_t01: Fail, OK # Requires bigints.
-LibTest/core/int/operator_remainder_A01_t01: Fail, OK # Requires bigints.
+LibTest/core/int/operator_NOT_A01_t01: RuntimeError, OK # Expects negative result from bit-operation.
+LibTest/core/int/operator_XOR_A01_t01: RuntimeError, OK # Requires bigints.
+LibTest/core/int/operator_AND_A01_t01: RuntimeError, OK # Requires bigints.
+LibTest/core/int/operator_right_shift_A01_t01: RuntimeError, OK # Expects negative result from bit-operation.
+LibTest/core/int/operator_OR_A01_t01: RuntimeError, OK # Requires bigints.
+LibTest/core/int/operator_remainder_A01_t01: RuntimeError, OK # Requires bigints.
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: Fail, OK # co19 issue 212
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: RuntimeError, OK # co19 issue 212
#
@@ -164,12 +157,10 @@
# can understand so he can file a bug later.
#
[ $compiler == dart2js ]
-Language/03_Overview/1_Scoping_A01_t40: Fail, OK # co19 issue 188
-Language/03_Overview/1_Scoping_A01_t41: Fail, OK # co19 issue 188
-Language/03_Overview/2_Privacy_A01_t09: Fail, OK # co19 issue 198
+Language/03_Overview/2_Privacy_A01_t09: RuntimeError, OK # co19 issue 198
Language/03_Overview/2_Privacy_A01_t11: Pass, OK # co19 issue 316
-Language/06_Functions/4_External_Functions_A01_t01: Fail, OK # http://dartbug.com/5021
-LibTest/core/int/hashCode_A01_t01: Fail, OK # co19 issue 308
+Language/06_Functions/4_External_Functions_A01_t01: CompileTimeError, OK # http://dartbug.com/5021
+LibTest/core/int/hashCode_A01_t01: RuntimeError, OK # co19 issue 308
LibTest/typed_data/Int64List/*: Fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Int64List/Int64List_A02_t01: pass # co19-roll r559: Please triage this failure
LibTest/typed_data/Uint64List/*: Fail # co19-roll r559: Please triage this failure
@@ -232,26 +223,34 @@
LibTest/typed_data/ByteData/setUint8_A02_t02: fail # Issue 12989
LibTest/typed_data/ByteData/setUint8_A02_t02: fail # Issue 12989
+LibTest/typed_data/Float32x4/toUint32x4_A01_t01: RuntimeError # co19 Issue 601
+LibTest/typed_data/Float32x4/toUint32x4_A01_t02: RuntimeError # co19 Issue 601
+LibTest/typed_data/Uint32x4/toFloat32x4_A01_t01: RuntimeError # co19 Issue 601
+LibTest/typed_data/Uint32x4/toFloat32x4_A01_t02: RuntimeError # co19 Issue 601
+LibTest/typed_data/Float32x4/clamp_A02_t01: RuntimeError # co19 Issue 600
+
+
[ $compiler == dart2js && $jscl ]
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail, Pass # issue 3333
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail, Pass # issue 3333
-LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail, OK # This is not rejected by V8.
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: Fail, OK # co19 issue 92.
-LibTest/core/RegExp/firstMatch_A01_t01: Fail, OK # Bad test, use Match.regexp, not Match.pattern.
-LibTest/core/int/compareTo_A01_t01: Fail, OK # Requires big int.
-LibTest/core/int/hashCode_A01_t01: Fail, OK # co19 testing missing assertion.
-LibTest/core/int/isEven_A01_t01: Fail, OK # Not in API.
-LibTest/core/int/isOdd_A01_t01: Fail, OK # Not in API.
-LibTest/core/int/operator_left_shift_A01_t01: Fail, OK # Requires big int.
-LibTest/core/int/operator_remainder_A01_t03: Fail, OK # Leg only has double.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError, OK # This is not rejected by V8.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: RuntimeError, OK # co19 issue 92.
+LibTest/core/RegExp/firstMatch_A01_t01: RuntimeError, OK # Bad test, use Match.regexp, not Match.pattern.
+LibTest/core/int/compareTo_A01_t01: RuntimeError, OK # Requires big int.
+LibTest/core/int/hashCode_A01_t01: RuntimeError, OK # co19 testing missing assertion.
+LibTest/core/int/isEven_A01_t01: RuntimeError, OK # Not in API.
+LibTest/core/int/isOdd_A01_t01: RuntimeError, OK # Not in API.
+LibTest/core/int/operator_left_shift_A01_t01: RuntimeError, OK # Requires big int.
+LibTest/core/int/operator_remainder_A01_t03: RuntimeError, OK # Leg only has double.
LibTest/core/int/operator_truncating_division_A01_t01: Fail, Pass # Requires big int unless type inference fools us.
-LibTest/core/int/operator_truncating_division_A01_t02: Fail, OK # Leg only has double.
-LibTest/core/int/remainder_A01_t01: Fail, OK # Requires big int.
-LibTest/core/int/remainder_A01_t03: Fail, OK # Leg only has double.
-LibTest/core/int/toDouble_A01_t01: Fail, OK # Requires big int.
-LibTest/core/int/toRadixString_A01_t01: Fail, OK # Bad test: uses Expect.fail, Expect.throws, assumes case of result, and uses unsupported radixes.
+LibTest/core/int/operator_truncating_division_A01_t02: RuntimeError, OK # Leg only has double.
+LibTest/core/int/remainder_A01_t01: RuntimeError, OK # Requires big int.
+LibTest/core/int/remainder_A01_t03: RuntimeError, OK # Leg only has double.
+LibTest/core/int/toDouble_A01_t01: RuntimeError, OK # Requires big int.
+LibTest/core/int/toRadixString_A01_t01: RuntimeError, OK # Bad test: uses Expect.fail, Expect.throws, assumes case of result, and uses unsupported radixes.
[ $compiler == dart2js && $runtime == ie9 ]
+LibTest/core/Uri/Uri_A06_t03: Pass, Timeout # Issue 13511
LibTest/math/cos_A01_t01: Fail # co19 issue 44
#
@@ -260,15 +259,15 @@
# may sometime be out of date.
#
[ $compiler == dart2js ]
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: Fail # compiler cancelled: cannot resolve type T
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: RuntimeError # compiler cancelled: cannot resolve type T
-Language/03_Overview/2_Privacy_A01_t06: Fail # cannot resolve type _inaccessibleFuncType
+Language/03_Overview/2_Privacy_A01_t06: RuntimeError # cannot resolve type _inaccessibleFuncType
[ $compiler == dart2js && $jscl ]
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # IllegalJSRegExpException: '\c(' 'SyntaxError: Invalid regular expression: /\c(/: Unterminated group'
-LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Expect.fail('Some exception expected')
-LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Expect.fail('Some exception expected')
-LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Expect.fail('Some exception expected')
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: RuntimeError # IllegalJSRegExpException: '\c(' 'SyntaxError: Invalid regular expression: /\c(/: Unterminated group'
+LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: RuntimeError # Expect.fail('Some exception expected')
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Expect.fail('Some exception expected')
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Expect.fail('Some exception expected')
[ $compiler == dart2js && $runtime == chromeOnAndroid ]
@@ -311,44 +310,36 @@
# Missing compile-time errors.
#
[ $compiler == dart2js ]
-Language/03_Overview/1_Scoping_A01_t39: Fail # dartbug.com/7202
-Language/05_Variables/05_Variables_A01_t04: Fail # Checks that a variable declaration cannot contain both 'final' and 'var'.
-Language/05_Variables/05_Variables_A01_t05: Fail # Checks that a variable declaration cannot contain both 'var' and 'type'.
-Language/05_Variables/05_Variables_A01_t08: Fail # Checks different variables in a single variable declaration must be delimited by commas.
-Language/05_Variables/05_Variables_A01_t12: Fail # Checks that variable declaration cannot contain both 'const' and 'var'.
-Language/05_Variables/05_Variables_A01_t13: Fail # Checks that variable declaration cannot contain both 'const' and 'final'.
-Language/05_Variables/05_Variables_A01_t14: Fail # Checks that variable declaration cannot contain 'const', 'final' and 'var' simultaneously.
-Language/05_Variables/05_Variables_A07_t07: Fail # Checks that a compile-time error occurs if a global constant variable is not initialized at declaration.
-Language/05_Variables/05_Variables_A07_t08: Fail # Checks that a compile-time error occurs if a global typed constant variable is not initialized at declaration.
-Language/05_Variables/05_Variables_A08_t01: Fail # Checks that a compile-time error occurs if a constant variable is not initialized.
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # Checks that static variable declaration can't be a required formal parameter
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: Fail # Checks that a functionSignature parameter cannot be final.
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: Fail # Checks that a functionSignature parameter cannot be declared as variable.
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # TODO(ahe): Enforce optional parameter semantics.
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: Fail # TODO(ahe): Enforce optional parameter semantics.
-Language/07_Classes/07_Classes_A02_t11: Fail # Checks that it is a compile-time error if a static final variable declaration does not include explicit initializer.
-Language/12_Expressions/01_Constants_A20_t03: Fail # Checks that an identifier expression that denotes a type parameter can not be assigned to a constant variable.
-Language/12_Expressions/05_Strings/1_String_Interpolation_A01_t09: Fail # Checks that it is a compile-time error if a string interpolation construct does not start with IDENTIFIER_NO_DOLLAR or opening brace.
-Language/12_Expressions/05_Strings_A02_t46: Fail # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
-Language/12_Expressions/05_Strings_A02_t48: Fail # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
-Language/12_Expressions/30_Identifier_Reference_A04_t09: Fail # Checks that it is a compile-time error when a built-in identifier dynamic is used as the declared name of a type variable.
-Language/12_Expressions/30_Identifier_Reference_A05_t01: Fail # Checks that it is a compile-time error when a built-in identifier "abstract" is used as a type annotation of a local variable.
-Language/12_Expressions/30_Identifier_Reference_A05_t12: Fail # Checks that it is a compile-time error when a built-in identifier "static" is used as a type annotation of a local variable.
-Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: Fail # Checks that other Unicode whitespaces are not allowed: check NO-BREAK SPACE (U+00A0)
-Language/16_Reference/1_Lexical_Rules_A02_t06: Fail # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
+Language/05_Variables/05_Variables_A07_t07: MissingCompileTimeError # Checks that a compile-time error occurs if a global constant variable is not initialized at declaration.
+Language/05_Variables/05_Variables_A07_t08: MissingCompileTimeError # Checks that a compile-time error occurs if a global typed constant variable is not initialized at declaration.
+Language/05_Variables/05_Variables_A08_t01: MissingCompileTimeError # Checks that a compile-time error occurs if a constant variable is not initialized.
+Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: MissingCompileTimeError # Checks that a functionSignature parameter cannot be final.
+Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: MissingCompileTimeError # Checks that a functionSignature parameter cannot be declared as variable.
+Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: MissingCompileTimeError # TODO(ahe): Enforce optional parameter semantics.
+Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: MissingCompileTimeError # TODO(ahe): Enforce optional parameter semantics.
+Language/07_Classes/07_Classes_A02_t11: MissingCompileTimeError # Checks that it is a compile-time error if a static final variable declaration does not include explicit initializer.
+Language/12_Expressions/01_Constants_A20_t03: MissingCompileTimeError # Checks that an identifier expression that denotes a type parameter can not be assigned to a constant variable.
+Language/12_Expressions/05_Strings/1_String_Interpolation_A01_t09: MissingCompileTimeError # Checks that it is a compile-time error if a string interpolation construct does not start with IDENTIFIER_NO_DOLLAR or opening brace.
+Language/12_Expressions/05_Strings_A02_t46: MissingCompileTimeError # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
+Language/12_Expressions/05_Strings_A02_t48: MissingCompileTimeError # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
+Language/12_Expressions/30_Identifier_Reference_A04_t09: MissingCompileTimeError # Checks that it is a compile-time error when a built-in identifier dynamic is used as the declared name of a type variable.
+Language/12_Expressions/30_Identifier_Reference_A05_t01: MissingCompileTimeError # Checks that it is a compile-time error when a built-in identifier "abstract" is used as a type annotation of a local variable.
+Language/12_Expressions/30_Identifier_Reference_A05_t12: MissingCompileTimeError # Checks that it is a compile-time error when a built-in identifier "static" is used as a type annotation of a local variable.
+Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: MissingCompileTimeError # Checks that other Unicode whitespaces are not allowed: check NO-BREAK SPACE (U+00A0)
+Language/16_Reference/1_Lexical_Rules_A02_t06: MissingCompileTimeError # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
#
# Unexpected compile-time errors.
#
[ $compiler == dart2js ]
-Language/07_Classes/3_Setters_A04_t01: Fail # http://dartbug.com/5023
-Language/07_Classes/3_Setters_A04_t02: Fail # http://dartbug.com/5023
-Language/07_Classes/3_Setters_A04_t03: Fail # http://dartbug.com/5023
-Language/07_Classes/3_Setters_A04_t04: Fail # http://dartbug.com/5023
-Language/07_Classes/3_Setters_A04_t05: Fail # http://dartbug.com/5023
-Language/07_Classes/3_Setters_A04_t06: Fail # http://dartbug.com/5023
-Language/07_Classes/3_Setters_A04_t07: Fail # http://dartbug.com/5023
+Language/07_Classes/3_Setters_A04_t01: CompileTimeError # http://dartbug.com/5023
+Language/07_Classes/3_Setters_A04_t02: CompileTimeError # http://dartbug.com/5023
+Language/07_Classes/3_Setters_A04_t03: CompileTimeError # http://dartbug.com/5023
+Language/07_Classes/3_Setters_A04_t04: CompileTimeError # http://dartbug.com/5023
+Language/07_Classes/3_Setters_A04_t05: CompileTimeError # http://dartbug.com/5023
+Language/07_Classes/3_Setters_A04_t06: CompileTimeError # http://dartbug.com/5023
+Language/07_Classes/3_Setters_A04_t07: CompileTimeError # http://dartbug.com/5023
[ $compiler == dart2js && $runtime == ie9 ]
@@ -426,15 +417,10 @@
Language/05_Variables/05_Variables_A05_t02: fail # co19-roll r546: Please triage this failure
Language/07_Classes/1_Instance_Methods_A01_t01: fail # co19-roll r559: Please triage this failure
Language/07_Classes/1_Instance_Methods_A01_t02: fail # co19-roll r559: Please triage this failure
-Language/07_Classes/1_Instance_Methods_A01_t03: fail # co19-roll r559: Please triage this failure
-Language/07_Classes/1_Instance_Methods_A01_t04: fail # co19-roll r559: Please triage this failure
-Language/07_Classes/1_Instance_Methods_A01_t05: fail # co19-roll r559: Please triage this failure
-Language/07_Classes/1_Instance_Methods_A01_t06: fail # co19-roll r559: Please triage this failure
Language/07_Classes/4_Abstract_Instance_Members_A03_t01: fail # co19-roll r559: Please triage this failure
Language/07_Classes/4_Abstract_Instance_Members_A03_t02: fail # co19-roll r559: Please triage this failure
Language/07_Classes/4_Abstract_Instance_Members_A03_t03: fail # co19-roll r559: Please triage this failure
Language/07_Classes/4_Abstract_Instance_Members_A03_t04: fail # co19-roll r559: Please triage this failure
-Language/07_Classes/4_Abstract_Instance_Members_A03_t05: fail # co19-roll r559: Please triage this failure
Language/12_Expressions/00_Object_Identity/1_Object_Identity_A02_t02: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/00_Object_Identity/1_Object_Identity_A06_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/00_Object_Identity/1_Object_Identity_A06_t02: fail # co19-roll r546: Please triage this failure
@@ -501,47 +487,47 @@
LibTest/isolate/IsolateStream/any_A02_t01: fail # co19-roll r546: Please triage this failure
LibTest/isolate/IsolateStream/contains_A02_t01: fail # co19-roll r546: Please triage this failure
LibTest/isolate/SendPort/send_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/typed_data/Float32List/Float32List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32List/Float32List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32List/Float32List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float32List/Float32List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float32List/Float32List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float32List/Float32List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32List/fold_A01_t01: fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32List/join_A01_t01: fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32List/join_A01_t02: fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32x4/clamp_A01_t01: fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32x4List/Float32x4List.view_A02_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32x4List/Float32x4List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32x4List/Float32x4List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32x4List/Float32x4List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float32x4List/Float32x4List.view_A02_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float32x4List/Float32x4List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float32x4List/Float32x4List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float32x4List/Float32x4List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32x4List/fold_A01_t01: fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32x4List/join_A01_t01: fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32x4List/join_A01_t02: fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float64List/Float64List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float64List/Float64List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float64List/Float64List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float64List/Float64List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float64List/Float64List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float64List/Float64List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
LibTest/typed_data/Float64List/fold_A01_t01: fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Float64List/join_A01_t01: fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Float64List/join_A01_t02: fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int16List/Int16List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int16List/Int16List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int16List/Int16List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int32List/Int32List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int32List/Int32List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int32List/Int32List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int8List/Int8List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int8List/Int8List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int8List/Int8List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint16List/Uint16List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint16List/Uint16List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint16List/Uint16List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint32List/Uint32List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint32List/Uint32List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint32List/Uint32List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint8List/Uint8List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint8List/Uint8List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint8List/Uint8List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int16List/Int16List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int16List/Int16List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int16List/Int16List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int32List/Int32List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int32List/Int32List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int32List/Int32List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int8List/Int8List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int8List/Int8List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int8List/Int8List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint16List/Uint16List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint16List/Uint16List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint16List/Uint16List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint32List/Uint32List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint32List/Uint32List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint32List/Uint32List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint8List/Uint8List.view_A05_t01: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint8List/Uint8List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint8List/Uint8List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this failure
[ $compiler == dart2js && $checked ]
@@ -594,7 +580,7 @@
# Could this be dart issue 7728?
[ $compiler == dart2js && ($runtime == d8 || $runtime == jsshell) ]
-LibTest/async/Future/Future.delayed_A01_t01: Fail # co19-roll r546: Please triage this failure
+LibTest/async/Future/Future.delayed_A01_t01: RuntimeError # co19-roll r546: Please triage this failure
LibTest/async/Future/Future.delayed_A03_t01: fail # co19-roll r546: Please triage this failure
LibTest/async/Stream/first_A01_t01: fail # co19-roll r546: Please triage this failure
LibTest/async/Stream/first_A02_t02: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 33966f7..719fc5d 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -72,7 +72,6 @@
Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: fail # Dart issue 12543
Language/12_Expressions/05_Strings_A02_t46: fail # Dart issue 12547
Language/12_Expressions/05_Strings_A02_t48: fail # Dart issue 12547
-Language/12_Expressions/05_Strings_A20_t01: fail # Dart issue 12518
Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: fail # Dart issue 12549
Language/12_Expressions/12_Instance_Creation/1_New_A09_t09: fail # Dart issue 1372
Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: fail # co19 issue 525
@@ -88,22 +87,15 @@
Language/13_Statements/03_Variable_Declaration_A04_t08: fail # co19 issue 535
Language/13_Statements/06_For_A01_t11: fail # Dart issue 5675
Language/13_Statements/09_Switch_A01_t02: fail # Dart issue 12908
-Language/13_Statements/09_Switch_A02_t02: fail # Dart issue 7307
-Language/13_Statements/09_Switch_A03_t01: fail # Dart issue 7307
-Language/13_Statements/09_Switch_A03_t02: fail # Dart issue 7307
-Language/13_Statements/09_Switch_A04_t01: fail # Dart issue 11233
Language/13_Statements/12_Labels_A01_t03: fail # Dart issue 2238
Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail # Dart issue 12915
Language/14_Libraries_and_Scripts/2_Exports_A04_t02: fail # Dart issue 12916
Language/14_Libraries_and_Scripts/2_Exports_A04_t03: fail # Dart issue 12916
Language/14_Libraries_and_Scripts/2_Exports_A05_t01: fail # Dart issue 12918
-Language/14_Libraries_and_Scripts/5_URIs_A01_t01: fail # Issue 12521
Language/14_Libraries_and_Scripts/5_URIs_A01_t04: fail # Issue 12521
Language/14_Libraries_and_Scripts/5_URIs_A01_t05: fail # Issue 12521
-Language/14_Libraries_and_Scripts/5_URIs_A01_t11: fail # Issue 12521
Language/14_Libraries_and_Scripts/5_URIs_A01_t14: fail # Issue 12521
Language/14_Libraries_and_Scripts/5_URIs_A01_t15: fail # Issue 12521
-Language/14_Libraries_and_Scripts/5_URIs_A01_t21: fail # Issue 12518
LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
@@ -149,3 +141,13 @@
Language/15_Types/4_Interface_Types_A11_t01: pass, timeout # Issue 13349
Language/15_Types/4_Interface_Types_A11_t02: pass, timeout # Issue 13349
+[ $compiler == none && $runtime == vm ]
+LibTest/typed_data/Float32x4/clamp_A01_t01: Pass, Fail # Issue 13543
+LibTest/typed_data/Float32x4/clamp_A02_t01: Pass, Fail # Issue 13543
+LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # Issue 13543
+LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # Issue 13543
+LibTest/typed_data/Float32x4/toUint32x4_A01_t01: Fail # co19 Issue 601
+LibTest/typed_data/Float32x4/toUint32x4_A01_t02: Fail # co19 Issue 601
+LibTest/typed_data/Uint32x4/toFloat32x4_A01_t01: Fail # co19 Issue 601
+LibTest/typed_data/Uint32x4/toFloat32x4_A01_t02: Fail # co19 Issue 601
+
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index 818149a..e189790 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -55,7 +55,7 @@
(String code, List errors, List warnings) {
Expect.isNull(code);
Expect.equals(1, errors.length);
- Expect.equals('Error: Could not find "main".', errors[0].toString());
+ Expect.equals("Error: Could not find 'main'.", errors[0].toString());
Expect.isTrue(warnings.isEmpty);
});
@@ -75,7 +75,7 @@
Expect.isNull(code);
Expect.equals(1, errors.length);
Expect.isTrue(
- errors[0].toString().startsWith('Error: Could not find "main".'));
+ errors[0].toString().startsWith("Error: Could not find 'main'."));
Expect.isTrue(warnings.isEmpty);
});
@@ -95,7 +95,7 @@
Expect.isNull(code);
Expect.equals(1, errors.length);
Expect.isTrue(
- errors[0].toString().startsWith('Error: Could not find "main".'));
+ errors[0].toString().startsWith("Error: Could not find 'main'."));
Expect.isTrue(warnings.isEmpty);
});
@@ -109,7 +109,7 @@
Expect.isTrue(errors.isEmpty);
Expect.equals(1, warnings.length);
Expect.equals(
- 'Warning: Cannot resolve type "Foo".', warnings[0].toString());
+ "Warning: Cannot resolve type 'Foo'.", warnings[0].toString());
});
runCompiler(
@@ -130,7 +130,7 @@
Expect.isNull(code);
Expect.isTrue(errors.isEmpty);
Expect.equals(
- 'Warning: Cannot resolve type "Foo".', warnings[0].toString());
+ "Warning: Cannot resolve type 'Foo'.", warnings[0].toString());
});
runCompiler(
@@ -142,7 +142,7 @@
Expect.isTrue(errors.isEmpty);
Expect.equals(1, warnings.length);
Expect.equals(
- 'Warning: Cannot resolve type "Foo".', warnings[0].toString());
+ "Warning: Cannot resolve type 'Foo'.", warnings[0].toString());
});
runCompiler(
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index 355d2cf..508010c 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -179,7 +179,8 @@
}
testVariableDefinitions() {
- testDart2Dart('main(){final var x,y;final String s;}');
+ testDart2Dart('main(){var x,y;final String s;}');
+ testDart2Dart('main(){final int x,y;final String s;}');
testDart2Dart('foo(f,g){}main(){foo(1,2);}');
testDart2Dart('foo(f(arg)){}main(){foo(main);}');
// A couple of static/finals inside a class.
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index 31ff16d..2ffcc04 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -29,7 +29,7 @@
['--analyze-only']);
asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
var main = compiler.mainApp.find(dart2js.Compiler.MAIN);
- Expect.isNotNull(main, 'Could not find "main"');
+ Expect.isNotNull(main, "Could not find 'main'");
compiler.deferredLoadTask.onResolutionComplete(main);
var deferredClasses =
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index cc7d02c..0ebba79 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -33,13 +33,13 @@
asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
diagnostics.sort();
var expected = [
- 'memory:exporter.dart:43:47:Info: "function(hest)" is defined here.'
- ':info',
- 'memory:library.dart:41:45:Info: "function(hest)" is defined here.'
- ':info',
- 'memory:main.dart:0:22:Info: "function(hest)" is imported here.:info',
- 'memory:main.dart:23:46:Info: "function(hest)" is imported here.:info',
- 'memory:main.dart:86:90:Error: Duplicate import of "hest".:error'
+ "memory:exporter.dart:43:47:Info: 'function(hest)' is defined here."
+ ":info",
+ "memory:library.dart:41:45:Info: 'function(hest)' is defined here."
+ ":info",
+ "memory:main.dart:0:22:Info: 'function(hest)' is imported here.:info",
+ "memory:main.dart:23:46:Info: 'function(hest)' is imported here.:info",
+ "memory:main.dart:86:90:Error: Duplicate import of 'hest'.:error"
];
Expect.listEquals(expected, diagnostics);
Expect.isTrue(compiler.compilationFailed);
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 6fc97af..4aee0ac 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -446,6 +446,18 @@
}
""";
+const String TEST_26 = r"""
+ class A {
+ var f1 = 42;
+ }
+ class B {
+ var f1 = 54;
+ }
+ main() {
+ new A().f1 = [new B(), new A()][0].f1 + 42;
+ }
+""";
+
void doTest(String test, bool disableInlining, Map<String, Function> fields) {
fields.forEach((String name, Function f) {
compileAndFind(
@@ -533,6 +545,7 @@
'f6': (compiler) => compiler.typesTask.stringType.nullable()});
runTest(TEST_25, {'f1': (compiler) => compiler.typesTask.intType });
+ runTest(TEST_26, {'f1': (compiler) => compiler.typesTask.intType });
}
void main() {
diff --git a/tests/compiler/dart2js/list_tracer3_test.dart b/tests/compiler/dart2js/list_tracer3_test.dart
new file mode 100644
index 0000000..d8fb177
--- /dev/null
+++ b/tests/compiler/dart2js/list_tracer3_test.dart
@@ -0,0 +1,45 @@
+// 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.
+
+// We used to always nullify the element type of a list we are tracing in
+// the presence of a fixed length list constructor call.
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import
+ '../../../sdk/lib/_internal/compiler/implementation/types/types.dart'
+ show ContainerTypeMask, TypeMask;
+
+import 'compiler_helper.dart';
+import 'parser_helper.dart';
+
+
+const String TEST = r'''
+var myList = [];
+var otherList = ['foo', 42];
+main() {
+ var a = otherList[0];
+ a += 54;
+ myList.add(a);
+}
+''';
+
+void main() {
+ Uri uri = new Uri(scheme: 'source');
+ var compiler = compilerFor(TEST, uri);
+ asyncTest(() => compiler.runCompiler(uri).then((_) {
+ var typesInferrer = compiler.typesTask.typesInferrer;
+
+ checkType(String name, type) {
+ var element = findElement(compiler, name);
+ ContainerTypeMask mask = typesInferrer.getTypeOfElement(element);
+ Expect.equals(type, mask.elementType.simplify(compiler), name);
+ }
+
+ var interceptorType =
+ findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
+
+ checkType('myList', interceptorType);
+ }));
+}
diff --git a/tests/compiler/dart2js/list_tracer_node_type_test.dart b/tests/compiler/dart2js/list_tracer_node_type_test.dart
index aa3e859..dfefd9b 100644
--- a/tests/compiler/dart2js/list_tracer_node_type_test.dart
+++ b/tests/compiler/dart2js/list_tracer_node_type_test.dart
@@ -56,6 +56,15 @@
}
""";
+String generateTest(String call) {
+ return """
+main() {
+ var a = [42];
+ return a.$call + 42;
+}
+""";
+}
+
main() {
asyncTest(() => compileAll(TEST1).then((generated) {
@@ -88,4 +97,21 @@
asyncTest(() => compileAll(TEST6).then((generated) {
Expect.isFalse(generated.contains('iae'));
}));
+
+ var selectors = const <String>[
+ 'first',
+ 'last',
+ 'single',
+ 'singleWhere',
+ 'elementAt',
+ 'removeAt',
+ 'removeLast'
+ ];
+ selectors.map((name) => generateTest('$name()')).forEach((String test) {
+ asyncTest(() => compileAll(test).then((generated) {
+ Expect.isFalse(generated.contains('if (typeof t1'));
+ Expect.isFalse(generated.contains('if (t1 == null)'));
+ }));
+ });
+
}
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 9cac4af..eb5f588 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -88,9 +88,7 @@
createDiagnosticHandler(diagnosticHandler, provider, showDiagnostics);
EventSink<String> outputProvider(String name, String extension) {
- if (name != '' && name != 'precompiled') {
- throw 'Attempt to output file "$name.$extension"';
- }
+ if (name != '') throw 'Attempt to output file "$name.$extension"';
return new NullSink('$name.$extension');
}
diff --git a/tests/compiler/dart2js/missing_file_test.dart b/tests/compiler/dart2js/missing_file_test.dart
index 3fc09f8..c354d0f 100644
--- a/tests/compiler/dart2js/missing_file_test.dart
+++ b/tests/compiler/dart2js/missing_file_test.dart
@@ -48,9 +48,7 @@
EventSink<String> outputProvider(String name, String extension) {
- if (name != '' && name != 'precompiled') {
- throw 'Attempt to output file "$name.$extension"';
- }
+ if (name != '') throw 'Attempt to output file "$name.$extension"';
return new NullSink('$name.$extension');
}
diff --git a/tests/compiler/dart2js/package_root_test.dart b/tests/compiler/dart2js/package_root_test.dart
index 2452389..3b74c09 100644
--- a/tests/compiler/dart2js/package_root_test.dart
+++ b/tests/compiler/dart2js/package_root_test.dart
@@ -48,9 +48,7 @@
EventSink<String> outputProvider(String name, String extension) {
- if (name != '' && name != 'precompiled') {
- throw 'Attempt to output file "$name.$extension"';
- }
+ if (name != '') throw 'Attempt to output file "$name.$extension"';
return new NullSink('$name.$extension');
}
@@ -63,8 +61,8 @@
asyncTest(() => compiler.run(main).then((_) {
Expect.equals(1, errors.length);
- Expect.equals('Error: Cannot resolve "package:foo/foo.dart". '
- 'Package root has not been set.',
+ Expect.equals("Error: Cannot resolve 'package:foo/foo.dart'. "
+ "Package root has not been set.",
errors[0]);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_callers_test.dart b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
index 616c819..6b1381b 100644
--- a/tests/compiler/dart2js/simple_inferrer_callers_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
@@ -8,7 +8,7 @@
import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart";
import '../../../sdk/lib/_internal/compiler/implementation/types/types.dart';
-import '../../../sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart';
import 'compiler_helper.dart';
import 'parser_helper.dart';
@@ -30,7 +30,7 @@
// Create our own type inferrer to avoid clearing out the internal
// data structures.
-class MyInferrer extends SimpleTypesInferrer {
+class MyInferrer extends TypeGraphInferrer {
MyInferrer(compiler) : super(compiler);
clear() {}
}
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
index 7a1e29b..fdb9cc8 100644
--- a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
@@ -23,9 +23,9 @@
returnNum3() => --this[index];
returnNum4() => this[index] -= 42;
- returnDynamic3() => this.bar--;
- returnNum5() => --this.bar;
- returnNum6() => this.bar -= 42;
+ returnEmpty3() => this.bar--;
+ returnEmpty1() => --this.bar;
+ returnEmpty2() => this.bar -= 42;
}
class B extends A {
@@ -72,7 +72,8 @@
var cls = findElement(compiler, className);
var element = cls.lookupLocalMember(buildSourceString(methodName));
Expect.equals(type,
- typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+ typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+ methodName);
}
var subclassOfInterceptor =
@@ -82,11 +83,11 @@
checkReturnInClass('A', 'returnNum2', typesTask.numType);
checkReturnInClass('A', 'returnNum3', typesTask.numType);
checkReturnInClass('A', 'returnNum4', typesTask.numType);
- checkReturnInClass('A', 'returnNum5', typesTask.numType);
- checkReturnInClass('A', 'returnNum6', typesTask.numType);
+ checkReturnInClass('A', 'returnEmpty1', const TypeMask.nonNullEmpty());
+ checkReturnInClass('A', 'returnEmpty2', const TypeMask.nonNullEmpty());
checkReturnInClass('A', 'returnDynamic1', subclassOfInterceptor);
checkReturnInClass('A', 'returnDynamic2', subclassOfInterceptor);
- checkReturnInClass('A', 'returnDynamic3', typesTask.dynamicType);
+ checkReturnInClass('A', 'returnEmpty3', const TypeMask.nonNullEmpty());
checkReturnInClass('B', 'returnString1', typesTask.stringType);
checkReturnInClass('B', 'returnString2', typesTask.stringType);
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 9af3822..45b882a 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -74,12 +74,12 @@
return 42.remainder(54);
}
-returnDynamic1() {
+returnEmpty1() {
// Ensure that we don't intrisify a wrong call to [int.remainder].
return 42.remainder();
}
-returnDynamic2() {
+returnEmpty2() {
// Ensure that we don't intrisify a wrong call to [int.abs].
return 42.abs(42);
}
@@ -578,8 +578,8 @@
returnInt8();
returnIntOrNull(true);
returnDynamic();
- returnDynamic1();
- returnDynamic2();
+ returnEmpty1();
+ returnEmpty2();
testIsCheck1(topLevelGetter());
testIsCheck2(topLevelGetter());
testIsCheck3(topLevelGetter());
@@ -690,8 +690,8 @@
checkReturn('returnInt4', typesTask.intType);
checkReturn('returnInt7', typesTask.intType);
checkReturn('returnInt8', typesTask.intType);
- checkReturn('returnDynamic1', typesTask.dynamicType);
- checkReturn('returnDynamic2', typesTask.dynamicType);
+ checkReturn('returnEmpty1', const TypeMask.nonNullEmpty());
+ checkReturn('returnEmpty2', const TypeMask.nonNullEmpty());
TypeMask intType = new TypeMask.nonNullSubtype(compiler.intClass.rawType);
checkReturn('testIsCheck1', intType);
checkReturn('testIsCheck2', intType);
diff --git a/tests/compiler/dart2js/unneeded_part_js_test.dart b/tests/compiler/dart2js/unneeded_part_js_test.dart
index eef894c..c8c0f20 100644
--- a/tests/compiler/dart2js/unneeded_part_js_test.dart
+++ b/tests/compiler/dart2js/unneeded_part_js_test.dart
@@ -31,9 +31,7 @@
}
EventSink<String> outputProvider(String name, String extension) {
- if (name != '' && name != 'precompiled') {
- throw 'Attempt to output file "$name.$extension"';
- }
+ if (name != '') throw 'Attempt to output file "$name.$extension"';
return new NullSink('$name.$extension');
}
diff --git a/tests/compiler/dart2js_native/only_pass_on_d8_test.dart b/tests/compiler/dart2js_native/only_pass_on_d8_test.dart
index db44fc6..4ef8432 100644
--- a/tests/compiler/dart2js_native/only_pass_on_d8_test.dart
+++ b/tests/compiler/dart2js_native/only_pass_on_d8_test.dart
@@ -4,9 +4,9 @@
import 'package:expect/expect.dart';
-import 'dart:_isolate_helper';
+import 'dart:_js_helper' show Primitives;
main() {
- Expect.isTrue(IsolateNatives.isD8);
- Expect.isFalse(IsolateNatives.isJsshell);
+ Expect.isTrue(Primitives.isD8);
+ Expect.isFalse(Primitives.isJsshell);
}
diff --git a/tests/compiler/dart2js_native/only_pass_on_jsshell_test.dart b/tests/compiler/dart2js_native/only_pass_on_jsshell_test.dart
index 8bb4811..17fce76 100644
--- a/tests/compiler/dart2js_native/only_pass_on_jsshell_test.dart
+++ b/tests/compiler/dart2js_native/only_pass_on_jsshell_test.dart
@@ -4,9 +4,9 @@
import 'package:expect/expect.dart';
-import 'dart:_isolate_helper';
+import 'dart:_js_helper' show Primitives;
main() {
- Expect.isFalse(IsolateNatives.isD8);
- Expect.isTrue(IsolateNatives.isJsshell);
+ Expect.isFalse(Primitives.isD8);
+ Expect.isTrue(Primitives.isJsshell);
}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index e58bc11..2c2c7b9 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -2,11 +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.
-[ $compiler == dart2js && $runtime == drt ]
-hash_set_test: Pass, Fail # v8 bug: Issue 12293
-list_test: Pass, Fail # v8 bug: Issue 12293
-
-
[ $compiler == none ]
unicode_test: Fail # Bug 6706
compare_to2_test: Fail # Bug 4018
@@ -38,12 +33,13 @@
unicode_test: Fail
[ $compiler == dart2js ]
-error_stack_trace1_test: Fail # Issue 12399
+error_stack_trace1_test: RuntimeError # Issue 12399
+hash_set_test/01: RuntimeError # Issue 11551
-big_integer_vm_test: Fail, OK # VM specific test.
-bit_twiddling_bigint_test: Fail # Requires bigint support.
-compare_to2_test: Fail, OK # Requires bigint support.
-string_base_vm_test: Fail, OK # VM specific test.
+big_integer_vm_test: RuntimeError, OK # VM specific test.
+bit_twiddling_bigint_test: RuntimeError # Requires bigint support.
+compare_to2_test: RuntimeError, OK # Requires bigint support.
+string_base_vm_test: RuntimeError, OK # VM specific test.
[ $compiler == dart2js && $runtime == none ]
*: Fail, Pass # TODO(ahe): Triage these tests.
@@ -65,16 +61,16 @@
# Library changes
[ $compiler == none || $compiler == dart2js || $compiler == dart2dart ]
-map_keys2_test: Fail # Generic types aren't right.
+map_keys2_test: RuntimeError # Generic types aren't right.
[ $compiler == dart2js ]
-map_values2_test: Fail # Generic types aren't right
+map_values2_test: RuntimeError # Generic types aren't right
## Tests failing after merge of experimental library branch.
[ $compiler == dart2js ]
# Tests fail due to bug in generics on constants, issue 6827
-iterable_to_list_test: Fail
-iterable_to_set_test: Fail
+iterable_to_list_test: RuntimeError
+iterable_to_set_test: RuntimeError
[ $compiler == dart2dart && $minified ]
error_stack_trace1_test: Fail # Fails in minified mode, test depends on method names.
diff --git a/tests/corelib/expando_test.dart b/tests/corelib/expando_test.dart
index 3bff957..d55aecf 100644
--- a/tests/corelib/expando_test.dart
+++ b/tests/corelib/expando_test.dart
@@ -21,6 +21,7 @@
Expect.equals(2, visits[object]);
}
testIllegal();
+ testIdentity();
}
static visit(object) {
@@ -78,6 +79,31 @@
Expect.throws(() => expando[false], (exception)
=> exception is ArgumentError);
}
+
+ static testIdentity() {
+ // Expando only depends on identity of object.
+ Expando<int> expando = new Expando<int>();
+ var m1 = new Mutable(1);
+ var m2 = new Mutable(7);
+ var m3 = new Mutable(13);
+ expando[m1] = 42;
+ Expect.equals(42, expando[m1]);
+ m1.id = 37;
+ Expect.equals(42, expando[m1]);
+ expando[m2] = 37;
+ expando[m3] = 10;
+ m3.id = 1;
+ Expect.equals(42, expando[m1]);
+ Expect.equals(37, expando[m2]);
+ Expect.equals(10, expando[m3]);
+ }
}
main() => ExpandoTest.testMain();
+
+class Mutable {
+ int id;
+ Mutable(this.id);
+ int get hashCode => id;
+ bool operator==(other) => other is Mutable && other.id == id;
+}
diff --git a/tests/corelib/hash_set_test.dart b/tests/corelib/hash_set_test.dart
index 175cba5..0628610 100644
--- a/tests/corelib/hash_set_test.dart
+++ b/tests/corelib/hash_set_test.dart
@@ -9,7 +9,7 @@
import "package:expect/expect.dart";
import 'dart:collection';
-testSet(Set newSet(), Set newSetFrom(Set from)) {
+testSet(Set newSet(), Set newSetFrom(Iterable from)) {
Set gen(int from, int to) =>
new Set.from(new Iterable.generate(to - from, (n) => n + from));
@@ -220,9 +220,60 @@
}
}
+
+void testIdentitySet(Set create()) {
+ Set set = create();
+ set.add(1);
+ set.add(2);
+ set.add(1); // Integers are identical if equal.
+ Expect.equals(2, set.length);
+ var complex = 4;
+ complex = set.length == 2 ? complex ~/ 4 : 87; // Avoid compile-time constant.
+ Expect.isTrue(set.contains(complex)); // 1 is in set, even if computed.
+ set.clear();
+
+ // All compile time constants are identical to themselves.
+ var constants = [double.INFINITY,
+ double.NAN, -0.0, /// 01: ok
+ 0.0, 42, "", null, false, true, #bif, testIdentitySet];
+ set.addAll(constants);
+ Expect.equals(constants.length, set.length);
+ for (var c in constants) {
+ Expect.isTrue(set.contains(c), "constant: $c");
+ }
+ Expect.isTrue(set.containsAll(constants), "constants: $set");
+ set.clear();
+
+ var m1 = new Mutable(1);
+ var m2 = new Mutable(2);
+ var m3 = new Mutable(3);
+ var m4 = new Mutable(2); // Equal to m2, but not identical.
+ set.addAll([m1, m2, m3, m4]);
+ Expect.equals(4, set.length);
+ Expect.equals(3, m3.hashCode);
+ m3.id = 1;
+ Expect.equals(1, m3.hashCode);
+ // Changing hashCode doesn't affect lookup.
+ Expect.isTrue(set.contains(m3));
+ Expect.isTrue(set.contains(m1));
+ set.remove(m3);
+ Expect.isFalse(set.contains(m3));
+ Expect.isTrue(set.contains(m1));
+}
+
+
void main() {
+ testSet(() => new Set(), (m) => new Set.from(m));
testSet(() => new HashSet(), (m) => new HashSet.from(m));
testSet(() => new LinkedHashSet(), (m) => new LinkedHashSet.from(m));
+ testIdentitySet(() => new Set.identity());
+ testIdentitySet(() => new HashSet.identity());
+ testIdentitySet(() => new LinkedHashSet.identity());
+ testIdentitySet(() => new HashSet(equals: (x, y) => identical(x, y),
+ hashCode: (x) => identityHashCode(x)));
+ testIdentitySet(
+ () => new LinkedHashSet(equals: (x, y) => identical(x, y),
+ hashCode: (x) => identityHashCode(x)));
}
@@ -235,3 +286,10 @@
// Can't make a bad compareTo that isn't invalid.
int compareTo(BadHashCode other) => id - other.id;
}
+
+class Mutable {
+ int id;
+ Mutable(this.id);
+ int get hashCode => id;
+ bool operator==(other) => other is Mutable && id == other.id;
+}
diff --git a/tests/corelib/hashcode_test.dart b/tests/corelib/hashcode_test.dart
new file mode 100644
index 0000000..41a272f
--- /dev/null
+++ b/tests/corelib/hashcode_test.dart
@@ -0,0 +1,48 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class Override {
+ int hash;
+ int get superHash => super.hashCode;
+ int get hashCode => hash;
+
+ int foo() => hash; // Just some function that can be closurized.
+
+ bool operator==(Object other) =>
+ other is Override && (other as Override).hash == hash;
+}
+
+int bar() => 42; // Some global function.
+
+main() {
+ var o = new Object();
+ var hash = o.hashCode;
+ // Doesn't change.
+ Expect.equals(hash, o.hashCode);
+ Expect.equals(hash, identityHashCode(o));
+
+ var c = new Override();
+ int identityHash = c.superHash;
+ hash = (identityHash == 42) ? 37 : 42;
+ c.hash = hash;
+ Expect.equals(hash, c.hashCode);
+ Expect.equals(identityHash, identityHashCode(c));
+
+ // These classes don't override hashCode.
+ var samples = [0, 0x10000000, 1.5, -0, null, true, false, const Object()];
+ for (var v in samples) {
+ print(v);
+ Expect.equals(v.hashCode, identityHashCode(v));
+ }
+ // These do, or might do, but we can still use hashCodeOf and get the same
+ // result each time.
+ samples = ["string", "", (x) => 42, c.foo, bar];
+ for (var v in samples) {
+ print(v);
+ Expect.equals(v.hashCode, v.hashCode);
+ Expect.equals(identityHashCode(v), identityHashCode(v));
+ }
+}
diff --git a/tests/corelib/map_test.dart b/tests/corelib/map_test.dart
index 7e9d50d..d782bcd 100644
--- a/tests/corelib/map_test.dart
+++ b/tests/corelib/map_test.dart
@@ -29,12 +29,12 @@
testNumericKeys(new Map<num, String>());
testNumericKeys(new HashMap());
testNumericKeys(new HashMap<num, String>());
- testNumericKeys(new HashMap(equals: identical));
- testNumericKeys(new HashMap<num, String>(equals: identical));
+ testNumericKeys(new HashMap.identity());
+ testNumericKeys(new HashMap<num, String>.identity());
testNumericKeys(new LinkedHashMap());
testNumericKeys(new LinkedHashMap<num, String>());
- testNumericKeys(new LinkedHashMap(equals: identical));
- testNumericKeys(new LinkedHashMap<num, String>(equals: identical));
+ testNumericKeys(new LinkedHashMap.identity());
+ testNumericKeys(new LinkedHashMap<num, String>.identity());
testNaNKeys(new Map());
testNaNKeys(new Map<num, String>());
@@ -45,8 +45,17 @@
// Identity maps fail the NaN-keys tests because the test assumes that
// NaN is not equal to NaN.
- testIdentityMap(new HashMap(equals: identical));
- testIdentityMap(new LinkedHashMap(equals: identical));
+ testIdentityMap(new Map.identity());
+ testIdentityMap(new HashMap.identity());
+ testIdentityMap(new LinkedHashMap.identity());
+ testIdentityMap(new HashMap(equals: identical,
+ hashCode: identityHashCode));
+ testIdentityMap(new LinkedHashMap(equals: identical,
+ hashCode: identityHashCode));
+ testIdentityMap(new HashMap(equals: (x, y) => identical(x, y),
+ hashCode: (x) => identityHashCode(x)));
+ testIdentityMap(new LinkedHashMap(equals: (x, y) => identical(x, y),
+ hashCode: (x) => identityHashCode(x)));
testCustomMap(new HashMap(equals: myEquals, hashCode: myHashCode,
isValidKey: (v) => v is Customer));
@@ -59,7 +68,7 @@
hashCode: myHashCode));
testIterationOrder(new LinkedHashMap());
- testIterationOrder(new LinkedHashMap(equals: identical));
+ testIterationOrder(new LinkedHashMap.identity());
testOtherKeys(new SplayTreeMap<int, int>());
testOtherKeys(new SplayTreeMap<int, int>((int a, int b) => a - b,
@@ -67,14 +76,14 @@
testOtherKeys(new SplayTreeMap((int a, int b) => a - b,
(v) => v is int));
testOtherKeys(new HashMap<int, int>());
- testOtherKeys(new HashMap<int, int>(equals: identical));
+ testOtherKeys(new HashMap<int, int>.identity());
testOtherKeys(new HashMap<int, int>(hashCode: (v) => v.hashCode,
isValidKey: (v) => v is int));
testOtherKeys(new HashMap(equals: (int x, int y) => x == y,
hashCode: (int v) => v.hashCode,
isValidKey: (v) => v is int));
testOtherKeys(new LinkedHashMap<int, int>());
- testOtherKeys(new LinkedHashMap<int, int>(equals: identical));
+ testOtherKeys(new LinkedHashMap<int, int>.identity());
testOtherKeys(new LinkedHashMap<int, int>(hashCode: (v) => v.hashCode,
isValidKey: (v) => v is int));
testOtherKeys(new LinkedHashMap(equals: (int x, int y) => x == y,
@@ -584,6 +593,26 @@
Expect.isTrue(eqMap.containsKey(eq02));
Expect.isTrue(eqMap.containsKey(eq11));
Expect.isTrue(eqMap.containsKey(eq12));
+
+ // Changing objects will not affect identity map.
+ map.clear();
+ var m1 = new Mutable(1);
+ var m2 = new Mutable(2);
+ var m3 = new Mutable(3);
+ map[m1] = 1;
+ map[m2] = 2;
+ map[m3] = 3;
+ Expect.equals(3, map.length);
+ Expect.isTrue(map.containsKey(m1));
+ Expect.isTrue(map.containsKey(m2));
+ Expect.isTrue(map.containsKey(m3));
+ Expect.notEquals(m1, m3);
+ m3.id = 1;
+ Expect.equals(m1, m3);
+ // Even if keys are equal, they are still not identical.
+ // Even if hashcode of m3 changed, it can still be found.
+ Expect.equals(1, map[m1]);
+ Expect.equals(3, map[m3]);
}
/** Class of objects that are equal if they hold the same id. */
@@ -713,3 +742,10 @@
Expect.isNull(map["not an int"]);
Expect.isNull(map[1.5]);
}
+
+class Mutable {
+ int id;
+ Mutable(this.id);
+ int get hashCode => id;
+ bool operator==(other) => other is Mutable && other.id == id;
+}
diff --git a/tests/corelib/regress_11099_test.dart b/tests/corelib/regress_11099_test.dart
new file mode 100644
index 0000000..2e6b8c1
--- /dev/null
+++ b/tests/corelib/regress_11099_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+void main() {
+ var l = [new MyTest(1), new MyTest(5), new MyTest(3)];
+ l.sort();
+ if (l.toString() != "[d{1}, d{3}, d{5}]") throw 'Wrong result!';
+}
+
+class MyTest implements Comparable<MyTest> {
+ final int a;
+ MyTest(this.a);
+ int compareTo(MyTest b) => this.a - b.a;
+ String toString() => "d{$a}";
+}
diff --git a/tests/corelib/uri_base_test.dart b/tests/corelib/uri_base_test.dart
new file mode 100644
index 0000000..0954aab
--- /dev/null
+++ b/tests/corelib/uri_base_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2012, 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 "package:expect/expect.dart";
+
+main() {
+ try {
+ Uri base = Uri.base;
+ Expect.isTrue(Uri.base.scheme == "file" || Uri.base.scheme == "http");
+ } on UnsupportedError catch (e) {
+ Expect.isTrue(
+ e.toString().contains("'Uri.base' is not supported"));
+ }
+}
diff --git a/tests/html/custom/constructor_calls_created_synchronously_test.dart b/tests/html/custom/constructor_calls_created_synchronously_test.dart
index f383a7a..edd689a 100644
--- a/tests/html/custom/constructor_calls_created_synchronously_test.dart
+++ b/tests/html/custom/constructor_calls_created_synchronously_test.dart
@@ -6,6 +6,7 @@
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
import 'dart:html';
+import '../utils.dart';
class A extends HtmlElement {
static final tag = 'x-a';
@@ -18,18 +19,6 @@
}
}
-loadPolyfills() {
- if (!document.supportsRegister) {
- // Cache blocker is a workaround for:
- // https://code.google.com/p/dart/issues/detail?id=11834
- var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
- return HttpRequest.getString('/root_dart/pkg/custom_element/lib/'
- 'custom-elements.debug.js?cacheBlock=$cacheBlocker').then((code) {
- document.head.children.add(new ScriptElement()..text = code);
- });
- }
-}
-
main() {
useHtmlConfiguration();
diff --git a/tests/html/custom/created_callback_test.dart b/tests/html/custom/created_callback_test.dart
index 00848c4..ebd3fba 100644
--- a/tests/html/custom/created_callback_test.dart
+++ b/tests/html/custom/created_callback_test.dart
@@ -54,18 +54,6 @@
}
}
-loadPolyfills() {
- if (!document.supportsRegister) {
- // Cache blocker is a workaround for:
- // https://code.google.com/p/dart/issues/detail?id=11834
- var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
- return HttpRequest.getString('/root_dart/pkg/custom_element/lib/'
- 'custom-elements.debug.js?cacheBlock=$cacheBlocker').then((code) {
- document.head.children.add(new ScriptElement()..text = code);
- });
- }
-}
-
main() {
useHtmlConfiguration();
diff --git a/tests/html/custom/document_register_basic_test.dart b/tests/html/custom/document_register_basic_test.dart
index 6934a47..c8964e5 100644
--- a/tests/html/custom/document_register_basic_test.dart
+++ b/tests/html/custom/document_register_basic_test.dart
@@ -37,18 +37,6 @@
factory BadE() => new Element.tag(tag);
}
-loadPolyfills() {
- if (!document.supportsRegister) {
- // Cache blocker is a workaround for:
- // https://code.google.com/p/dart/issues/detail?id=11834
- var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
- return HttpRequest.getString('/root_dart/pkg/custom_element/lib/'
- 'custom-elements.debug.js?cacheBlock=$cacheBlocker').then((code) {
- document.head.children.add(new ScriptElement()..text = code);
- });
- }
-}
-
main() {
useHtmlConfiguration();
diff --git a/tests/html/custom/document_register_type_extensions_test.dart b/tests/html/custom/document_register_type_extensions_test.dart
index cae07a1..79b036d 100644
--- a/tests/html/custom/document_register_type_extensions_test.dart
+++ b/tests/html/custom/document_register_type_extensions_test.dart
@@ -40,18 +40,6 @@
factory FooBad() => new Element.tag('div', tag);
}
-loadPolyfills() {
- if (!document.supportsRegister) {
- // Cache blocker is a workaround for:
- // https://code.google.com/p/dart/issues/detail?id=11834
- var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
- return HttpRequest.getString('/root_dart/pkg/custom_element/lib/'
- 'custom-elements.debug.js?cacheBlock=$cacheBlocker').then((code) {
- document.head.children.add(new ScriptElement()..text = code);
- });
- }
-}
-
main() {
useHtmlIndividualConfiguration();
@@ -72,9 +60,9 @@
}
registeredTypes = true;
document.register(Foo.tag, Foo);
- document.register(Bar.tag, Bar);
+ document.register(Bar.tag, Bar, extendsTag: 'input');
document.register(Baz.tag, Baz);
- document.register(Qux.tag, Qux);
+ document.register(Qux.tag, Qux, extendsTag: 'input');
}
setUp(loadPolyfills);
diff --git a/tests/html/custom/entered_left_view_test.dart b/tests/html/custom/entered_left_view_test.dart
new file mode 100644
index 0000000..79f65c8
--- /dev/null
+++ b/tests/html/custom/entered_left_view_test.dart
@@ -0,0 +1,246 @@
+// 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 entered_left_view_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:js' as js;
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import '../utils.dart';
+
+var invocations = [];
+class Foo extends HtmlElement {
+ factory Foo() => null;
+
+ void created() {
+ invocations.add('created');
+ }
+
+ void enteredView() {
+ invocations.add('entered');
+ }
+
+ void leftView() {
+ invocations.add('left');
+ }
+
+ void attributeChanged() {
+ invocations.add('attribute changed');
+ }
+}
+
+// Pump custom events polyfill events.
+void customElementsTakeRecords() {
+ if (js.context.hasProperty('CustomElements')) {
+ js.context['CustomElements'].callMethod('takeRecords');
+ }
+}
+
+main() {
+ useHtmlIndividualConfiguration();
+
+ // Adapted from Blink's
+ // fast/dom/custom/entered-left-document.html test.
+
+ var docA = document;
+ var docB = document.implementation.createHtmlDocument('');
+
+ var nullSanitizer = new NullTreeSanitizer();
+
+ var registeredTypes = false;
+ setUp(() {
+ return loadPolyfills().then((_) {
+ if (registeredTypes) {
+ return;
+ }
+ registeredTypes = true;
+ document.register('x-a', Foo);
+ });
+ });
+
+ group('standard_events', () {
+ var a = new Element.tag('x-a');
+ setUp(() {
+ invocations = [];
+ });
+
+ test('Created', () {
+ a = new Element.tag('x-a');
+ expect(invocations, ['created']);
+ });
+
+ test('entered', () {
+ document.body.append(a);
+ customElementsTakeRecords();
+ expect(invocations, ['entered']);
+ });
+
+ test('left', () {
+ a.remove();
+ customElementsTakeRecords();
+ expect(invocations, ['left']);
+ });
+
+ var div = new DivElement();
+ test('nesting does not trigger entered', () {
+ div.append(a);
+ customElementsTakeRecords();
+ expect(invocations, []);
+ });
+
+ test('nested entering triggers entered', () {
+ document.body.append(div);
+ customElementsTakeRecords();
+ expect(invocations, ['entered']);
+ });
+
+ test('nested leaving triggers left', () {
+ div.remove();
+ customElementsTakeRecords();
+ expect(invocations, ['left']);
+ });
+ });
+
+ group('viewless_document', () {
+ var a = docB.createElement('x-a');
+ setUp(() {
+ invocations = [];
+ });
+
+ test('Created, owned by a document without a view', () {
+ a = docB.createElement('x-a');
+ expect(a.document, docB,
+ reason:'new instance should be owned by the document the definition '
+ 'was registered with');
+ expect(invocations, ['created'],
+ reason: 'calling the constructor should invoke the created callback');
+ });
+
+ test('Entered document without a view', () {
+ docB.body.append(a);
+ expect(invocations, [],
+ reason: 'entered callback should not be invoked when entering a '
+ 'document without a view');
+ });
+
+ /*
+ test('Attribute changed in document without a view', () {
+ a.setAttribute('data-foo', 'bar');
+ expect(invocations, ['attribute changed'],
+ reason: 'changing an attribute should invoke the callback, even in a '
+ 'document without a view');
+ });
+ */
+ test('Entered document with a view', () {
+ document.body.append(a);
+ customElementsTakeRecords();
+ expect(invocations, ['entered'],
+ reason: 'entered callback should be invoked when entering a document '
+ 'with a view');
+ });
+
+ test('Left document with a view', () {
+ a.remove();
+ customElementsTakeRecords();
+ expect(invocations, ['left'],
+ reason: 'left callback should be invoked when leaving a document '
+ 'with a view');
+ });
+
+ test('Created in a document without a view', () {
+ docB.body.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+ Platform.upgradeCustomElements(docB.body);
+
+ expect(invocations, ['created'],
+ reason: 'only created callback should be invoked when parsing a '
+ 'custom element in a document without a view');
+ });
+ });
+
+ group('shadow_dom', () {
+ var div;
+ var s;
+ setUp(() {
+ invocations = [];
+ div = new DivElement();
+ s = div.createShadowRoot();
+ });
+
+ tearDown(() {
+ customElementsTakeRecords();
+ });
+
+ test('Created in Shadow DOM that is not in a document', () {
+ s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+ Platform.upgradeCustomElements(s);
+
+ expect(invocations, ['created'],
+ reason: 'the entered callback should not be invoked when entering a '
+ 'Shadow DOM subtree not in the document');
+ });
+
+ test('Leaves Shadow DOM that is not in a document', () {
+ s.innerHtml = '';
+ expect(invocations, [],
+ reason: 'the left callback should not be invoked when leaving a '
+ 'Shadow DOM subtree not in the document');
+ });
+
+ test('Enters a document with a view as a constituent of Shadow DOM', () {
+ s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+ Platform.upgradeCustomElements(s);
+
+ document.body.append(div);
+ customElementsTakeRecords();
+ expect(invocations, ['created', 'entered'],
+ reason: 'the entered callback should be invoked when inserted into '
+ 'a document with a view as part of Shadow DOM');
+
+ div.remove();
+ customElementsTakeRecords();
+
+ expect(invocations, ['created', 'entered', 'left'],
+ reason: 'the left callback should be invoked when removed from a '
+ 'document with a view as part of Shadow DOM');
+ });
+ });
+
+
+ group('disconnected_subtree', () {
+ var div = new DivElement();
+
+ setUp(() {
+ invocations = [];
+ });
+
+ test('Enters a disconnected subtree of DOM', () {
+ div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+ Platform.upgradeCustomElements(div);
+
+ expect(invocations, ['created'],
+ reason: 'the entered callback should not be invoked when inserted '
+ 'into a disconnected subtree');
+ });
+
+ test('Leaves a disconnected subtree of DOM', () {
+ div.innerHtml = '';
+ expect(invocations, [],
+ reason: 'the left callback should not be invoked when removed from a '
+ 'disconnected subtree');
+ });
+
+ test('Enters a document with a view as a constituent of a subtree', () {
+ div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
+ Platform.upgradeCustomElements(div);
+ invocations = [];
+ document.body.append(div);
+ customElementsTakeRecords();
+ expect(invocations, ['entered'],
+ reason: 'the entered callback should be invoked when inserted into a '
+ 'document with a view as part of a subtree');
+ });
+ });
+}
diff --git a/tests/html/custom/entered_left_view_test.html b/tests/html/custom/entered_left_view_test.html
new file mode 100644
index 0000000..7c1059c
--- /dev/null
+++ b/tests/html/custom/entered_left_view_test.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="dart.unittest" content="full-stack-traces">
+ <title> entered_left_view_test </title>
+ <style>
+ .unittest-table { font-family:monospace; border:1px; }
+ .unittest-pass { background: #6b3;}
+ .unittest-fail { background: #d55;}
+ .unittest-error { background: #a11;}
+ </style>
+ <script src="/packages/shadow_dom/shadow_dom.debug.js"></script>
+</head>
+<body>
+ <h1> Running entered_left_view_test </h1>
+ <script type="text/javascript"
+ src="/packages/unittest/test_controller.js"></script>
+ <script type="text/javascript"
+ src="/packages/browser/interop.js"></script>
+ %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/html/event_test.dart b/tests/html/event_test.dart
index 29ceea5..6f135ba 100644
--- a/tests/html/event_test.dart
+++ b/tests/html/event_test.dart
@@ -222,11 +222,4 @@
expect(ev.shiftKey, isTrue);
expect(ev.metaKey, isTrue);
}, type: 'mousewheel');
-
- // HttpRequestProgressEvent has no properties to itself, so just test that
- // it doesn't error out on creation and can be dispatched.
- // Issue 1005.
- // eventTest('HttpRequestProgressEvent',
- // () => new HttpRequestProgressEvent('foo', 5),
- // (ev) {});
}
diff --git a/tests/html/events_test.dart b/tests/html/events_test.dart
index 8451c893d..d455b7f 100644
--- a/tests/html/events_test.dart
+++ b/tests/html/events_test.dart
@@ -1,7 +1,13 @@
-library EventsTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+// 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 tests.html.events_test;
+
+import 'dart:async';
import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
main() {
useHtmlConfiguration();
@@ -72,4 +78,33 @@
DivElement div = new Element.tag('div');
MouseEvent event = new MouseEvent('zebra', relatedTarget: div);
});
+
+ test('DOM event callbacks are associated with the correct zone', () {
+ var callbacks = [];
+
+ final element = new Element.tag('test');
+ element.id = 'eventtarget';
+ document.body.append(element);
+
+ // runZoned executes the function synchronously, but we don't want to
+ // rely on this. We therefore wrap it into an expectAsync0.
+ runZoned(expectAsync0(() {
+ Zone zone = Zone.current;
+ expect(zone, isNot(equals(Zone.ROOT)));
+
+ var sub;
+
+ void handler(Event e) {
+ expect(Zone.current, equals(zone));
+
+ runAsync(expectAsync0(() {
+ expect(Zone.current, equals(zone));
+ sub.cancel();
+ }));
+ }
+
+ sub = element.on['test'].listen(expectAsync1(handler));
+ }));
+ element.dispatchEvent(new Event('test'));
+ });
}
diff --git a/tests/html/html.status b/tests/html/html.status
index e27c033..4905e0b 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -12,6 +12,7 @@
[ $compiler == dart2js && $runtime != drt && $browser ]
custom/document_register_type_extensions_test/namespaces: Fail # Polyfill does not support createElementNS
custom/document_register_basic_test: Fail # Polyfill is not case-sensitive
+custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
[ $compiler == dart2js && $browser ]
# Issue 9325 failures
@@ -28,7 +29,9 @@
postmessage_structured_test/typed_arrays: Fail
xhr_test: Pass, Fail # Issue 12648
custom/attribute_changed_callback_test: Fail # 12643
+custom/entered_left_view_test: Fail # 13313
xhr_test/json: Fail # Issue 13069
+uri_test: Fail Issue 13581
[ $compiler == none && $runtime == drt && $system == windows ]
worker_test/functional: Pass, Crash # Issue 9929.
@@ -116,6 +119,7 @@
canvasrenderingcontext2d_test/drawImage_video_element: Fail # IE does not support drawImage w/ video element
canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # IE does not support drawImage w/ video element
worker_test/functional: Fail # IE uses incorrect security context for Blob URIs.
+custom/entered_left_view_test: Skip # Issue 13551 - IE is timing out
# IE10 Feature support statuses-
# All changes should be accompanied by platform support annotation changes.
@@ -157,7 +161,6 @@
webgl_1_test/supported: Fail
websql_test/supported: Fail
xhr_test/json: Fail # IE10 returns string, not JSON object
-xhr_test/supported_HttpRequestProgressEvent: Fail
xhr_test/supported_overrideMimeType: Fail
xsltprocessor_test/supported: Fail
@@ -264,7 +267,6 @@
websocket_test/supported: Fail
websql_test/supported: Fail
worker_test/supported: Fail
-xhr_test/supported_HttpRequestProgressEvent: Fail
xhr_test/supported_onLoadEnd: Fail
xhr_test/supported_onProgress: Fail
xhr_test/supported_overrideMimeType: Fail
@@ -383,7 +385,6 @@
speechrecognition_test/supported: Fail
touchevent_test/supported: Fail
websql_test/supported: Fail
-xhr_test/supported_HttpRequestProgressEvent: Fail
# 'html' tests import the HTML library, so they only make sense in
# a browser environment.
diff --git a/tests/html/uri_test.dart b/tests/html/uri_test.dart
new file mode 100644
index 0000000..af2ae82
--- /dev/null
+++ b/tests/html/uri_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2012, 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 '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:html';
+
+main() {
+ useHtmlConfiguration();
+
+ test('Uri.base', () {
+ expect(Uri.base.scheme, "http");
+ expect(Uri.base.toString(), window.location.href);
+ });
+}
diff --git a/tests/html/utils.dart b/tests/html/utils.dart
index 2533f24..04c8235 100644
--- a/tests/html/utils.dart
+++ b/tests/html/utils.dart
@@ -159,3 +159,17 @@
validateNodeTree(a.nodes[i], b.nodes[i], '$path[$i].');
}
}
+
+Future loadCustomElementPolyfill() {
+ if (!document.supportsRegister) {
+ var script = new ScriptElement()
+ ..src = '/packages/custom_element/custom-elements.debug.js';
+ document.head.append(script);
+ return document.body.on['WebComponentsReady'].first;
+ }
+ return new Future.value();
+}
+
+Future loadPolyfills() {
+ return loadCustomElementPolyfill();
+}
diff --git a/tests/html/window_test.dart b/tests/html/window_test.dart
index a663d1b..edf822d 100644
--- a/tests/html/window_test.dart
+++ b/tests/html/window_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2012, 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 WindowTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
diff --git a/tests/html/xhr_test.dart b/tests/html/xhr_test.dart
index 9894888..b39ab1c 100644
--- a/tests/html/xhr_test.dart
+++ b/tests/html/xhr_test.dart
@@ -37,12 +37,6 @@
expect(xhr.responseText, equals(''));
}
- group('supported_HttpRequestProgressEvent', () {
- test('supported', () {
- expect(HttpRequestProgressEvent.supported, isTrue);
- });
- });
-
group('supported_onProgress', () {
test('supported', () {
expect(HttpRequest.supportsProgressEvent, isTrue);
@@ -166,15 +160,6 @@
}
});
- test('HttpRequestProgressEvent', () {
- var expectation = HttpRequestProgressEvent.supported ?
- returnsNormally : throws;
- expect(() {
- var event = new Event.eventType('XMLHttpRequestProgressEvent', '');
- expect(event is HttpRequestProgressEvent, isTrue);
- }, expectation);
- });
-
test('overrideMimeType', () {
var expectation =
HttpRequest.supportsOverrideMimeType ? returnsNormally : throws;
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index b9257d5..700d27c 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -4,13 +4,10 @@
[ $runtime == vm ]
browser/*: SkipByDesign # Browser specific tests
-unresolved_ports_negative_test: Skip # Issue 6839
isolate_stress_test: Fail # Issue 12588: This should be able to pass when we have wrapper-less tests.
[ $compiler == none ]
serialization_test: SkipByDesign # Tests dart2js-specific serialization code
-spawn_uri_test: SkipByDesign # Test uses a ".js" URI.
-spawn_uri_negative_test: SkipByDesign # Test uses a ".js" URI.
isolate2_negative_test: Skip # Issue 12587.
isolate3_negative_test: Skip # Issue 12587.
@@ -18,13 +15,12 @@
isolate2_negative_test: Fail
isolate_negative_test: Fail
spawn_function_negative_test: Fail
-spawn_uri_negative_test: Fail
spawn_uri_vm_negative_test: Fail
unresolved_ports_negative_test: Fail
[ $compiler == dart2js && $jscl ]
browser/*: SkipByDesign # Browser specific tests
-illegal_msg_stream_test: Fail # Issue 6750
+illegal_msg_stream_test: RuntimeError # Issue 6750
[ $compiler == dart2js && $browser ]
illegal_msg_stream_test: Fail, Pass # Issue 6750
@@ -33,14 +29,14 @@
unresolved_ports_negative_test: Pass, Crash # Issue 10613
[ $compiler == dart2js ]
-serialization_test: Fail # Issue 1882, tries to access class TestingOnly declared in isolate_patch.dart
-illegal_msg_test: Fail # Issue 6750
-stream_mangling_test: Fail # Issue 9245
+serialization_test: RuntimeError # Issue 1882, tries to access class TestingOnly declared in isolate_patch.dart
+illegal_msg_test: RuntimeError # Issue 6750
+stream_mangling_test: RuntimeError # Issue 9245
-global_error_handler_test: Pass, Fail # Issue 9012, Issue 9024
-global_error_handler_stream_test: Pass, Fail # Issue 9012, Issue 9024
-global_error_handler2_test: Pass, Fail # Issue 9012, Issue 9024
-global_error_handler_stream2_test: Pass, Fail # Issue 9012, Issue 9024
+global_error_handler_test: Pass, RuntimeError # Issue 9012, Issue 9024
+global_error_handler_stream_test: Pass, RuntimeError # Issue 9012, Issue 9024
+global_error_handler2_test: Pass, RuntimeError # Issue 9012, Issue 9024
+global_error_handler_stream2_test: Pass, RuntimeError # Issue 9012, Issue 9024
[ $compiler == dart2js && ($runtime == drt || $runtime == ff || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == ie9 || $runtime == ie10 || $runtime == safari) ]
browser/typed_data_message_test: Fail # Issue 12624
@@ -69,7 +65,6 @@
[ $compiler == dart2js && $runtime == none ]
spawn_function_negative_test: Fail # Issue 12628
-spawn_uri_negative_test: Fail # Issue 12628
unresolved_ports_negative_test: Fail # Issue 12628
stream_mangling_test: Pass # Issue 12628
isolate_negative_test: Fail # Issue 12628
@@ -96,6 +91,11 @@
[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
isolate_stress_test: Skip # Issue 12537
+spawn_uri_multi_test/01: Fail # Issue 13615
[ $csp ]
-spawn_uri_negative_test: Fail # http://dartbug.com/13454
+spawn_uri_multi_test/none: Fail # http://dartbug.com/13454
+spawn_uri_test: Fail # http://dartbug.com/13454
+
+[ $jscl || $runtime == ie9 ]
+spawn_uri_multi_test/none: RuntimeError # http://dartbug.com/13544
diff --git a/tests/isolate/spawn_uri_negative_test.dart b/tests/isolate/spawn_uri_multi_test.dart
similarity index 65%
rename from tests/isolate/spawn_uri_negative_test.dart
rename to tests/isolate/spawn_uri_multi_test.dart
index 6e5be3b..fc95962 100644
--- a/tests/isolate/spawn_uri_negative_test.dart
+++ b/tests/isolate/spawn_uri_multi_test.dart
@@ -8,18 +8,24 @@
// OtherScripts=spawn_uri_child_isolate.dart
library spawn_tests;
import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+
+/* Dummy import so multi-test copies the file.
+import 'spawn_uri_child_isolate.dart';
+*/
main() {
test('isolate fromUri - negative test', () {
ReceivePort port = new ReceivePort();
port.receive(expectAsync2((msg, _) {
- expect(msg, equals('re: hello')); // should be hi, not hello
+ String expectedMessage = 're: hi';
+ // Should be hi, not hello.
+ expectedMessage = 're: hello'; /// 01: runtime error
+ expect(msg, equals(expectedMessage));
port.close();
}));
- // TODO(eub): make this work for non-JS targets.
- SendPort s = spawnUri('spawn_uri_child_isolate.js');
+ SendPort s = spawnUri('spawn_uri_child_isolate.dart');
s.send('hi', port.toSendPort());
});
}
diff --git a/tests/isolate/spawn_uri_test.dart b/tests/isolate/spawn_uri_test.dart
index 5a33903..a68f34f 100644
--- a/tests/isolate/spawn_uri_test.dart
+++ b/tests/isolate/spawn_uri_test.dart
@@ -18,8 +18,7 @@
port.close();
}));
- // TODO(eub): make this work for non-JS targets.
- SendPort s = spawnUri('spawn_uri_child_isolate.js');
+ SendPort s = spawnUri('spawn_uri_child_isolate.dart');
s.send('hi', port.toSendPort());
});
}
diff --git a/tests/language/bad_constructor_test.dart b/tests/language/bad_constructor_test.dart
index 3228017..02ac4e5 100644
--- a/tests/language/bad_constructor_test.dart
+++ b/tests/language/bad_constructor_test.dart
@@ -1,7 +1,6 @@
// Copyright (c) 2012, 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.
-// VMOptions=--constructor_name_check
class A {
// Constructor may not be static.
@@ -14,8 +13,9 @@
var m;
A.m() { m = 0; } /// 04: compile-time error
- set q(var value) { m = q; }
- A.q(); /// 05: compile-time error
+ set q(var value) { m = q; } // No name conflict with q=.
+ // The runtime error occurs because main calls new A() instead of new A.q().
+ A.q(); /// 05: runtime error
A.foo() : m = 0; /// 06: compile-time error
int foo(int a, int b) => a + b * m;
diff --git a/tests/language/bailout_container_type_test.dart b/tests/language/bailout_container_type_test.dart
new file mode 100644
index 0000000..f7b012f
--- /dev/null
+++ b/tests/language/bailout_container_type_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// Regression test for dart2js that used to generate bad code for the
+// non-bailout version of [main].
+
+var a = [false, [1, 2, 3]];
+var b;
+
+main() {
+ // Defeat type inferencing for [b].
+ b = new Object();
+ b = 42;
+ b = [];
+
+ // Make the function recursive to force a bailout version.
+ if (a[0]) main();
+
+ // We used to ask [b] to be of the same type as [a], but not
+ // checking that the length and element type are the same.
+ var arrayPhi = a[0] ? a : b;
+
+ if (arrayPhi.length != 0) {
+ throw 'Test failed';
+ }
+}
diff --git a/tests/language/class_literal_test.dart b/tests/language/class_literal_test.dart
index cb9b536..161073d 100644
--- a/tests/language/class_literal_test.dart
+++ b/tests/language/class_literal_test.dart
@@ -48,17 +48,13 @@
Expect.throws(() { Class / 3; }, (e) => e is NoSuchMethodError);
Expect.throws(() { Class += 3; }, (e) => e is NoSuchMethodError);
- // Verify that a class literal is its runtimeType.
- var obj = new Class();
- Expect.identical(Class, obj.runtimeType);
-
// Verify that a class literal isn't a string literal.
Expect.notEquals(Class, "Class");
// Verify toString() works for class literals.
- Expect.equals((Class).toString(), "Class");
+ Expect.isTrue((Class).toString() is String);
var y = Class;
- Expect.equals(y.toString(), "Class");
+ Expect.isTrue(y.toString() is String);
Expect.throws(() { Class.toString(); }, (e) => e is NoSuchMethodError);
}
diff --git a/tests/language/div_with_power_of_two2_test.dart b/tests/language/div_with_power_of_two2_test.dart
new file mode 100644
index 0000000..936aadf
--- /dev/null
+++ b/tests/language/div_with_power_of_two2_test.dart
@@ -0,0 +1,105 @@
+// 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 division by power of two.
+// Test that results before and after optimization are the same.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+// [function, [list of tuples argument/result]].
+var expectedResults =
+ [ [divBy1,
+ [[134217730, 134217730],
+ [-134217730, -134217730],
+ [10, 10],
+ [-10, -10]]],
+ [divByNeg1,
+ [[134217730, -134217730],
+ [-134217730, 134217730],
+ [10, -10],
+ [-10, 10]]],
+ [divBy2,
+ [[134217730, 67108865],
+ [-134217730, -67108865],
+ [10, 5],
+ [-10, -5]]],
+ [divByNeg2,
+ [[134217730, -67108865],
+ [-134217730, 67108865],
+ [10, -5],
+ [-10, 5]]],
+ [divBy4,
+ [[134217730, 33554432],
+ [-134217730, -33554432],
+ [10, 2],
+ [-10, -2]]],
+ [divByNeg4,
+ [[134217730, -33554432],
+ [-134217730, 33554432],
+ [10, -2],
+ [-10, 2]]],
+ [divBy134217728,
+ [[134217730, 1],
+ [-134217730, -1],
+ [10, 0],
+ [-10, 0]]],
+ [divByNeg134217728,
+ [[134217730, -1],
+ [-134217730, 1],
+ [10, 0],
+ [-10, 0]]],
+ // Use different functions for 64 bit arguments.
+ [divBy4_,
+ [[549755813990, 137438953497],
+ [-549755813990, -137438953497],
+ [288230925907525632, 72057731476881408],
+ [-288230925907525632, -72057731476881408]]],
+ [divByNeg4_,
+ [[549755813990, -137438953497],
+ [-549755813990, 137438953497],
+ [288230925907525632, -72057731476881408],
+ [-288230925907525632, 72057731476881408]]],
+ [divBy549755813888,
+ [[549755813990, 1],
+ [-549755813990, -1],
+ [288230925907525632, 524289],
+ [-288230925907525632, -524289]]],
+ [divByNeg549755813888,
+ [[549755813990, -1],
+ [-549755813990, 1],
+ [288230925907525632, -524289],
+ [-288230925907525632, 524289]]],
+ ];
+
+divBy0(a) => a ~/ 0;
+divBy1(a) => a ~/ 1;
+divByNeg1(a) => a ~/ -1;
+divBy2(a) => a ~/ 2;
+divByNeg2(a) => a ~/ -2;
+divBy4(a) => a ~/ 4;
+divByNeg4(a) => a ~/ -4;
+divBy134217728(a) => a ~/ 134217728;
+divByNeg134217728(a) => a ~/ -134217728;
+
+divBy4_(a) => a ~/ 4;
+divByNeg4_(a) => a ~/ -4;
+divBy549755813888(a) => a ~/ 549755813888;
+divByNeg549755813888(a) => a ~/ -549755813888;
+
+main() {
+ for (int i = 0; i < 20; i++) {
+ for (var e in expectedResults) {
+ Function f = e[0];
+ List values = e[1];
+ for (var v in values) {
+ int arg = v[0];
+ int res = v[1];
+ Expect.equals(res, f(arg));
+ }
+ }
+ Expect.throws(() => divBy0(4),
+ (e) => e is IntegerDivisionByZeroException
+ || e is RuntimeError);
+ }
+}
diff --git a/tests/language/div_with_power_of_two_test.dart b/tests/language/div_with_power_of_two_test.dart
index 2ee10d7..a628563 100644
--- a/tests/language/div_with_power_of_two_test.dart
+++ b/tests/language/div_with_power_of_two_test.dart
@@ -98,9 +98,5 @@
Expect.equals(res, f(arg));
}
}
- try {
- divBy0(4);
- Expect.fail("Should have thrown exception.");
- } on IntegerDivisionByZeroException catch (e) {}
}
}
diff --git a/tests/language/getter_no_setter_test.dart b/tests/language/getter_no_setter_test.dart
index d48864f..62233fd 100644
--- a/tests/language/getter_no_setter_test.dart
+++ b/tests/language/getter_no_setter_test.dart
@@ -29,7 +29,7 @@
}
}
static test() {
- nextVar = 0; /// 01: compile-time error
+ nextVar = 0; /// 01: runtime error
this.nextVar = 0; /// 02: compile-time error
}
}
diff --git a/tests/language/illegal_invocation_test.dart b/tests/language/illegal_invocation_test.dart
index e0329ce..3908a99 100644
--- a/tests/language/illegal_invocation_test.dart
+++ b/tests/language/illegal_invocation_test.dart
@@ -6,7 +6,7 @@
// Test for issue 1393. Invoking a library prefix name caused an internal error
// in dartc.
-import "illegal_invocation_lib.dart" as foo; /// 01: compile-time error
+import "illegal_invocation_lib.dart" as foo; /// 01: runtime error
main() {
// probably what the user meant was foo.foo(), but the qualifier refers
diff --git a/tests/language/instantiate_type_variable_test.dart b/tests/language/instantiate_type_variable_test.dart
index a798984..d2eb88e 100644
--- a/tests/language/instantiate_type_variable_test.dart
+++ b/tests/language/instantiate_type_variable_test.dart
@@ -7,7 +7,7 @@
class Foo<T> {
Foo() {}
T make() {
- return new T(); /// 01: compile-time error
+ return new T(); /// 01: runtime error
}
}
diff --git a/tests/language/integer_division_by_zero_test.dart b/tests/language/integer_division_by_zero_test.dart
new file mode 100644
index 0000000..98aab8c
--- /dev/null
+++ b/tests/language/integer_division_by_zero_test.dart
@@ -0,0 +1,15 @@
+// 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 integer division by zero.
+// Test that results before and after optimization are the same.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+divBy0(a) => a ~/ 0;
+
+main() {
+ Expect.throws(() => divBy0(4),
+ (e) => e is IntegerDivisionByZeroException);
+}
diff --git a/tests/language/issue13556_test.dart b/tests/language/issue13556_test.dart
new file mode 100644
index 0000000..dc202aa
--- /dev/null
+++ b/tests/language/issue13556_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+// Regression test for dart2js that used to crash when resolving the
+// @B() annotation.
+
+class A {
+ final a;
+ const A({this.a});
+}
+
+class B extends A {
+ const B();
+}
+
+@B()
+main() {
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 67a94c1..e567204 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -10,8 +10,6 @@
mixin_super_constructor_positionals_test: Fail # Issue 12631
built_in_identifier_prefix_test: Fail # Issue 6970
library_juxtaposition_test: Fail # Issue 6877
-switch_int_double_test/01: Fail # Issue 7307
-switch_int_double_test/02: Fail # Issue 7307
throwing_lazy_variable_test: Fail # Issue 5802
# These bugs refer currently ongoing language discussions.
@@ -25,17 +23,7 @@
lazy_static3_test: Fail # Issue 12593
duplicate_export_negative_test: Fail # Issue 6134
on_catch_malformed_type_test: Fail # Issue 8601
-mixin_mixin_test: Fail # Issue 9683
-mixin_mixin2_test: Fail # Issue 9683
-mixin_mixin3_test: Fail # Issue 9683
-mixin_mixin4_test: Fail # Issue 9683
-mixin_mixin5_test: Fail # Issue 9683
-mixin_issue10216_2_test: Fail # Issue 9683
-mixin_illegal_object_test/01: Crash # Issue 10952
-mixin_illegal_object_test/02: Crash # Issue 10952
-mixin_forwarding_constructor2_test: Fail # Issue 11888
-mixin_typedef_constructor_test: Fail # Issue 11888
-mixin_type_parameter2_test: Fail # Issue 11888
+mixin_forwarding_constructor2_test: Fail # Issue 13641
[ $compiler == none && $unchecked ]
# Only checked mode reports an error on type assignment
@@ -65,3 +53,6 @@
[ $compiler == none && $runtime == drt && $system == macos ]
field_type_check_test/none: Pass, Fail # Issue 13266
+
+[ $compiler == dart2js && $runtime == ie9 ]
+lazy_static3_test: Fail # Issue 13469
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 4dc9997..d229d47 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -4,6 +4,17 @@
[ $compiler == dartanalyzer ]
+# Missing compile-time errors for parameters marked static.
+static_parameter_test/02: Fail
+static_parameter_test/03: Fail
+static_parameter_test/04: Fail
+static_parameter_test/06: Fail
+static_parameter_test/07: Fail
+static_parameter_test/08: Fail
+static_parameter_test/10: Fail
+static_parameter_test/11: Fail
+static_parameter_test/12: Fail
+
# Runtime negative test. No static errors or warnings.
closure_call_wrong_argument_count_negative_test: skip
@@ -58,10 +69,6 @@
lazy_static3_test: fail
field3a_negative_test: Fail # Issue 11124
-const_syntax_test/01: Fail # Issue 11124
-const_syntax_test/04: Fail # Issue 11124
-const_syntax_test/02: Fail # Issue 11124
-const_syntax_test/03: Fail # Issue 11124
final_syntax_test/01: Fail # Issue 11124
final_syntax_test/04: Fail # Issue 11124
final_syntax_test/02: Fail # Issue 11124
@@ -116,9 +123,6 @@
# test issue 11590, runtime only negative test
field_method4_negative_test: fail
-# test issue 11591, assigning to the final variable is warning, not error
-getter_no_setter_test/01: fail
-
# test issue 11592, Function type alias (typedef) is not a constant
first_class_types_constants_test: fail
@@ -126,8 +130,6 @@
import_combinators_negative_test: fail
interface_static_non_final_fields_negative_test: fail
-instantiate_type_variable_test/01: fail # Issue 11595
-
# test issue 11698, no setter, so warning, not error
assign_instance_method_negative_test: fail
@@ -155,7 +157,6 @@
# test issue 12156, fails only at runtime
static_call_wrong_argument_count_negative_test: fail
-static_final_field2_test/02: Fail # Issue 13018
constructor9_test/01: Fail # Issue 12157
throw7_test/01: Fail # Issue 12159
@@ -179,7 +180,6 @@
# test issue 12191, ambiguous import is always warning now
prefix3_negative_test: fail # Issue 12191
-library_ambiguous_test/00: fail # Issue 12191
# test issue 12289, assignment in assert statement
type_error_test: fail # Issue 12289
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index b489212..f43b9e8 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -4,6 +4,17 @@
[ $compiler == dart2analyzer ]
+# Missing compile-time errors for parameters marked static.
+static_parameter_test/02: Fail
+static_parameter_test/03: Fail
+static_parameter_test/04: Fail
+static_parameter_test/06: Fail
+static_parameter_test/07: Fail
+static_parameter_test/08: Fail
+static_parameter_test/10: Fail
+static_parameter_test/11: Fail
+static_parameter_test/12: Fail
+
# Runtime negative test. No static errors or warnings.
closure_call_wrong_argument_count_negative_test: skip
@@ -58,10 +69,6 @@
lazy_static3_test: fail
field3a_negative_test: Fail # Issue 11124
-const_syntax_test/01: Fail # Issue 11124
-const_syntax_test/04: Fail # Issue 11124
-const_syntax_test/02: Fail # Issue 11124
-const_syntax_test/03: Fail # Issue 11124
final_syntax_test/01: Fail # Issue 11124
final_syntax_test/04: Fail # Issue 11124
final_syntax_test/02: Fail # Issue 11124
@@ -128,10 +135,6 @@
instantiate_type_variable_test/01: fail # Issue 11595
-mixin_type_parameters_errors_test/01: fail # Issue 11598
-mixin_type_parameters_errors_test/02: fail # Issue 11598
-mixin_type_parameters_errors_test/05: fail # Issue 11598
-
# test issue 11698, no setter, so warning, not error
assign_instance_method_negative_test: fail
@@ -159,8 +162,6 @@
# test issue 12156, fails only at runtime
static_call_wrong_argument_count_negative_test: fail
-# test issue 12157, uninitializer instance variable is warning, so not negative test
-static_final_field2_test/02: Fail # Issue 13018
constructor9_test/01: Fail # Issue 12157
throw7_test/01: Fail # Issue 12159
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index c71efb6..499ad55 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,16 +3,22 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2js || $compiler == dart2dart ]
-block_scope_test: Fail # Issue 13204.
-null_test/03: Fail # Issue 12445.
-black_listed_test/none: Fail # Issue 12446.
-malformed_test/none: Fail # Issue 12695
-malformed_test/05: Fail # Issue 12695
-malformed_test/06: Fail # Issue 12695
-full_stacktrace1_test: Pass, Fail # Issue 12698
-full_stacktrace2_test: Pass, Fail # Issue 12698
-full_stacktrace3_test: Pass, Fail # Issue 12698
-stacktrace_test: Pass, Fail # # Issue 12698
+bad_constructor_test/05: CompileTimeError # Issue 13669
+block_scope_test: CompileTimeError # Issue 13204.
+null_test/03: MissingCompileTimeError # Issue 12445.
+black_listed_test/none: CompileTimeError # Issue 12446.
+malformed_test/05: MissingCompileTimeError # Issue 12695
+malformed_test/06: MissingCompileTimeError # Issue 12695
+full_stacktrace1_test: Pass, RuntimeError # Issue 12698
+full_stacktrace2_test: Pass, RuntimeError # Issue 12698
+full_stacktrace3_test: Pass, RuntimeError # Issue 12698
+stacktrace_test: Pass, RuntimeError # # Issue 12698
+illegal_invocation_test/01: CompileTimeError # Issue 13630
+instantiate_type_variable_test/01: CompileTimeError # Issue 13631
+library_ambiguous_test/00: CompileTimeError # Issue 13632
+library_ambiguous_test/01: CompileTimeError # Issue 13632
+library_ambiguous_test/02: CompileTimeError # Issue 13632
+library_ambiguous_test/03: CompileTimeError # Issue 13632
# VM specific tests that should not be run by dart2js.
vm/*: Skip # Issue 12699
@@ -37,30 +43,30 @@
redirecting_factory_malbounded_test/01: Fail # Issue 12825
[ $compiler == dart2js && $unchecked ]
-type_checks_in_factory_method_test: Fail # Issue 12746
-assertion_test: Fail # Issue 12748
-double_to_string_as_exponential2_test: Fail # Issue 12749
-double_to_string_as_fixed2_test: Fail # Issue 12749
-double_to_string_as_precision2_test: Fail # Issue 12749
-compile_time_constant_checked_test/02: Fail, OK
-compile_time_constant_checked2_test/01: Fail, OK
-compile_time_constant_checked2_test/02: Fail, OK
-compile_time_constant_checked2_test/03: Fail, OK
-compile_time_constant_checked2_test/04: Fail, OK
-compile_time_constant_checked2_test/05: Fail, OK
-compile_time_constant_checked2_test/06: Fail, OK
-compile_time_constant_checked3_test/01: Fail, OK
-compile_time_constant_checked3_test/02: Fail, OK
-compile_time_constant_checked3_test/03: Fail, OK
-compile_time_constant_checked3_test/04: Fail, OK
-compile_time_constant_checked3_test/05: Fail, OK
-compile_time_constant_checked3_test/06: Fail, OK
-generic_test: Fail, OK
-named_parameters_type_test/01: Fail, OK
-named_parameters_type_test/02: Fail, OK
-named_parameters_type_test/03: Fail, OK
-positional_parameters_type_test/01: Fail, OK
-positional_parameters_type_test/02: Fail, OK
+type_checks_in_factory_method_test: RuntimeError # Issue 12746
+assertion_test: RuntimeError # Issue 12748
+double_to_string_as_exponential2_test: RuntimeError # Issue 12749
+double_to_string_as_fixed2_test: RuntimeError # Issue 12749
+double_to_string_as_precision2_test: RuntimeError # Issue 12749
+compile_time_constant_checked_test/02: MissingCompileTimeError, OK
+compile_time_constant_checked2_test/01: MissingCompileTimeError, OK
+compile_time_constant_checked2_test/02: MissingCompileTimeError, OK
+compile_time_constant_checked2_test/03: MissingCompileTimeError, OK
+compile_time_constant_checked2_test/04: MissingCompileTimeError, OK
+compile_time_constant_checked2_test/05: MissingCompileTimeError, OK
+compile_time_constant_checked2_test/06: MissingCompileTimeError, OK
+compile_time_constant_checked3_test/01: MissingCompileTimeError, OK
+compile_time_constant_checked3_test/02: MissingCompileTimeError, OK
+compile_time_constant_checked3_test/03: MissingCompileTimeError, OK
+compile_time_constant_checked3_test/04: MissingCompileTimeError, OK
+compile_time_constant_checked3_test/05: MissingCompileTimeError, OK
+compile_time_constant_checked3_test/06: MissingCompileTimeError, OK
+generic_test: RuntimeError, OK
+named_parameters_type_test/01: MissingRuntimeError, OK
+named_parameters_type_test/02: MissingRuntimeError, OK
+named_parameters_type_test/03: MissingRuntimeError, OK
+positional_parameters_type_test/01: MissingRuntimeError, OK
+positional_parameters_type_test/02: MissingRuntimeError, OK
[ $compiler == dart2js && $minified ]
f_bounded_quantification4_test: Fail # Issue 12605.
@@ -70,95 +76,95 @@
mixin_mixin3_test: Fail # Issue 12605.
mixin_mixin4_test: Fail # Issue 12605.
mixin_mixin5_test: Fail # Issue 12605.
+mixin_mixin6_test: Fail # Issue 12605.
[ $compiler == dart2js ]
+malformed_test/none: RuntimeError # Issue 12695
function_type_alias9_test/00: Crash # Issue 9792
-branch_canonicalization_test: Fail # Issue 638.
-div_with_power_of_two_test: Fail # Issue 8301.
-class_literal_test: Fail # Issue 7626.
-identical_closure2_test: Fail # Issue 1533, Issue 12596
-invocation_mirror_test: Fail # Issue 12705
-built_in_identifier_prefix_test: Fail # Issue 6972
-number_identity2_test: Fail # Issue 12596
-new_expression_type_args_test/00: Fail # Issue 5519
-new_expression_type_args_test/01: Fail # Issue 5519
-double_int_to_string_test: Fail # Issue 1533
-mint_arithmetic_test: Fail # Issue 1533
-left_shift_test: Fail # Issue 1533
-factory_redirection_test/01: Fail # Issue 12752
-factory_redirection_test/07: Fail # Issue 12752
-bad_override_test/01: Fail # Issue 11496
-bad_override_test/02: Fail # Issue 11496
-bad_override_test/06: Fail # Issue 11496
-class_override_test/00: Fail # Issue 11496
-field_override3_test/00: Fail # Issue 11496
-field_override3_test/01: Fail # Issue 11496
-field_override3_test/02: Fail # Issue 11496
-field_override3_test/03: Fail # Issue 11496
-getter_override_test/00: Fail # Issue 11496
-getter_override_test/01: Fail # Issue 11496
-getter_override_test/02: Fail # Issue 11496
-method_override7_test/00: Fail # Issue 11496
-method_override7_test/01: Fail # Issue 11496
-method_override7_test/02: Fail # Issue 11496
-method_override8_test/03: Fail # Issue 11496
-setter_override_test/00: Fail # Issue 11496
-setter_override_test/03: Fail # Issue 11496
-setter_override2_test/02: Fail # Issue 11496
-constructor_named_arguments_test/01: Fail # Issue 5519
-getter_no_setter_test/01: Fail # Issue 5519
-not_enough_positional_arguments_test/01: Fail # Issue 12838
-not_enough_positional_arguments_test/02: Fail # Issue 12838
-not_enough_positional_arguments_test/05: Fail # Issue 12838
-metadata_test: Fail # Issue 5841
-infinity_test: Fail # Issue 4984
-positive_bit_operations_test: Fail # Issue 12795
-mixin_mixin2_test: Fail # Issue 13109.
-mixin_mixin3_test: Fail # Issue 13109.
+branch_canonicalization_test: RuntimeError # Issue 638.
+identical_closure2_test: RuntimeError # Issue 1533, Issue 12596
+integer_division_by_zero_test: RuntimeError # Issue 8301
+built_in_identifier_prefix_test: CompileTimeError # Issue 6972
+number_identity2_test: RuntimeError # Issue 12596
+new_expression_type_args_test/00: CompileTimeError # Issue 5519
+new_expression_type_args_test/01: CompileTimeError # Issue 5519
+double_int_to_string_test: RuntimeError # Issue 1533
+mint_arithmetic_test: RuntimeError # Issue 1533
+left_shift_test: RuntimeError # Issue 1533
+factory_redirection_test/01: CompileTimeError # Issue 12752
+factory_redirection_test/07: MissingCompileTimeError # Issue 12752
+bad_override_test/01: CompileTimeError # Issue 11496
+bad_override_test/02: CompileTimeError # Issue 11496
+bad_override_test/06: CompileTimeError # Issue 11496
+class_override_test/00: CompileTimeError # Issue 11496
+field_override3_test/00: MissingCompileTimeError # Issue 11496
+field_override3_test/01: MissingCompileTimeError # Issue 11496
+field_override3_test/02: MissingCompileTimeError # Issue 11496
+field_override3_test/03: MissingCompileTimeError # Issue 11496
+getter_override_test/00: MissingCompileTimeError # Issue 11496
+getter_override_test/01: MissingCompileTimeError # Issue 11496
+getter_override_test/02: MissingCompileTimeError # Issue 11496
+method_override7_test/00: MissingCompileTimeError # Issue 11496
+method_override7_test/01: MissingCompileTimeError # Issue 11496
+method_override7_test/02: MissingCompileTimeError # Issue 11496
+method_override8_test/03: CompileTimeError # Issue 11496
+setter_override_test/00: MissingCompileTimeError # Issue 11496
+setter_override_test/03: MissingCompileTimeError # Issue 11496
+setter_override2_test/02: CompileTimeError # Issue 11496
+constructor_named_arguments_test/01: CompileTimeError # Issue 5519
+not_enough_positional_arguments_test/01: CompileTimeError # Issue 12838
+not_enough_positional_arguments_test/02: CompileTimeError # Issue 12838
+not_enough_positional_arguments_test/05: CompileTimeError # Issue 12838
+metadata_test: CompileTimeError # Issue 5841
+infinity_test: RuntimeError # Issue 4984
+positive_bit_operations_test: RuntimeError # Issue 12795
+mixin_mixin2_test: RuntimeError # Issue 13109.
+mixin_mixin3_test: RuntimeError # Issue 13109.
+mixin_mixin7_test: RuntimeError # Issue 13109.
# Compilation errors.
-const_var_test: Fail # Issue 12793
-map_literal3_test: Fail # Issue 12793
-function_type_alias5_test/00: Fail # Issue 12754
-function_type_alias5_test/01: Fail # Issue 12754
-function_type_alias5_test/02: Fail # Issue 12754
-method_override5_test: Fail # Issue 12809
+const_var_test: CompileTimeError # Issue 12793
+map_literal3_test: CompileTimeError # Issue 12793
+function_type_alias5_test/00: MissingCompileTimeError # Issue 12754
+function_type_alias5_test/01: MissingCompileTimeError # Issue 12754
+function_type_alias5_test/02: MissingCompileTimeError # Issue 12754
+method_override5_test: RuntimeError # Issue 12809
parameter_initializer6_negative_test: Fail # Issue 3502
-named_parameters_aggregated_test/03: Fail # Issue 12812
-external_test/11: Fail # Issue 12887
-external_test/12: Fail # Issue 12887
-external_test/13: Fail # Issue 12887
-external_test/21: Fail # Issue 12887
-external_test/22: Fail # Issue 12887
-external_test/23: Fail # Issue 12887
-external_test/30: Fail # Issue 12887
-external_test/31: Fail # Issue 12887
-instanceof4_test/01: Fail # Issue 12889
-list_literal4_test: Fail # Issue 12890
-map_literal4_test: Fail # Issue 12891
-built_in_identifier_test/01: Fail # Issue 13022
+named_parameters_aggregated_test/03: MissingCompileTimeError # Issue 12812
+external_test/11: MissingCompileTimeError # Issue 12887
+external_test/12: MissingCompileTimeError # Issue 12887
+external_test/13: CompileTimeError # Issue 12887
+external_test/21: MissingCompileTimeError # Issue 12887
+external_test/22: MissingCompileTimeError # Issue 12887
+external_test/23: MissingCompileTimeError # Issue 12887
+external_test/30: MissingCompileTimeError # Issue 12887
+external_test/31: MissingCompileTimeError # Issue 12887
+instanceof4_test/01: RuntimeError # Issue 12889
+list_literal4_test: RuntimeError # Issue 12890
+map_literal4_test: RuntimeError # Issue 12891
+built_in_identifier_test/01: CompileTimeError # Issue 13022
-const_syntax_test/03: Fail # Issue 12932
-const_syntax_test/04: Fail # Issue 12932
-constructor9_test/01: Fail # Issue 12934
-list_literal1_test/01: Fail # Issue 12993
-map_literal1_test/01: Fail # Issue 12993
-scope_variable_test/01: Fail # Issue 13016
-static_final_field2_test/02: Fail # Issue 13017
-throw7_test/01: Fail # Issue 13019
+const_syntax_test/03: MissingCompileTimeError # Issue 12932
+const_syntax_test/04: MissingCompileTimeError # Issue 12932
+constructor9_test/01: MissingCompileTimeError # Issue 12934
+list_literal1_test/01: MissingCompileTimeError # Issue 12993
+map_literal1_test/01: MissingCompileTimeError # Issue 12993
+scope_variable_test/01: MissingCompileTimeError # Issue 13016
+static_final_field2_test/02: MissingCompileTimeError # Issue 13017
+throw7_test/01: MissingCompileTimeError # Issue 13019
-numbers_test: Fail, OK # Issue 1533
-canonical_const2_test: Fail, OK # Issue 1533
-bit_operations_test: Fail, OK # Issue 1533
-expect_test: Fail, OK # Issue 13080
+numbers_test: RuntimeError, OK # Issue 1533
+canonical_const2_test: RuntimeError, OK # Issue 1533
+bit_operations_test: RuntimeError, OK # Issue 1533
+expect_test: RuntimeError, OK # Issue 13080
-final_syntax_test/01: Fail # Issue 13020
-final_syntax_test/02: Fail # Issue 13020
-final_syntax_test/03: Fail # Issue 13020
-final_syntax_test/04: Fail # Issue 13020
+final_syntax_test/01: MissingCompileTimeError # Issue 13020
+final_syntax_test/02: MissingCompileTimeError # Issue 13020
+final_syntax_test/03: MissingCompileTimeError # Issue 13020
+final_syntax_test/04: MissingCompileTimeError # Issue 13020
-assign_top_method_test: Fail # Issue 13075
-null_test/none: Fail # Issue 12482
+assign_top_method_test: RuntimeError # Issue 13075
+null_test/none: RuntimeError # Issue 12482
[ $compiler == dart2js && $runtime == none ]
@@ -194,9 +200,10 @@
[ $compiler == dart2dart ]
+function_type_alias9_test/00: Crash # Issue 11986
+malformed_test/none: CompileTimeError # Issue 12695
mixin_super_constructor_named_test: Fail # Issue 12631
mixin_super_constructor_positionals_test: Fail # Issue 12631
-function_type_alias9_test/00: Crash # Issue 11986
built_in_identifier_prefix_test: Fail # Issue 6972
constructor_initializer_test/none: Fail # Issue 12633
@@ -206,15 +213,7 @@
on_catch_malformed_type_test: Fail # Issue 8601
# Mixins fail on the VM.
-mixin_mixin_test: Fail # Issue 9683
-mixin_mixin2_test: Fail # Issue 9683
-mixin_mixin3_test: Fail # Issue 9683
-mixin_mixin4_test: Fail # Issue 9683
-mixin_mixin5_test: Fail # Issue 9683
-mixin_issue10216_2_test: Fail # Issue 9683
-mixin_forwarding_constructor2_test: Fail # Issue 11888
-mixin_typedef_constructor_test: Fail # Issue 11888
-mixin_type_parameter2_test: Fail # Issue 11888
+mixin_forwarding_constructor2_test: Fail # Issue 13641
mixin_with_two_implicit_constructors_test: Fail # Issue 11889
@@ -259,7 +258,6 @@
const_syntax_test/07: Fail # Issue 12933
const_syntax_test/08: Fail # Issue 12933
const_syntax_test/10: Fail # Issue 12933
-map_literal11_test: Fail # Issue 12933
compile_time_constant_c_test/02: Fail # Issue 12933
constructor9_test/01: Fail # Issue 12935
constructor_named_arguments_test/01: Fail # Issue 5519
@@ -267,7 +265,6 @@
final_syntax_test/02: Fail # Issue 13020
final_syntax_test/03: Fail # Issue 13020
final_syntax_test/04: Fail # Issue 13020
-getter_no_setter_test/01: Fail # Issue 5519
named_parameters_aggregated_test/03: Fail # Issue 12813
not_enough_positional_arguments_test/01: Fail # Issue 12839
not_enough_positional_arguments_test/02: Fail # Issue 12839
@@ -341,9 +338,6 @@
overridden_no_such_method_test: Pass, Fail # Issue 13078
no_such_method_test: Pass, Fail # Issue 13078
-# TODO(tball): Assign proper bug numbers.
-class_literal_test: Fail
-
import_core_prefix_test: Pass
prefix22_test: Pass
invocation_mirror_test: Fail, OK # Issue 12706 (hardcoded names).
diff --git a/tests/language/library_ambiguous_test.dart b/tests/language/library_ambiguous_test.dart
index cb02c8d..1584b24 100644
--- a/tests/language/library_ambiguous_test.dart
+++ b/tests/language/library_ambiguous_test.dart
@@ -13,10 +13,10 @@
{}
main() {
- print(foo); /// 00: compile-time error
- print(bar()); /// 01: compile-time error
- print(baz()); /// 02: compile-time error
- print(bay()); /// 03: compile-time error
+ print(foo); /// 00: runtime error
+ print(bar()); /// 01: runtime error
+ print(baz()); /// 02: runtime error
+ print(bay()); /// 03: runtime error
print(main is bax); /// 04: static type warning
var x = new X(); /// 05: continued
print("No error expected if ambiguous definitions are not used.");
diff --git a/tests/language/mixin_mixin6_test.dart b/tests/language/mixin_mixin6_test.dart
new file mode 100644
index 0000000..8041e52
--- /dev/null
+++ b/tests/language/mixin_mixin6_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<T> { }
+
+class J<T> { }
+
+class K<T> { }
+
+class S<T> { }
+
+class M<T> {
+ m() { return T; }
+}
+
+typedef A<U, V> = Object with M<Map<U, V>> implements I<V>;
+
+typedef B<T> = Object with A<T, Set<T>> implements J<T>;
+
+typedef C<T> = S<List<T>> with B implements K<T>; // B is raw.
+
+main() {
+ var c = new C<int>();
+ Expect.equals("Map<dynamic, Set>", c.m().toString());
+ Expect.isTrue(c is K<int>);
+ Expect.isTrue(c is J);
+ Expect.isTrue(c is I<Set>);
+ Expect.isTrue(c is S<List<int>>);
+ Expect.isTrue(c is A<dynamic, Set>);
+ Expect.isTrue(c is M<Map<dynamic, Set>>);
+}
diff --git a/tests/language/mixin_mixin7_test.dart b/tests/language/mixin_mixin7_test.dart
new file mode 100644
index 0000000..2e56355
--- /dev/null
+++ b/tests/language/mixin_mixin7_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<T> { }
+
+class J<T> { }
+
+class K<T> { }
+
+class S<T> { }
+
+class M<T> {
+ m() { return T; }
+}
+
+typedef A<U, V> = Object with M implements I<V>; // M is raw.
+
+typedef B<T> = Object with A implements J<T>; // A is raw.
+
+typedef C<T> = S<List<T>> with B implements K<T>; // B is raw.
+
+main() {
+ var c = new C<int>();
+ Expect.equals("dynamic", c.m().toString());
+ Expect.isTrue(c is K<int>);
+ Expect.isTrue(c is J);
+ Expect.isTrue(c is I);
+ Expect.isTrue(c is S<List<int>>);
+ Expect.isTrue(c is A);
+ Expect.isTrue(c is M);
+}
diff --git a/tests/language/regress_13462_0_test.dart b/tests/language/regress_13462_0_test.dart
new file mode 100644
index 0000000..b87bf1f
--- /dev/null
+++ b/tests/language/regress_13462_0_test.dart
@@ -0,0 +1,9 @@
+// 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.
+
+import 'dart:mirrors';
+
+main() {
+ print(MirrorSystem.getName(#foo));
+}
diff --git a/tests/language/regress_13462_1_test.dart b/tests/language/regress_13462_1_test.dart
new file mode 100644
index 0000000..bffdd03
--- /dev/null
+++ b/tests/language/regress_13462_1_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+import 'dart:mirrors';
+
+main() {
+ var name = MirrorSystem.getName(#foo);
+ if (name != 'foo') throw 'Wrong name: $name != foo';
+}
diff --git a/tests/language/static_parameter_test.dart b/tests/language/static_parameter_test.dart
new file mode 100644
index 0000000..7c5d068
--- /dev/null
+++ b/tests/language/static_parameter_test.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.
+
+foo(x
+ , static int y /// 01: compile-time error
+ , final static y /// 02: compile-time error
+ , {static y} /// 03: compile-time error
+ , [static y] /// 04: compile-time error
+ ) {
+}
+
+class C {
+ bar(x
+ , static int y /// 05: compile-time error
+ , final static y /// 06: compile-time error
+ , {static y} /// 07: compile-time error
+ , [static y] /// 08: compile-time error
+ ) {
+ }
+
+ static baz(x
+ , static int y /// 09: compile-time error
+ , final static y /// 10: compile-time error
+ , {static y} /// 11: compile-time error
+ , [static y] /// 12: compile-time error
+ ) {
+ }
+}
+
+main() {
+ foo(1
+ , 1 /// 01: continued
+ , 1 /// 02: continued
+ , y: 1 /// 03: continued
+ , 1 /// 04: continued
+ );
+ new C().bar(1
+ , 1 /// 05: continued
+ , 1 /// 06: continued
+ , y: 1 /// 07: continued
+ , 1 /// 08: continued
+ );
+ C.baz(1
+ , 1 /// 09: continued
+ , 1 /// 10: continued
+ , y: 1 /// 11: continued
+ , 1 /// 12: continued
+ );
+}
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
index 20a7804..227e5c6 100644
--- a/tests/lib/analyzer/analyze_library.status
+++ b/tests/lib/analyzer/analyze_library.status
@@ -3,6 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2analyzer ]
+lib/async/async: fail
lib/core/core: fail
lib/typed_data/typed_data: fail
lib/io/io: fail
diff --git a/tests/lib/async/catch_errors.dart b/tests/lib/async/catch_errors.dart
index c289690..ec11859 100644
--- a/tests/lib/async/catch_errors.dart
+++ b/tests/lib/async/catch_errors.dart
@@ -10,20 +10,10 @@
return true;
}
- void onDone() {
- controller.close();
- }
-
void onListen() {
- runZonedExperimental(body, onError: onError, onDone: onDone);
+ runZoned(body, onError: onError);
}
controller = new StreamController(onListen: onListen);
return controller.stream;
}
-
-Future waitForCompletion(void body()) {
- Completer completer = new Completer.sync();
- runZonedExperimental(body, onDone: completer.complete);
- return completer.future;
-}
diff --git a/tests/lib/async/catch_errors10_test.dart b/tests/lib/async/catch_errors10_test.dart
deleted file mode 100644
index f2cfdee..0000000
--- a/tests/lib/async/catch_errors10_test.dart
+++ /dev/null
@@ -1,29 +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.
-
-import 'package:async_helper/async_helper.dart';
-import "package:expect/expect.dart";
-import 'dart:async';
-import 'catch_errors.dart';
-
-main() {
- asyncStart();
- bool futureWasExecuted = false;
- // Test that `catchErrors` waits for a future that has been delayed by
- // `Timer.run`.
- catchErrors(() {
- Timer.run(() {
- new Future.value(499).then((x) {
- futureWasExecuted = true;
- });
- });
- return 'allDone';
- }).listen((x) {
- Expect.fail("Unexpected callback");
- },
- onDone: () {
- Expect.isTrue(futureWasExecuted);
- asyncEnd();
- });
-}
diff --git a/tests/lib/async/catch_errors11_test.dart b/tests/lib/async/catch_errors11_test.dart
index dff9b83..c2d34bc 100644
--- a/tests/lib/async/catch_errors11_test.dart
+++ b/tests/lib/async/catch_errors11_test.dart
@@ -9,16 +9,25 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test that `catchErrors` catches errors that are delayed by `Timer.run`.
catchErrors(() {
events.add("catch error entry");
new Future.error("future error");
- Timer.run(() { throw "timer error"; });
+ Timer.run(() {
+ done.complete(true);
+ throw "timer error";
+ });
}).listen((x) {
events.add(x);
},
- onDone: () {
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give the handler time to execute.
+ Timer.run(() {
Expect.listEquals([
"catch error entry",
"main exit",
@@ -28,5 +37,6 @@
events);
asyncEnd();
});
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors12_test.dart b/tests/lib/async/catch_errors12_test.dart
index af4acbc..8952860 100644
--- a/tests/lib/async/catch_errors12_test.dart
+++ b/tests/lib/async/catch_errors12_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Tests that errors that have been delayed by several milliseconds with
// Timers are still caught by `catchErrors`.
@@ -17,13 +19,19 @@
Timer.run(() { throw "timer error"; });
new Timer(const Duration(milliseconds: 100), () { throw "timer2 error"; });
new Future.value(499).then((x) {
- new Timer(const Duration(milliseconds: 200), () { throw x; });
+ new Timer(const Duration(milliseconds: 200), () {
+ done.complete(499);
+ throw x;
+ });
});
throw "catch error";
}).listen((x) {
events.add(x);
},
- onDone: () {
+ onDone: () { Expect.fail("Unexpected callback"); });
+ done.future.whenComplete(() {
+ // Give time to execute the callbacks.
+ Timer.run(() {
Expect.listEquals([
"catch error entry",
"main exit",
@@ -35,5 +43,6 @@
events);
asyncEnd();
});
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors13_test.dart b/tests/lib/async/catch_errors13_test.dart
index 1e3a8db..284dee9 100644
--- a/tests/lib/async/catch_errors13_test.dart
+++ b/tests/lib/async/catch_errors13_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Work around bug that makes runAsync use Timers. By invoking `runAsync` here
// we make sure that asynchronous non-timer events are executed before any
@@ -27,17 +29,24 @@
runAsync(() { throw "runAsync"; });
throw "delayed error";
});
- }).listen((x) { events.add(x); })
- .asFuture()
- .then((_) => events.add("inner done"))
- .then((_) { throw "inner done throw"; });
+ }).listen((x) {
+ events.add(x);
+ if (x == "runAsync") {
+ throw "inner done throw";
+ }
+ });
events.add("after inner");
Timer.run(() { throw "timer outer"; });
throw "inner throw";
}).listen((x) {
events.add(x);
+ if (x == "inner done throw") done.complete(true);
},
- onDone: () {
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give callbacks time to run.
+ Timer.run(() {
Expect.listEquals([
"catch error entry",
"catch error entry2",
@@ -48,11 +57,11 @@
"timer outer",
"delayed error",
"runAsync",
- "inner done",
"inner done throw"
],
events);
asyncEnd();
});
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors14_test.dart b/tests/lib/async/catch_errors14_test.dart
index bccc464..7f75e1a 100644
--- a/tests/lib/async/catch_errors14_test.dart
+++ b/tests/lib/async/catch_errors14_test.dart
@@ -9,18 +9,27 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test that periodic Timers are handled correctly by `catchErrors`.
catchErrors(() {
int counter = 0;
new Timer.periodic(const Duration(milliseconds: 50), (timer) {
- if (counter++ == 5) timer.cancel();
+ if (counter++ == 5) {
+ timer.cancel();
+ done.complete(true);
+ }
throw "error $counter";
});
}).listen((x) {
events.add(x);
},
- onDone: () {
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give time to complete the handlers.
+ Timer.run(() {
Expect.listEquals([
"main exit",
"error 1",
@@ -33,5 +42,6 @@
events);
asyncEnd();
});
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors15_test.dart b/tests/lib/async/catch_errors15_test.dart
index 7e1219d..2f9c13b 100644
--- a/tests/lib/async/catch_errors15_test.dart
+++ b/tests/lib/async/catch_errors15_test.dart
@@ -9,9 +9,9 @@
main() {
asyncStart();
+ Completer done = new Completer();
var events = [];
- // Test that the outer `catchErrors` waits for the nested `catchErrors` stream
- // to be done.
+
catchErrors(() {
events.add("catch error entry");
catchErrors(() {
@@ -23,14 +23,20 @@
throw "delayed error";
});
throw "catch error";
- }).listen((x) { events.add("i $x"); },
- onDone: () => events.add("inner done"));
+ }).listen((x) {
+ events.add("i $x");
+ if (x == "delayed error") done.complete(true);
+ },
+ onDone: () { Expect.fail("Unexpected callback"); });
events.add("after inner");
throw "inner throw";
}).listen((x) {
events.add("o $x");
},
- onDone: () {
+ onDone: () { Expect.fail("Unexpected callback"); });
+ done.future.whenComplete(() {
+ // Give some time to run the handlers.
+ Timer.run(() {
Expect.listEquals(["catch error entry",
"catch error entry2",
"after inner",
@@ -43,10 +49,10 @@
"i future error2",
"i 499",
"i delayed error",
- "inner done",
],
events);
asyncEnd();
});
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors17_test.dart b/tests/lib/async/catch_errors17_test.dart
index 8cb45c3..4a1591f 100644
--- a/tests/lib/async/catch_errors17_test.dart
+++ b/tests/lib/async/catch_errors17_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
StreamController controller;
// Test that errors do not cross zone boundaries.
@@ -23,21 +25,25 @@
.transform(new StreamTransformer(
handleError: (e, sink) => sink.add("error $e")))
.listen((x) { events.add("stream $x"); });
- }).listen((x) { events.add(x); })
- .asFuture().then((_) { events.add("inner done"); });
+ }).listen((x) { events.add(x); });
controller.add(1);
// Errors are not allowed to traverse boundaries. This error should be
// caught by the outer catchErrors.
controller.addError(2);
controller.close();
- }).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals(["map 1",
- "stream 101",
- "outer: 2",
- "inner done",
- ],
- events);
- asyncEnd();
- });
+ }).listen((x) {
+ events.add("outer: $x");
+ if (x == 2) done.complete(true);
+ }, onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ Timer.run(() {
+ Expect.listEquals(["map 1",
+ "stream 101",
+ "outer: 2",
+ ],
+ events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors18_test.dart b/tests/lib/async/catch_errors18_test.dart
index 5d04a57..a275176 100644
--- a/tests/lib/async/catch_errors18_test.dart
+++ b/tests/lib/async/catch_errors18_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
Stream stream = new Stream.periodic(const Duration(milliseconds: 20),
(x) => x);
@@ -19,13 +21,19 @@
if (x == 5) {
events.add("cancel");
subscription.cancel();
+ done.complete(true);
return;
}
events.add(x);
});
}).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals([0, 1, 2, 3, 4, "cancel"], events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
+ Expect.listEquals([0, 1, 2, 3, 4, "cancel"], events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors19_test.dart b/tests/lib/async/catch_errors19_test.dart
index 1bf5581..8741fe7 100644
--- a/tests/lib/async/catch_errors19_test.dart
+++ b/tests/lib/async/catch_errors19_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
Stream stream = new Stream.periodic(const Duration(milliseconds: 20),
(x) => x);
@@ -21,11 +23,17 @@
}, onDone: () {
new Future.delayed(const Duration(milliseconds: 30), () {
events.add(499);
+ done.complete(true);
});
});
}).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals([0, 1, 2, 3, 4, 499], events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
+ Expect.listEquals([0, 1, 2, 3, 4, 499], events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors20_test.dart b/tests/lib/async/catch_errors20_test.dart
index ffcf7c8..ee87c2c 100644
--- a/tests/lib/async/catch_errors20_test.dart
+++ b/tests/lib/async/catch_errors20_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test that nested stream (from `catchErrors`) that is delayed by a future
// is waited for.
@@ -17,18 +19,23 @@
new Future.error(499);
new Future.delayed(const Duration(milliseconds: 20), () {
events.add(42);
+ done.complete(true);
});
}).listen(events.add,
onDone: () { events.add("done"); });
throw "foo";
}).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals(["outer: foo",
- 499,
- 42,
- "done",
- ],
- events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
+ Expect.listEquals(["outer: foo",
+ 499,
+ 42,
+ ],
+ events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors21_test.dart b/tests/lib/async/catch_errors21_test.dart
index 932a80b..8b220f5 100644
--- a/tests/lib/async/catch_errors21_test.dart
+++ b/tests/lib/async/catch_errors21_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
var controller = new StreamController();
// Test that stream errors, as a result of bad user-code (`map`) are correctly
@@ -21,19 +23,27 @@
// Should not happen.
events.add("bad: $x");
});
- }).listen((x) { events.add("caught: $x"); },
- onDone: () { events.add("done"); });
+ }).listen((x) {
+ events.add("caught: $x");
+ if (x == 4) done.complete(true);
+ },
+ onDone: () { Expect.fail("Unexpected callback"); });
}).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals(["caught: 1",
- "caught: 2",
- "caught: 3",
- "caught: 4",
- "done",
- ],
- events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
+ Expect.listEquals(["caught: 1",
+ "caught: 2",
+ "caught: 3",
+ "caught: 4",
+ ],
+ events);
+ asyncEnd();
+ });
+ });
+
[1, 2, 3, 4].forEach(controller.add);
controller.close();
}
diff --git a/tests/lib/async/catch_errors22_test.dart b/tests/lib/async/catch_errors22_test.dart
index 2d92e8c..46debaf 100644
--- a/tests/lib/async/catch_errors22_test.dart
+++ b/tests/lib/async/catch_errors22_test.dart
@@ -9,6 +9,7 @@
main() {
asyncStart();
+
var events = [];
bool onDoneWasCalled = false;
var controller = new StreamController();
diff --git a/tests/lib/async/catch_errors23_test.dart b/tests/lib/async/catch_errors23_test.dart
index d2dddab3..cb78b3d 100644
--- a/tests/lib/async/catch_errors23_test.dart
+++ b/tests/lib/async/catch_errors23_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
StreamController controller;
Stream stream;
@@ -28,22 +30,29 @@
.asBroadcastStream();
stream.listen((x) { events.add("stream $x"); });
}).listen((x) { events.add(x); })
- .asFuture().then((_) { events.add("inner done"); });
+ .asFuture().then((_) { Expect.fail("Unexpected callback"); });
stream.listen((x) { events.add("stream2 $x"); });
controller.add(1);
// Errors are not allowed to traverse boundaries. This error should be
// caught by the outer catchErrors.
controller.addError(2);
controller.close();
- }).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals(["map 1",
- "stream 101",
- "stream2 101",
- "outer: 2",
- "inner done",
- ],
- events);
- asyncEnd();
- });
+ }).listen((x) {
+ events.add("outer: $x");
+ if (x == 2) done.complete(true);
+ },
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
+ Expect.listEquals(["map 1",
+ "stream 101",
+ "stream2 101",
+ "outer: 2",
+ ],
+ events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors24_test.dart b/tests/lib/async/catch_errors24_test.dart
index c9d6e4b..675d3a1 100644
--- a/tests/lib/async/catch_errors24_test.dart
+++ b/tests/lib/async/catch_errors24_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
StreamController controller;
Stream stream;
@@ -26,9 +28,14 @@
.transform(new StreamTransformer(
handleError: (e, sink) => sink.add("error $e")))
.asBroadcastStream();
- runAsync(() { stream.listen((x) { events.add("stream $x"); }); });
+ runAsync(() {
+ stream.listen((x) {
+ events.add("stream $x");
+ if (x == "error 2") done.complete(true);
+ });
+ });
}).listen((x) { events.add(x); })
- .asFuture().then((_) { events.add("inner done"); });
+ .asFuture().then((_) { Expect.fail("Unexpected callback"); });
stream.listen((x) { events.add("stream2 $x"); });
runAsync(() {
controller.add(1);
@@ -39,15 +46,19 @@
controller.close();
});
}).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals(["map 1",
- "stream2 101",
- "stream 101",
- "stream2 error 2",
- "stream error 2",
- "inner done",
- ],
- events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to complete.
+ Timer.run(() {
+ Expect.listEquals(["map 1",
+ "stream2 101",
+ "stream 101",
+ "stream2 error 2",
+ "stream error 2",
+ ],
+ events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors25_test.dart b/tests/lib/async/catch_errors25_test.dart
index 2360e9a..f3e9c0e 100644
--- a/tests/lib/async/catch_errors25_test.dart
+++ b/tests/lib/async/catch_errors25_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
StreamController controller;
// Test multiple subscribers of an asBroadcastStream inside the same
@@ -17,9 +19,15 @@
var stream = new Stream.fromIterable([1, 2]).asBroadcastStream();
stream.listen(events.add);
stream.listen(events.add);
+ done.complete(stream.listen(null).asFuture());
}).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals([1, 1, 2, 2], events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
+ Expect.listEquals([1, 1, 2, 2], events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors26_test.dart b/tests/lib/async/catch_errors26_test.dart
index 8ac5431..e2894f8 100644
--- a/tests/lib/async/catch_errors26_test.dart
+++ b/tests/lib/async/catch_errors26_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
StreamController controller;
Stream stream;
@@ -26,7 +28,7 @@
handleError: (e, sink) => sink.add("error $e")))
.listen((x) { events.add("stream $x"); });
}).listen((x) { events.add(x); })
- .asFuture().then((_) { events.add("inner done"); });
+ .asFuture().then((_) { Expect.fail("Unexpected callback"); });
controller.stream.listen((x) { events.add("stream2 $x"); },
onError: (x) { events.add("stream2 error $x"); });
controller.add(1);
@@ -35,16 +37,23 @@
// this should work.
controller.addError(2);
controller.close();
- }).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals(["map 1",
- "stream 101",
- "stream2 1",
- "stream2 error 2",
- "outer: 2",
- "inner done",
- ],
- events);
- asyncEnd();
- });
+ }).listen((x) {
+ events.add("outer: $x");
+ if (x == 2) done.complete(true);
+ },
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
+ Expect.listEquals(["map 1",
+ "stream 101",
+ "stream2 1",
+ "stream2 error 2",
+ "outer: 2",
+ ],
+ events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors27_test.dart b/tests/lib/async/catch_errors27_test.dart
index 23f8b99..ab89f16 100644
--- a/tests/lib/async/catch_errors27_test.dart
+++ b/tests/lib/async/catch_errors27_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
StreamController controller;
Stream stream;
@@ -37,19 +39,26 @@
controller.addError(2);
controller.close();
});
- }).listen((x) { events.add(x); })
- .asFuture().then((_) { events.add("inner done"); });
+ }).listen((x) {
+ events.add(x);
+ if (x == 2) done.complete(true);
+ })
+ .asFuture().then((_) { Expect.fail("Unexpected callback"); });
stream.listen((x) { events.add("stream2 $x"); });
}).listen((x) { events.add("outer: $x"); },
- onDone: () {
- Expect.listEquals(["map 1",
- "stream 101",
- "stream2 101",
- "stream error 2",
- 2, // Caught by the inner `catchErrors`.
- "inner done",
- ],
- events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
+ Expect.listEquals(["map 1",
+ "stream 101",
+ "stream2 101",
+ "stream error 2",
+ 2, // Caught by the inner `catchErrors`.
+ ],
+ events);
+ asyncEnd();
+ });
+ });
}
diff --git a/tests/lib/async/catch_errors28_test.dart b/tests/lib/async/catch_errors28_test.dart
index 1f13df4..de82d4b 100644
--- a/tests/lib/async/catch_errors28_test.dart
+++ b/tests/lib/async/catch_errors28_test.dart
@@ -9,19 +9,28 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test that periodic Timers are handled correctly by `catchErrors`.
catchErrors(() {
int counter = 0;
new Timer.periodic(const Duration(milliseconds: 50), (timer) {
- if (counter == 5) timer.cancel();
+ if (counter == 5) {
+ timer.cancel();
+ done.complete(true);
+ }
counter++;
events.add(counter);
});
}).listen((x) {
events.add(x);
},
- onDone: () {
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to run.
+ Timer.run(() {
Expect.listEquals([
"main exit",
1, 2, 3, 4, 5, 6,
@@ -29,5 +38,7 @@
events);
asyncEnd();
});
+ });
+
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors2_test.dart b/tests/lib/async/catch_errors2_test.dart
index 4c0d77c..bdc0c32 100644
--- a/tests/lib/async/catch_errors2_test.dart
+++ b/tests/lib/async/catch_errors2_test.dart
@@ -10,10 +10,11 @@
main() {
asyncStart();
bool futureWasExecuted = false;
- // Make sure that `catchErrors` only closes the error stream when the inner
- // futures are done.
+ Future done;
+
+ // Error streams never close.
catchErrors(() {
- new Future(() {
+ done = new Future(() {
futureWasExecuted = true;
});
return 'allDone';
@@ -21,7 +22,8 @@
Expect.fail("Unexpected callback");
},
onDone: () {
- Expect.isTrue(futureWasExecuted);
- asyncEnd();
+ Expect.fail("Unexpected callback");
});
+
+ done.whenComplete(asyncEnd);
}
diff --git a/tests/lib/async/catch_errors3_test.dart b/tests/lib/async/catch_errors3_test.dart
index ee55620..10b5f1b 100644
--- a/tests/lib/async/catch_errors3_test.dart
+++ b/tests/lib/async/catch_errors3_test.dart
@@ -9,11 +9,11 @@
main() {
asyncStart();
+ Completer done = new Completer();
bool futureWasExecuted = false;
bool future2WasExecuted = false;
- // Make sure `catchErrors` doesn't close its error stream before all
- // asynchronous operations are done.
+ // Make sure `catchErrors` never closes its stream.
catchErrors(() {
new Future(() => 499).then((x) {
futureWasExecuted = true;
@@ -21,6 +21,8 @@
runAsync(() {
new Future(() => 42).then((x) {
future2WasExecuted = true;
+ Expect.isTrue(futureWasExecuted);
+ done.complete(true);
});
});
return 'allDone';
@@ -28,8 +30,7 @@
Expect.fail("Unexpected callback");
},
onDone: () {
- Expect.isTrue(futureWasExecuted);
- Expect.isTrue(future2WasExecuted);
- asyncEnd();
+ Expect.fail("Unexpected callback");
});
+ done.future.whenComplete(asyncEnd);
}
diff --git a/tests/lib/async/catch_errors4_test.dart b/tests/lib/async/catch_errors4_test.dart
index 3814ddf..4508ba8 100644
--- a/tests/lib/async/catch_errors4_test.dart
+++ b/tests/lib/async/catch_errors4_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test that synchronous errors inside a `catchErrors` are caught.
catchErrors(() {
@@ -16,14 +18,17 @@
throw "catch error";
}).listen((x) {
events.add(x);
+ done.complete(true);
},
- onDone: () {
- Expect.listEquals(["catch error entry",
- "main exit",
- "catch error",
- ],
- events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ Expect.listEquals(["catch error entry",
+ "main exit",
+ "catch error",
+ ],
+ events);
+ asyncEnd();
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors5_test.dart b/tests/lib/async/catch_errors5_test.dart
index 1bb8bba..9550546 100644
--- a/tests/lib/async/catch_errors5_test.dart
+++ b/tests/lib/async/catch_errors5_test.dart
@@ -9,24 +9,32 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test that synchronous *and* asynchronous errors are caught by
// `catchErrors`.
catchErrors(() {
events.add("catch error entry");
- new Future.error("future error");
+ Future errorFuture = new Future.error("future error");
+ errorFuture.whenComplete(() => done.complete(true));
throw "catch error";
}).listen((x) {
events.add(x);
},
- onDone: () {
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give some time for the event listener to execute.
+ Timer.run(() {
Expect.listEquals(["catch error entry",
- "main exit",
- "catch error",
- "future error",
- ],
- events);
+ "main exit",
+ "catch error",
+ "future error",
+ ],
+ events);
asyncEnd();
});
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors7_test.dart b/tests/lib/async/catch_errors7_test.dart
index b241a2c..1193178 100644
--- a/tests/lib/async/catch_errors7_test.dart
+++ b/tests/lib/async/catch_errors7_test.dart
@@ -9,28 +9,44 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test that asynchronous errors are caught.
catchErrors(() {
events.add("catch error entry");
- new Future.error("future error");
- new Future.error("future error2");
- new Future.value(499).then((x) => throw x);
+ var futures = [
+ new Future.error("future error"),
+ new Future.error("future error2"),
+ new Future.value(499).then((x) => throw x),
+ ];
+ int completedCount = 0;
+ for (var future in futures) {
+ future.whenComplete(() {
+ completedCount++;
+ if (completedCount == 3) done.complete(true);
+ });
+ }
throw "catch error";
}).listen((x) {
events.add(x);
},
- onDone: () {
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ // Give handlers time to execute.
+ Timer.run(() {
Expect.listEquals(
["catch error entry",
- "main exit",
- "catch error",
- "future error",
- "future error2",
- 499,
+ "main exit",
+ "catch error",
+ "future error",
+ "future error2",
+ 499,
],
events);
asyncEnd();
});
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors8_test.dart b/tests/lib/async/catch_errors8_test.dart
index 7519fc6..3390046 100644
--- a/tests/lib/async/catch_errors8_test.dart
+++ b/tests/lib/async/catch_errors8_test.dart
@@ -9,6 +9,8 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test nested `catchErrors`.
// The nested `catchErrors` throws all kinds of different errors (synchronous
@@ -25,31 +27,37 @@
throw "delayed error";
});
throw "catch error";
- }).listen((x) { events.add(x); })
- .asFuture()
- .then((_) => events.add("inner done"))
- .then((_) { throw "inner done throw"; });
+ }).listen((x) {
+ events.add(x);
+ if (x == "delayed error") {
+ throw "inner done throw";
+ }
+ });
events.add("after inner");
throw "inner throw";
}).listen((x) {
events.add(x);
+ if (x == "inner done throw") {
+ done.complete(true);
+ }
},
- onDone: () {
- Expect.listEquals(["catch error entry",
- "catch error entry2",
- "after inner",
- "main exit",
- "catch error",
- "inner throw",
- "future error",
- "future error2",
- 499,
- "delayed error",
- "inner done",
- "inner done throw"
- ],
- events);
- asyncEnd();
- });
+ onDone: () { Expect.fail("Unexpected callback"); });
+
+ done.future.whenComplete(() {
+ Expect.listEquals(["catch error entry",
+ "catch error entry2",
+ "after inner",
+ "main exit",
+ "catch error",
+ "inner throw",
+ "future error",
+ "future error2",
+ 499,
+ "delayed error",
+ "inner done throw"
+ ],
+ events);
+ asyncEnd();
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/catch_errors9_test.dart b/tests/lib/async/catch_errors9_test.dart
deleted file mode 100644
index f16bcfb..0000000
--- a/tests/lib/async/catch_errors9_test.dart
+++ /dev/null
@@ -1,27 +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.
-
-import 'package:async_helper/async_helper.dart';
-import "package:expect/expect.dart";
-import 'dart:async';
-import 'catch_errors.dart';
-
-main() {
- asyncStart();
- bool futureWasExecuted = false;
- // Test that `catchErrors` waits for `Timer.run` before closing its error
- // stream.
- catchErrors(() {
- Timer.run(() {
- futureWasExecuted = true;
- });
- return 'allDone';
- }).listen((x) {
- Expect.fail("Unexpected callback");
- },
- onDone: () {
- Expect.isTrue(futureWasExecuted);
- asyncEnd();
- });
-}
diff --git a/tests/lib/async/catch_errors_test.dart b/tests/lib/async/catch_errors_test.dart
index f4e0eef..adbe5ae 100644
--- a/tests/lib/async/catch_errors_test.dart
+++ b/tests/lib/async/catch_errors_test.dart
@@ -9,14 +9,12 @@
main() {
asyncStart();
- // Make sure `catchErrors` shuts down the error stream when the synchronous
- // operation is done and there isn't any asynchronous pending callback.
+
+ // Make sure `catchErrors` does not execute the error callback.
catchErrors(() {
return 'allDone';
- }).listen((x) {
- Expect.fail("Unexpected callback");
- },
- onDone: () {
- asyncEnd();
- });
+ }).listen((x) { Expect.fail("Unexpected callback"); });
+
+ // Wait one cycle before shutting down the test.
+ Timer.run(asyncEnd);
}
diff --git a/tests/lib/async/intercept_run_async6_test.dart b/tests/lib/async/intercept_run_async6_test.dart
index 82cfcd0..ae42ed5 100644
--- a/tests/lib/async/intercept_run_async6_test.dart
+++ b/tests/lib/async/intercept_run_async6_test.dart
@@ -50,8 +50,7 @@
"async handler", "async handler done",
"after",
"run async body",
- "error: foo",
- "done"],
+ "error: foo"],
events);
asyncEnd();
});
diff --git a/tests/lib/async/run_zoned1_test.dart b/tests/lib/async/run_zoned1_test.dart
index 71af234..74af5b1 100644
--- a/tests/lib/async/run_zoned1_test.dart
+++ b/tests/lib/async/run_zoned1_test.dart
@@ -7,5 +7,5 @@
main() {
// Make sure `runZoned` returns the result of a synchronous call.
- Expect.equals(499, runZonedExperimental(() => 499));
+ Expect.equals(499, runZoned(() => 499));
}
diff --git a/tests/lib/async/run_zoned2_test.dart b/tests/lib/async/run_zoned2_test.dart
deleted file mode 100644
index fa9110f..0000000
--- a/tests/lib/async/run_zoned2_test.dart
+++ /dev/null
@@ -1,14 +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.
-
-import 'package:async_helper/async_helper.dart';
-import "package:expect/expect.dart";
-import 'dart:async';
-
-main() {
- asyncStart();
- // Ensure that `runZoned` is done when a synchronous call finishes.
- runZonedExperimental(() => 499,
- onDone: asyncEnd);
-}
diff --git a/tests/lib/async/run_zoned3_test.dart b/tests/lib/async/run_zoned3_test.dart
deleted file mode 100644
index 4545155..0000000
--- a/tests/lib/async/run_zoned3_test.dart
+++ /dev/null
@@ -1,24 +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.
-
-import 'package:async_helper/async_helper.dart';
-import "package:expect/expect.dart";
-import 'dart:async';
-
-main() {
- asyncStart();
- // Ensure that `runZoned` is done when a synchronous call throws.
- bool sawException = false;
- try {
- runZonedExperimental(() { throw 0; },
- onDone: () {
- // onDone is executed synchronously.
- Expect.isFalse(sawException);
- asyncEnd();
- });
- } catch (e) {
- sawException = true;
- }
- Expect.isTrue(sawException);
-}
diff --git a/tests/lib/async/run_zoned4_test.dart b/tests/lib/async/run_zoned4_test.dart
index ac96b65..a5336b2 100644
--- a/tests/lib/async/run_zoned4_test.dart
+++ b/tests/lib/async/run_zoned4_test.dart
@@ -9,6 +9,6 @@
// Make sure `runZoned` returns the result of a synchronous call when an
// error handler is defined.
Expect.equals(499,
- runZonedExperimental(() => 499,
- onError: (e) { throw "Unexpected"; }));
+ runZoned(() => 499,
+ onError: (e) { throw "Unexpected"; }));
}
diff --git a/tests/lib/async/run_zoned5_test.dart b/tests/lib/async/run_zoned5_test.dart
index 6106a06..6a18d5c 100644
--- a/tests/lib/async/run_zoned5_test.dart
+++ b/tests/lib/async/run_zoned5_test.dart
@@ -9,9 +9,9 @@
main() {
asyncStart();
// Ensure that `runZoned`'s onError handles synchronous errors.
- runZonedExperimental(() { throw 0; },
- onError: (e) {
- Expect.equals(0, e);
- asyncEnd();
- });
+ runZoned(() { throw 0; },
+ onError: (e) {
+ Expect.equals(0, e);
+ asyncEnd();
+ });
}
diff --git a/tests/lib/async/run_zoned6_test.dart b/tests/lib/async/run_zoned6_test.dart
index 9ede7a7..34efae5 100644
--- a/tests/lib/async/run_zoned6_test.dart
+++ b/tests/lib/async/run_zoned6_test.dart
@@ -11,13 +11,13 @@
// Ensure that `runZoned`'s onError handles synchronous errors but delegates
// to the top-level when the handler returns false.
try {
- runZonedExperimental(() { throw 0; },
- onError: (e) {
- Expect.equals(0, e);
- if (false) /// 01: runtime error
- asyncEnd();
- throw e; /// 01: runtime error
- });
+ runZoned(() { throw 0; },
+ onError: (e) {
+ Expect.equals(0, e);
+ if (false) /// 01: runtime error
+ asyncEnd();
+ throw e; /// 01: runtime error
+ });
} catch (e) {
// We should never see an error here.
if (false) /// 01: continued
diff --git a/tests/lib/async/run_zoned7_test.dart b/tests/lib/async/run_zoned7_test.dart
index e6f4067..d6ee3b9 100644
--- a/tests/lib/async/run_zoned7_test.dart
+++ b/tests/lib/async/run_zoned7_test.dart
@@ -9,22 +9,29 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test runZoned with periodic Timers.
- runZonedExperimental(() {
+ runZoned(() {
int counter = 0;
new Timer.periodic(const Duration(milliseconds: 50), (timer) {
- if (counter == 5) timer.cancel();
+ if (counter == 5) {
+ timer.cancel();
+ done.complete(true);
+ }
counter++;
events.add(counter);
});
- }, onDone: () {
- Expect.listEquals([
- "main exit",
- 1, 2, 3, 4, 5, 6,
- ],
- events);
- asyncEnd();
- });
+ });
+
+ done.future.whenComplete(() {
+ Expect.listEquals([
+ "main exit",
+ 1, 2, 3, 4, 5, 6,
+ ],
+ events);
+ asyncEnd();
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/run_zoned8_test.dart b/tests/lib/async/run_zoned8_test.dart
index 6c0c89f..cf642d5 100644
--- a/tests/lib/async/run_zoned8_test.dart
+++ b/tests/lib/async/run_zoned8_test.dart
@@ -9,26 +9,30 @@
main() {
asyncStart();
+ Completer done = new Completer();
+
var events = [];
// Test runZoned with periodic Timers.
- runZonedExperimental(() {
+ runZoned(() {
int counter = 0;
new Timer.periodic(const Duration(milliseconds: 50), (timer) {
- if (counter == 1) timer.cancel();
+ if (counter == 1) {
+ timer.cancel();
+ done.complete(true);
+ }
counter++;
events.add(counter);
throw counter;
});
- }, onError: (e) {
- events.add("error: $e");
- },
- onDone: () {
- Expect.listEquals([
- "main exit",
- 1, "error: 1", 2, "error: 2",
- ],
- events);
- asyncEnd();
- });
+ }, onError: (e) { events.add("error: $e"); });
+
+ done.future.whenComplete(() {
+ Expect.listEquals([
+ "main exit",
+ 1, "error: 1", 2, "error: 2",
+ ],
+ events);
+ asyncEnd();
+ });
events.add("main exit");
}
diff --git a/tests/lib/async/run_zoned9_test.dart b/tests/lib/async/run_zoned9_test.dart
index ab0f5ab1..fab0da3 100644
--- a/tests/lib/async/run_zoned9_test.dart
+++ b/tests/lib/async/run_zoned9_test.dart
@@ -12,13 +12,13 @@
// to the next runZonedExperimental when the handler returns false.
bool sawInnerHandler = false;
try {
- runZonedExperimental(() {
- runZonedExperimental(() { throw 0; },
- onError: (e) {
- Expect.equals(0, e);
- sawInnerHandler = true;
- throw e;
- });
+ runZoned(() {
+ runZoned(() { throw 0; },
+ onError: (e) {
+ Expect.equals(0, e);
+ sawInnerHandler = true;
+ throw e;
+ });
}, onError: (e) {
Expect.equals(0, e);
Expect.isTrue(sawInnerHandler);
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index a130b4c..ecc6474 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -659,7 +659,7 @@
return sink.close();
})
.then((_) {
- if (asBroadcast) {
+ if (asBroadcast || broadcast) {
// The done-future of the sink completes when it passes
// the done event to the asBroadcastStream controller, which is
// before the final listener gets the event.
diff --git a/tests/lib/async/zone_bind_callback_test.dart b/tests/lib/async/zone_bind_callback_test.dart
new file mode 100644
index 0000000..09eded9
--- /dev/null
+++ b/tests/lib/async/zone_bind_callback_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+
+ var valueToCapture;
+ var restoredValue;
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork(specification: new ZoneSpecification(
+ registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
+ // The zone is still the same as when origin.run was invoked, which
+ // is the root zone. (The origin zone hasn't been set yet).
+ Expect.identical(Zone.current, Zone.ROOT);
+ // Note that not forwarding is completely legal, though not encouraged.
+ var capturedValue = valueToCapture;
+ return parent.registerCallback(origin, () {
+ restoredValue = capturedValue;
+ return f();
+ });
+ }));
+
+ valueToCapture = 499;
+ var fun = () {
+ Expect.identical(forked, Zone.current);
+ return 99;
+ };
+ var registered = forked.bindCallback(fun, runGuarded: false);
+ Expect.isFalse(identical(fun, registered));
+
+ var result = registered();
+ Expect.equals(99, result);
+ Expect.equals(499, restoredValue);
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_bind_callback_unary_test.dart b/tests/lib/async/zone_bind_callback_unary_test.dart
new file mode 100644
index 0000000..5753e09
--- /dev/null
+++ b/tests/lib/async/zone_bind_callback_unary_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+
+ var valueToCapture;
+ var restoredValue;
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork(specification: new ZoneSpecification(
+ registerUnaryCallback: (Zone self, ZoneDelegate parent, Zone origin, f(arg)) {
+ // The zone is still the same as when origin.run was invoked, which
+ // is the root zone. (The origin zone hasn't been set yet).
+ Expect.identical(Zone.current, Zone.ROOT);
+ // Note that not forwarding is completely legal, though not encouraged.
+ var capturedValue = valueToCapture;
+ return parent.registerUnaryCallback(origin, (arg) {
+ restoredValue = capturedValue;
+ return f(arg);
+ });
+ }));
+
+ valueToCapture = 499;
+ var fun = (x) {
+ Expect.identical(forked, Zone.current);
+ return x + 99;
+ };
+ var bound = forked.bindUnaryCallback(fun, runGuarded: false);
+ Expect.isFalse(identical(fun, bound));
+
+ // It is legal to invoke the callback in a different zone. This is, of course,
+ // etremely discouraged.
+ var result = bound(399);
+ Expect.equals(498, result);
+ Expect.equals(499, restoredValue);
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_create_periodic_timer_test.dart b/tests/lib/async/zone_create_periodic_timer_test.dart
new file mode 100644
index 0000000..5c9232b
--- /dev/null
+++ b/tests/lib/async/zone_create_periodic_timer_test.dart
@@ -0,0 +1,54 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+ List events = [];
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked;
+ forked = Zone.current.fork(specification: new ZoneSpecification(
+ createPeriodicTimer: (Zone self, ZoneDelegate parent, Zone origin,
+ Duration period, f(Timer timer)) {
+ events.add("forked.createPeriodicTimer");
+ return parent.createPeriodicTimer(origin, period, (Timer timer) {
+ events.add("wrapped function ${period.inMilliseconds}");
+ f(timer);
+ });
+ }));
+
+ asyncStart();
+ int tickCount = 0;
+ forked.run(() {
+ new Timer.periodic(const Duration(milliseconds: 5),
+ (Timer timer) {
+ events.add("periodic Timer $tickCount");
+ Expect.identical(forked, Zone.current);
+ tickCount++;
+ if (tickCount == 4) {
+ timer.cancel();
+ // Allow some time in case the cancel didn't work.
+ new Timer(const Duration(milliseconds: 20), done.complete);
+ }
+ });
+ });
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ events.add("after createPeriodicTimer");
+
+ done.future.whenComplete(() {
+ Expect.listEquals(
+ [ "forked.createPeriodicTimer", "after createPeriodicTimer",
+ "wrapped function 5", "periodic Timer 0",
+ "wrapped function 5", "periodic Timer 1",
+ "wrapped function 5", "periodic Timer 2",
+ "wrapped function 5", "periodic Timer 3" ],
+ events);
+ asyncEnd();
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_create_timer2_test.dart b/tests/lib/async/zone_create_timer2_test.dart
new file mode 100644
index 0000000..c7ccaab
--- /dev/null
+++ b/tests/lib/async/zone_create_timer2_test.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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+ List events = [];
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked;
+ forked = Zone.current.fork(specification: new ZoneSpecification(
+ createTimer: (Zone self, ZoneDelegate parent, Zone origin,
+ Duration duration, f()) {
+ events.add("forked.createTimer");
+ return parent.createTimer(origin, duration, () {
+ events.add("wrapped function ${duration.inMilliseconds}");
+ f();
+ });
+ }));
+
+ asyncStart();
+ forked.run(() {
+ Timer timer = new Timer(const Duration(milliseconds: 20), () {
+ events.add("createTimer");
+ Expect.identical(forked, Zone.current);
+ done.complete(true);
+ });
+ });
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ events.add("after createTimer");
+
+ done.future.whenComplete(() {
+ Expect.listEquals(
+ [ "forked.createTimer", "after createTimer", "wrapped function 20",
+ "createTimer" ],
+ events);
+ asyncEnd();
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_create_timer_test.dart b/tests/lib/async/zone_create_timer_test.dart
new file mode 100644
index 0000000..4935522
--- /dev/null
+++ b/tests/lib/async/zone_create_timer_test.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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+ List events = [];
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked;
+ forked = Zone.current.fork(specification: new ZoneSpecification(
+ createTimer: (Zone self, ZoneDelegate parent, Zone origin,
+ Duration duration, f()) {
+ events.add("forked.createTimer");
+ return parent.createTimer(origin, duration, () {
+ events.add("wrapped function ${duration.inMilliseconds}");
+ f();
+ });
+ }));
+
+ asyncStart();
+ forked.run(() {
+ new Timer(Duration.ZERO, () {
+ events.add("createTimer");
+ Expect.identical(forked, Zone.current);
+ done.complete(true);
+ });
+ });
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ events.add("after createTimer");
+
+ done.future.whenComplete(() {
+ Expect.listEquals(
+ [ "forked.createTimer", "after createTimer", "wrapped function 0",
+ "createTimer" ],
+ events);
+ asyncEnd();
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_debug_test.dart b/tests/lib/async/zone_debug_test.dart
new file mode 100644
index 0000000..10d43fc
--- /dev/null
+++ b/tests/lib/async/zone_debug_test.dart
@@ -0,0 +1,133 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+import 'dart:collection';
+
+/**
+ * We represent the current stack trace by an integer. From time to time we
+ * increment the variable. This corresponds to a new stack trace.
+ */
+int stackTrace = 0;
+List restoredStackTrace = [];
+
+List events = [];
+
+debugZoneRegisterCallback(Zone self, ZoneDelegate parent, Zone origin, f()) {
+ List savedTrace = [stackTrace]..addAll(restoredStackTrace);
+ return parent.registerCallback(origin, () {
+ restoredStackTrace = savedTrace;
+ return f();
+ });
+}
+
+debugZoneRegisterUnaryCallback(Zone self, ZoneDelegate parent, Zone origin,
+ f(arg)) {
+ List savedTrace = [stackTrace]..addAll(restoredStackTrace);
+ return parent.registerCallback(origin, (arg) {
+ restoredStackTrace = savedTrace;
+ return f(arg);
+ });
+}
+
+debugZoneRun(Zone self, ZoneDelegate parent, Zone origin, f()) {
+ stackTrace++;
+ restoredStackTrace = [];
+ return parent.run(origin, f);
+}
+
+debugZoneRunUnary(Zone self, ZoneDelegate parent, Zone origin, f(arg), arg) {
+ stackTrace++;
+ restoredStackTrace = [];
+ return parent.run1(origin, f, arg);
+}
+
+List expectedDebugTrace;
+
+debugUncaughtHandler(Zone self, ZoneDelegate parent, Zone origin, error) {
+ events.add("handling uncaught error $error");
+ Expect.listEquals(expectedDebugTrace, restoredStackTrace);
+ // Suppress the error and don't propagate to parent.
+}
+
+const DEBUG_SPECIFICATION = const ZoneSpecification(
+ registerCallback: debugZoneRegisterCallback,
+ registerUnaryCallback: debugZoneRegisterUnaryCallback,
+ run: debugZoneRun,
+ runUnary: debugZoneRunUnary,
+ handleUncaughtError: debugUncaughtHandler);
+
+main() {
+ Completer done = new Completer();
+
+ // runGuarded calls run, captures the synchronous error (if any) and
+ // gives that one to handleUncaughtError.
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked;
+ forked = Zone.current.fork(specification: DEBUG_SPECIFICATION);
+
+ asyncStart();
+
+ int openTests = 0;
+
+ openTests++;
+ forked.run(() {
+ int forkTrace = stackTrace;
+ runAsync(() {
+ int runAsyncTrace = stackTrace;
+ runAsync(() {
+ expectedDebugTrace = [runAsyncTrace, forkTrace];
+ openTests--;
+ if (openTests == 0) {
+ done.complete();
+ }
+ throw "foo";
+ });
+ expectedDebugTrace = [forkTrace];
+ throw "bar";
+ });
+ });
+
+ Expect.listEquals([], restoredStackTrace);
+ Zone forked2 = forked.fork();
+ Zone forked3 = forked2.fork();
+ int fork2Trace;
+ int fork3Trace;
+ var f2;
+ var globalTrace = stackTrace;
+ var f = forked3.bindCallback(() {
+ Expect.identical(forked3, Zone.current);
+ fork2Trace = stackTrace;
+ f2 = forked2.bindCallback(() {
+ Expect.identical(forked2, Zone.current);
+ Expect.listEquals([fork2Trace, globalTrace], restoredStackTrace);
+ fork3Trace = stackTrace;
+ openTests--;
+ if (openTests == 0) {
+ done.complete();
+ }
+ runAsync(() {
+ expectedDebugTrace = [fork3Trace, fork2Trace, globalTrace];
+ throw "gee";
+ });
+ }, runGuarded: false);
+ }, runGuarded: false);
+ openTests++;
+ f();
+ f2();
+
+ done.future.whenComplete(() {
+ // We don't really care for the order.
+ events.sort();
+ Expect.listEquals([ "handling uncaught error bar",
+ "handling uncaught error foo",
+ "handling uncaught error gee"],
+ events);
+ asyncEnd();
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_empty_description2_test.dart b/tests/lib/async/zone_empty_description2_test.dart
new file mode 100644
index 0000000..68e1453
--- /dev/null
+++ b/tests/lib/async/zone_empty_description2_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+testEmptyZoneSpecification() {
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork();
+ Expect.isFalse(identical(Zone.ROOT, forked));
+
+ asyncStart();
+ bool timerDidRun = false;
+ forked.createTimer(const Duration(milliseconds: 20), () {
+ // The createTimer functions on the Zone don't bind the closures.
+ Expect.identical(Zone.ROOT, Zone.current);
+ timerDidRun = true;
+ asyncEnd();
+ });
+ Expect.identical(Zone.ROOT, Zone.current);
+
+ asyncStart();
+ int periodicTimerCount = 0;
+ forked.createPeriodicTimer(const Duration(milliseconds: 20), (Timer timer) {
+ periodicTimerCount++;
+ if (periodicTimerCount == 4) {
+ timer.cancel();
+ asyncEnd();
+ }
+ // The createPeriodicTimer functions on the Zone don't bind the closures.
+ Expect.identical(Zone.ROOT, Zone.current);
+ });
+ Expect.identical(Zone.ROOT, Zone.current);
+}
+
+main() {
+ testEmptyZoneSpecification();
+}
diff --git a/tests/lib/async/zone_empty_description_test.dart b/tests/lib/async/zone_empty_description_test.dart
new file mode 100644
index 0000000..81ddedc
--- /dev/null
+++ b/tests/lib/async/zone_empty_description_test.dart
@@ -0,0 +1,80 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+testForkedZone(Zone forked) {
+ var result;
+ result = forked.run(() {
+ Expect.identical(forked, Zone.current);
+ return 499;
+ });
+ Expect.equals(499, result);
+ Expect.identical(Zone.ROOT, Zone.current);
+
+ result = forked.runUnary((x) {
+ Expect.equals(42, x);
+ Expect.identical(forked, Zone.current);
+ return -499;
+ }, 42);
+ Expect.equals(-499, result);
+ Expect.identical(Zone.ROOT, Zone.current);
+
+ bool runGuardedDidRun = false;
+ forked.runGuarded(() {
+ runGuardedDidRun = true;
+ Expect.identical(forked, Zone.current);
+ });
+ Expect.identical(Zone.ROOT, Zone.current);
+ Expect.isTrue(runGuardedDidRun);
+
+ runGuardedDidRun = false;
+ forked.runUnaryGuarded((x) {
+ runGuardedDidRun = true;
+ Expect.equals(42, x);
+ Expect.identical(forked, Zone.current);
+ }, 42);
+ Expect.identical(Zone.ROOT, Zone.current);
+ Expect.isTrue(runGuardedDidRun);
+
+ var callback = () => 499;
+ Expect.identical(callback, forked.registerCallback(callback));
+ Expect.identical(Zone.ROOT, Zone.current);
+
+ var callback1 = (x) => 42 + x;
+ Expect.identical(callback1, forked.registerUnaryCallback(callback1));
+ Expect.identical(Zone.ROOT, Zone.current);
+
+ asyncStart();
+ bool asyncDidRun = false;
+ forked.scheduleMicrotask(() {
+ // The runAsync functions on the Zone don't bind the closures.
+ Expect.identical(Zone.ROOT, Zone.current);
+ asyncDidRun = true;
+ asyncEnd();
+ });
+ Expect.isFalse(asyncDidRun);
+ Expect.identical(Zone.ROOT, Zone.current);
+
+ asyncStart();
+ bool timerDidRun = false;
+ forked.createTimer(const Duration(milliseconds: 0), () {
+ // The createTimer functions on the Zone don't bind the closures.
+ Expect.identical(Zone.ROOT, Zone.current);
+ timerDidRun = true;
+ asyncEnd();
+ });
+ Expect.identical(Zone.ROOT, Zone.current);
+}
+
+main() {
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork();
+ Expect.isFalse(identical(Zone.ROOT, forked));
+ testForkedZone(forked);
+ Zone forkedChild = forked.fork();
+ testForkedZone(forkedChild);
+}
diff --git a/tests/lib/async/zone_fork_test.dart b/tests/lib/async/zone_fork_test.dart
new file mode 100644
index 0000000..883daff
--- /dev/null
+++ b/tests/lib/async/zone_fork_test.dart
@@ -0,0 +1,58 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+ List events = [];
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked;
+ forked = Zone.current.fork(specification: new ZoneSpecification(
+ fork: (Zone self, ZoneDelegate parent, Zone origin,
+ ZoneSpecification zoneSpecification, Map mapValues) {
+ // The zone is still the same as when origin.run was invoked, which
+ // is the root zone. (The origin zone hasn't been set yet).
+ Expect.identical(Zone.ROOT, Zone.current);
+ events.add("forked.fork");
+ Function descriptionRun = zoneSpecification.run;
+ ZoneSpecification modified = new ZoneSpecification.from(
+ zoneSpecification,
+ run: (self, parent, origin, f) {
+ events.add("wrapped run");
+ return descriptionRun(self, parent, origin, () {
+ events.add("wrapped f");
+ return f();
+ });
+ });
+ return parent.fork(origin, modified, mapValues);
+ }));
+
+ events.add("start");
+ Zone forkedChild = forked.fork(specification: new ZoneSpecification(
+ run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
+ events.add("executing child run");
+ return parent.run(origin, f);
+ }));
+
+ events.add("after child fork");
+ Expect.identical(Zone.ROOT, Zone.current);
+
+ forkedChild.run(() {
+ events.add("child run");
+ });
+
+ events.add("after child run");
+
+ Expect.listEquals(
+ [ "start",
+ "forked.fork",
+ "after child fork",
+ "wrapped run", "executing child run", "wrapped f", "child run",
+ "after child run" ],
+ events);
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_future_run_async_test.dart b/tests/lib/async/zone_future_run_async_test.dart
new file mode 100644
index 0000000..ddfac18
--- /dev/null
+++ b/tests/lib/async/zone_future_run_async_test.dart
@@ -0,0 +1,64 @@
+// 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.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+
+main() {
+ asyncStart();
+ Completer done = new Completer();
+
+ // Make sure that the zones use the runAsync of their zones.
+ int runAsyncCount = 0;
+ Completer completer;
+ Completer completer2;
+ Future future;
+ Future future2;
+ runZonedExperimental(() {
+ completer = new Completer();
+ completer.complete(499);
+ completer2 = new Completer.sync();
+ completer2.complete(-499);
+ future = new Future.value(42);
+ future2 = new Future.error(11);
+ }, onRunAsync: (f) {
+ runAsyncCount++;
+ runAsync(f);
+ });
+ int openCallbackCount = 0;
+
+ openCallbackCount++;
+ completer.future.then((x) {
+ Expect.equals(499, x);
+ openCallbackCount--;
+ if (openCallbackCount == 0) done.complete();
+ });
+
+ openCallbackCount++;
+ completer2.future.then((x) {
+ Expect.equals(-499, x);
+ openCallbackCount--;
+ if (openCallbackCount == 0) done.complete();
+ });
+
+ openCallbackCount++;
+ future.then((x) {
+ Expect.equals(42, x);
+ openCallbackCount--;
+ if (openCallbackCount == 0) done.complete();
+ });
+
+ openCallbackCount++;
+ future2.catchError((x) {
+ Expect.equals(11, x);
+ openCallbackCount--;
+ if (openCallbackCount == 0) done.complete();
+ });
+
+ done.future.whenComplete(() {
+ Expect.equals(4, runAsyncCount);
+ asyncEnd();
+ });
+}
diff --git a/tests/lib/async/zone_register_callback_test.dart b/tests/lib/async/zone_register_callback_test.dart
new file mode 100644
index 0000000..e05ed8e
--- /dev/null
+++ b/tests/lib/async/zone_register_callback_test.dart
@@ -0,0 +1,39 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+
+ var valueToCapture;
+ var restoredValue;
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork(specification: new ZoneSpecification(
+ registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
+ // The zone is still the same as when origin.run was invoked, which
+ // is the root zone. (The origin zone hasn't been set yet).
+ Expect.identical(Zone.current, Zone.ROOT);
+ // Note that not forwarding is completely legal, though not encouraged.
+ var capturedValue = valueToCapture;
+ return parent.registerCallback(origin, () {
+ restoredValue = capturedValue;
+ return f();
+ });
+ }));
+
+ valueToCapture = 499;
+ var fun = () => 99;
+ var registered = forked.registerCallback(fun);
+ Expect.isFalse(identical(fun, registered));
+
+ // It is legal to invoke the callback in a different zone. This is, of course,
+ // extremely discouraged.
+ var result = registered();
+ Expect.equals(99, result);
+ Expect.equals(499, restoredValue);
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_register_callback_unary_test.dart b/tests/lib/async/zone_register_callback_unary_test.dart
new file mode 100644
index 0000000..2049e02
--- /dev/null
+++ b/tests/lib/async/zone_register_callback_unary_test.dart
@@ -0,0 +1,39 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+
+ var valueToCapture;
+ var restoredValue;
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork(specification: new ZoneSpecification(
+ registerUnaryCallback: (Zone self, ZoneDelegate parent, Zone origin, f(arg)) {
+ // The zone is still the same as when origin.run was invoked, which
+ // is the root zone. (The origin zone hasn't been set yet).
+ Expect.identical(Zone.current, Zone.ROOT);
+ // Note that not forwarding is completely legal, though not encouraged.
+ var capturedValue = valueToCapture;
+ return parent.registerUnaryCallback(origin, (arg) {
+ restoredValue = capturedValue;
+ return f(arg);
+ });
+ }));
+
+ valueToCapture = 499;
+ var fun = (x) => x + 99;
+ var registered = forked.registerUnaryCallback(fun);
+ Expect.isFalse(identical(fun, registered));
+
+ // It is valid to invoke the callback in a different zone. This is, of course,
+ // extremely discouraged.
+ var result = registered(399);
+ Expect.equals(498, result);
+ Expect.equals(499, restoredValue);
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_root_bind_test.dart b/tests/lib/async/zone_root_bind_test.dart
new file mode 100644
index 0000000..7b73f98
--- /dev/null
+++ b/tests/lib/async/zone_root_bind_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork();
+ var f = Zone.current.bindCallback(() {
+ Expect.identical(Zone.ROOT, Zone.current);
+ }, runGuarded: false);
+ forked.run(() {
+ f();
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_run_guarded_test.dart b/tests/lib/async/zone_run_guarded_test.dart
new file mode 100644
index 0000000..42faaeb
--- /dev/null
+++ b/tests/lib/async/zone_run_guarded_test.dart
@@ -0,0 +1,78 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+ List events = [];
+
+ // runGuarded calls run, captures the synchronous error (if any) and
+ // gives that one to handleUncaughtError.
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked;
+ forked = Zone.current.fork(specification: new ZoneSpecification(
+ run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
+ // The zone is still the same as when origin.run was invoked, which
+ // is the root zone. (The origin zone hasn't been set yet).
+ Expect.identical(Zone.ROOT, Zone.current);
+ events.add("forked.run");
+ return parent.run(origin, f);
+ },
+ handleUncaughtError: (Zone self, ZoneDelegate parent, Zone origin, e) {
+ Expect.identical(Zone.ROOT, Zone.current);
+ Expect.identical(forked, origin);
+ events.add("forked.handleUncaught $e");
+ return 499;
+ }));
+
+ var result = forked.runGuarded(() {
+ events.add("runGuarded 1");
+ Expect.identical(forked, Zone.current);
+ return 42;
+ });
+ Expect.identical(Zone.ROOT, Zone.current);
+ Expect.equals(42, result);
+ events.add("after runGuarded 1");
+
+ result = forked.runGuarded(() {
+ events.add("runGuarded 2");
+ Expect.identical(forked, Zone.current);
+ throw 42;
+ });
+ Expect.equals(499, result);
+
+ Expect.listEquals(
+ [ "forked.run", "runGuarded 1", "after runGuarded 1",
+ "forked.run", "runGuarded 2", "forked.handleUncaught 42" ],
+ events);
+
+ events.clear();
+ asyncStart();
+ result = forked.runGuarded(() {
+ Expect.identical(forked, Zone.current);
+ events.add("run closure");
+ runAsync(() {
+ events.add("run closure 2");
+ Expect.identical(forked, Zone.current);
+ done.complete(true);
+ throw 88;
+ });
+ throw 1234;
+ });
+ events.add("after nested runAsync");
+ Expect.equals(499, result);
+
+ done.future.whenComplete(() {
+ Expect.listEquals(
+ ["forked.run", "run closure", "forked.handleUncaught 1234",
+ "after nested runAsync", "forked.run", "run closure 2",
+ "forked.handleUncaught 88" ],
+ events);
+ asyncEnd();
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_run_test.dart b/tests/lib/async/zone_run_test.dart
new file mode 100644
index 0000000..51d52e2
--- /dev/null
+++ b/tests/lib/async/zone_run_test.dart
@@ -0,0 +1,65 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+ List events = [];
+
+ bool shouldForward = true;
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork(specification: new ZoneSpecification(
+ run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
+ // The zone is still the same as when origin.run was invoked, which
+ // is the root zone. (The origin zone hasn't been set yet).
+ Expect.identical(Zone.current, Zone.ROOT);
+ events.add("forked.run");
+ if (shouldForward) return parent.run(origin, f);
+ return 42;
+ }));
+
+ events.add("zone forked");
+ Zone expectedZone = forked;
+ var result = forked.run(() {
+ Expect.identical(expectedZone, Zone.current);
+ events.add("run closure");
+ return 499;
+ });
+ Expect.equals(499, result);
+ events.add("executed run");
+
+ shouldForward = false;
+ result = forked.run(() {
+ Expect.fail("should not be invoked");
+ });
+ Expect.equals(42, result);
+ events.add("executed run2");
+
+ asyncStart();
+ shouldForward = true;
+ result = forked.run(() {
+ Expect.identical(forked, Zone.current);
+ events.add("run closure 2");
+ runAsync(() {
+ events.add("run closure 3");
+ Expect.identical(forked, Zone.current);
+ done.complete(true);
+ });
+ return 1234;
+ });
+ events.add("after nested runAsync");
+ Expect.equals(1234, result);
+
+ done.future.whenComplete(() {
+ Expect.listEquals(
+ ["zone forked", "forked.run", "run closure", "executed run",
+ "forked.run", "executed run2", "forked.run", "run closure 2",
+ "after nested runAsync", "forked.run", "run closure 3"],
+ events);
+ asyncEnd();
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_run_unary_test.dart b/tests/lib/async/zone_run_unary_test.dart
new file mode 100644
index 0000000..61f8ce8
--- /dev/null
+++ b/tests/lib/async/zone_run_unary_test.dart
@@ -0,0 +1,65 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+ List events = [];
+
+ bool shouldForward = true;
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked = Zone.current.fork(specification: new ZoneSpecification(
+ runUnary: (Zone self, ZoneDelegate parent, Zone origin, f(arg), arg) {
+ // The zone is still the same as when origin.run was invoked, which
+ // is the root zone. (The origin zone hasn't been set yet).
+ Expect.identical(Zone.current, Zone.ROOT);
+ events.add("forked.run1");
+ if (shouldForward) return parent.runUnary(origin, f, arg + 1);
+ return 42;
+ }));
+
+ events.add("zone forked");
+ Zone expectedZone = forked;
+ var result = forked.runUnary((arg) {
+ Expect.identical(expectedZone, Zone.current);
+ events.add("run closure");
+ return arg + 3;
+ }, 495);
+ Expect.equals(499, result);
+ events.add("executed run");
+
+ shouldForward = false;
+ result = forked.runUnary((arg) {
+ Expect.fail("should not be invoked");
+ }, 99);
+ Expect.equals(42, result);
+ events.add("executed run2");
+
+ asyncStart();
+ shouldForward = true;
+ result = forked.runUnary((arg) {
+ Expect.identical(forked, Zone.current);
+ events.add("run closure 2");
+ runAsync(() {
+ events.add("run closure 3");
+ Expect.identical(forked, Zone.current);
+ done.complete(true);
+ });
+ return -arg - 8;
+ }, 490);
+ events.add("after nested runAsync");
+ Expect.equals(-499, result);
+
+ done.future.whenComplete(() {
+ Expect.listEquals(
+ ["zone forked", "forked.run1", "run closure", "executed run",
+ "forked.run1", "executed run2", "forked.run1", "run closure 2",
+ "after nested runAsync", "run closure 3"],
+ events);
+ asyncEnd();
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/async/zone_value_test.dart b/tests/lib/async/zone_value_test.dart
new file mode 100644
index 0000000..8aa7c85
--- /dev/null
+++ b/tests/lib/async/zone_value_test.dart
@@ -0,0 +1,54 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+ Completer done = new Completer();
+ List events = [];
+
+ // runGuarded calls run, captures the synchronous error (if any) and
+ // gives that one to handleUncaughtError.
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Zone forked;
+ Map zoneValues = new Map();
+ var foo = const Symbol("foo");
+ var bar = const Symbol("bar");
+ zoneValues[foo] = 499;
+ zoneValues[bar] = [];
+ forked = Zone.current.fork(zoneValues: zoneValues);
+
+ Expect.identical(Zone.ROOT, Zone.current);
+ Expect.isNull(Zone.current[foo]);
+ Expect.isNull(Zone.current[bar]);
+
+ forked.run(() {
+ Expect.equals(499, Zone.current[foo]);
+ Expect.listEquals([], Zone.current[bar]);
+ Zone.current[bar].add(42);
+ });
+ Expect.identical(Zone.ROOT, Zone.current);
+ Expect.isNull(Zone.current[foo]);
+ Expect.isNull(Zone.current[bar]);
+
+ forked.run(() {
+ Expect.equals(499, Zone.current[foo]);
+ Expect.listEquals([42], Zone.current[bar]);
+ });
+
+ zoneValues = new Map();
+ var gee = const Symbol("gee");
+ zoneValues[gee] = 99;
+ zoneValues[foo] = -499;
+ Zone forkedChild = forked.fork(zoneValues: zoneValues);
+
+ forkedChild.run(() {
+ Expect.equals(-499, Zone.current[foo]);
+ Expect.listEquals([42], Zone.current[bar]);
+ Expect.equals(99, Zone.current[gee]);
+ });
+}
\ No newline at end of file
diff --git a/tests/lib/convert/html_escape_test.dart b/tests/lib/convert/html_escape_test.dart
index 691547b..674c781 100644
--- a/tests/lib/convert/html_escape_test.dart
+++ b/tests/lib/convert/html_escape_test.dart
@@ -8,15 +8,15 @@
const _NOOP = 'Nothing_to_escape';
-const _TEST_INPUT = '<A <test> of \u00A0 "double" & \'single\' values>';
+const _TEST_INPUT = '<A </test> of \u00A0 "double" & \'single\' values>';
-const _OUTPUT_UNKNOWN = '<A <test> of "double" & '
- ''single' values>';
+const _OUTPUT_UNKNOWN = '<A </test> of "double" & '
+ ''single' values>';
-const _OUTPUT_ATTRIBUTE = "<A <test> of "double" & "
+const _OUTPUT_ATTRIBUTE = "<A </test> of "double" & "
"\'single\' values>";
-const _OUTPUT_ELEMENT = '<A <test> of "double" & '
+const _OUTPUT_ELEMENT = '<A </test> of "double" & '
'\'single\' values>';
void _testMode(HtmlEscape escape, String input, String expected) {
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index fe1fd3d..4276ffc 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -2,81 +2,89 @@
# 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.
-[ $compiler == dart2js && $runtime == drt ]
-convert/chunked_conversion_utf87_test: Pass, Fail # v8 bug: Issue 12293
-typed_data/byte_data_test: Pass, Fail # v8 bug: Issue 12293
-
[ $compiler == dart2js ]
-math/double_pow_test: Fail
-math/low_test: Fail
-math/random_test: Fail
-mirrors/class_mirror_type_variables_test: Fail # Issue 12087
-mirrors/equality_test/02: Fail # Issue 12333
-mirrors/fake_function_test: Fail # Issue 11612
-mirrors/function_type_mirror_test: Fail # Issue 12166
-mirrors/generics_test/01: Fail # Issue 12333
-mirrors/hierarchy_invariants_test: Fail # Issue 11863
-mirrors/invoke_test: Fail # Issue 11954
-mirrors/invoke_named_test: Fail # Issue 10471, 12863
-mirrors/invoke_private_test: Fail # Issue 12164
-mirrors/invoke_throws_test: Fail # Issue 11954
+math/double_pow_test: RuntimeError
+math/low_test: RuntimeError
+math/random_test: RuntimeError
+mirrors/closure_mirror_find_in_context_test: Fail # Issue 6490
+mirrors/equality_test/02: RuntimeError # Issue 12333
+mirrors/fake_function_test: RuntimeError # Issue 11612
+mirrors/function_type_mirror_test: RuntimeError # Issue 12166
+mirrors/generics_test/01: RuntimeError # Issue 12333
+mirrors/hierarchy_invariants_test: RuntimeError # Issue 11863
+mirrors/invoke_test: RuntimeError # Issue 11954
+mirrors/invoke_closurization_test: RuntimeError # Issue 13002
+mirrors/invoke_named_test/none: RuntimeError # Issue 12863
+mirrors/invoke_private_test: CompileTimeError # Issue 12164
+mirrors/invoke_throws_test: RuntimeError # Issue 11954
mirrors/library_uri_io_test: Skip # Not intended for dart2js as it uses dart:io.
-mirrors/method_mirror_name_test: Fail # Issue 6335
-mirrors/method_mirror_properties_test: Fail # Issue 11861
-mirrors/method_mirror_returntype_test : Fail # Issue 11928
-mirrors/method_mirror_source_test : Fail # Issue 6490
-mirrors/mirrors_test: Fail # TODO(ahe): I'm working on fixing this.
-mirrors/mixin_test/none: Fail # Issue 12464
-mirrors/new_instance_with_type_arguments_test: Fail # Issue 12333
-mirrors/null_test : Fail # Issue 12129
-mirrors/parameter_test/none: Fail # Issue 6490
-mirrors/parameter_metadata_test: Fail # Issue 10905
-mirrors/reflected_type_test: Fail # Issue 12607
-mirrors/typedef_metadata_test: Fail # Issue 12785
-mirrors/typevariable_mirror_metadata_test: Fail # Issue 10905
-mirrors/unnamed_library_test: Fail # Issue 10580
-async/run_async3_test: Fail # _enqueueImmediate runs after Timer. http://dartbug.com/9002
-async/run_async4_test: Pass, Fail # no global exception handler in isolates. http://dartbug.com/9012
-async/run_async6_test: Fail # global error handling is not supported. http://dartbug.com/5958
-async/stream_controller_async_test: Fail, Pass # http://dartbug.com/11953
-mirrors/typedef_test/none: Fail # http://dartbug.com/6490
-mirrors/typedef_test/02: Fail, OK # Incorrect VM behavior.
-mirrors/redirecting_factory_test/none: Fail # Issue 6490
-mirrors/redirecting_factory_test/02: Fail # Issue 6490
-mirrors/closures_test/none: Fail # Issue 6490
+mirrors/method_mirror_name_test: RuntimeError # Issue 6335
+mirrors/method_mirror_properties_test: RuntimeError # Issue 11861
+mirrors/method_mirror_returntype_test : RuntimeError # Issue 11928
+mirrors/method_mirror_source_test : RuntimeError # Issue 6490
+mirrors/mirrors_test: RuntimeError # TODO(ahe): I'm working on fixing this.
+mirrors/mixin_test/none: RuntimeError # Issue 12464
+mirrors/new_instance_with_type_arguments_test: RuntimeError # Issue 12333
+mirrors/null_test : RuntimeError # Issue 12129
+mirrors/parameter_test/none: RuntimeError # Issue 6490
+mirrors/parameter_metadata_test: CompileTimeError # Issue 10905
+mirrors/reflected_type_test: RuntimeError # Issue 12607
+mirrors/typedef_metadata_test: RuntimeError # Issue 12785
+mirrors/typevariable_mirror_metadata_test: CompileTimeError # Issue 10905
+mirrors/unnamed_library_test: RuntimeError # Issue 10580
+async/run_async3_test: RuntimeError # _enqueueImmediate runs after Timer. http://dartbug.com/9002
+async/run_async4_test: Pass, RuntimeError # no global exception handler in isolates. http://dartbug.com/9012
+async/run_async6_test: RuntimeError # global error handling is not supported. http://dartbug.com/5958
+mirrors/typedef_test/none: RuntimeError # http://dartbug.com/6490
+mirrors/redirecting_factory_test/none: RuntimeError # Issue 6490
+mirrors/redirecting_factory_test/02: RuntimeError # Issue 6490
+mirrors/closures_test/none: RuntimeError # Issue 6490
+mirrors/library_metadata2_test/01: CompileTimeError # Issue 13633
[ $runtime == safari ]
mirrors/return_type_test: Pass, Timeout # Issue 12858
[ $compiler == dart2js && $runtime != jsshell && $runtime != safari && $runtime != ff && $runtime != ie9 && $runtime != ie10]
-math/math_test: Fail
-math/math2_test: Fail
+math/math_test: RuntimeError
+math/math2_test: RuntimeError
[ $compiler == dart2js && $jscl ]
-async/future_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/slow_consumer2_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/slow_consumer3_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/slow_consumer_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/stream_from_iterable_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/stream_state_nonzero_timer_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/multiple_timer_test: Fail,OK # Needs Timer to run.
-async/timer_cancel_test: Fail,OK # Needs Timer to run.
-async/timer_cancel1_test: Fail,OK # Needs Timer to run.
-async/timer_cancel2_test: Fail,OK # Needs Timer to run.
-async/timer_isolate_test: Fail, OK # Needs Timer to run.
-async/timer_repeat_test: Fail,OK # Needs Timer to run.
-async/timer_test: Fail,OK # Needs Timer to run.
+async/future_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/slow_consumer2_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/slow_consumer3_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/slow_consumer_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/stream_from_iterable_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/stream_state_nonzero_timer_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/multiple_timer_test: RuntimeError,OK # Needs Timer to run.
+async/timer_cancel_test: RuntimeError,OK # Needs Timer to run.
+async/timer_cancel1_test: RuntimeError,OK # Needs Timer to run.
+async/timer_cancel2_test: RuntimeError,OK # Needs Timer to run.
+async/timer_isolate_test: RuntimeError, OK # Needs Timer to run.
+async/timer_repeat_test: RuntimeError,OK # Needs Timer to run.
+async/timer_test: RuntimeError,OK # Needs Timer to run.
+async/stream_controller_async_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic2_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic3_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic4_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/stream_periodic5_test: RuntimeError # Timer interface not supported; dartbug.com/7728.
+async/run_zoned7_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
+async/catch_errors22_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
+async/timer_isActive_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
+async/zone_empty_description2_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
+async/zone_create_timer2_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
+async/zone_create_periodic_timer_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
+async/catch_errors12_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/catch_errors13_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/catch_errors14_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/catch_errors15_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/catch_errors18_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/catch_errors19_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/catch_errors20_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/catch_errors28_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/catch_errors8_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/run_zoned8_test: Fail # Timer interface not supported: dartbug.com/7728.
-[ $compiler == dart2js && ($jscl || $runtime == d8) ]
-async/stream_controller_async_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/stream_periodic_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/stream_periodic2_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/stream_periodic3_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/stream_periodic4_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/stream_periodic5_test: Fail # Timer interface not supported; dartbug.com/7728.
-async/run_zoned7_test: Fail # Timer interface not supported: dartbug.com/7728.
-async/catch_errors22_test: Fail # Timer interface not supported: dartbug.com/7728.
-async/timer_isActive_test: Fail # Timer interface not supported: dartbug.com/7728.
[ $compiler == dart2js && $browser ]
async/timer_not_available_test: Fail, OK # only meant to test when there is no way to
@@ -110,7 +118,7 @@
convert/streamed_conversion_utf8_decode_test: Pass, Timeout # http://dartbug.com/12768
[ $compiler == dart2js ]
-typed_data/typed_data_hierarchy_int64_test: Fail # Issue 10275
+typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 10275
[ $runtime == opera ]
async/multiple_timer_test: Pass, Fail
@@ -158,11 +166,24 @@
async/run_zoned6_test/01: fail # Issue 12756.
async/run_zoned9_test/01: fail # Issue 12756.
+async/stream_controller_async_test: Pass, Fail # Issue 13608
+
[ $compiler == dartanalyzer ]
+mirrors/typedef_test/none: Fail # Issue 13093
+mirrors/generics_test/none: Fail # Issue 13432
+mirrors/invoke_named_test/none: Fail # http://dartbug.com/13612
+
+mirrors/parameter_metadata_test: Fail # Issue 13510
+mirrors/method_mirror_returntype_test: Fail # Issue 13510
+mirrors/function_type_mirror_test: Fail # Issue 13510
+mirrors/typevariable_mirror_metadata_test: Fail # Issue 13510
+
+[ $compiler == dart2analyzer ]
mirrors/library_metadata2_test/01: Fail # http://dartbug.com/12950
mirrors/typedef_test/none: Fail # Issue 13093
mirrors/generics_test/none: Fail # Issue 13432
-[ $compiler == dart2analyzer ]
-mirrors/library_metadata2_test/01: Fail # http://dartbug.com/12950
-
+mirrors/parameter_metadata_test: Fail # Issue 13510
+mirrors/method_mirror_returntype_test: Fail # Issue 13510
+mirrors/function_type_mirror_test: Fail # Issue 13510
+mirrors/typevariable_mirror_metadata_test: Fail # Issue 13510
diff --git a/tests/lib/math/min_max_test.dart b/tests/lib/math/min_max_test.dart
index 46d0566..2b16176 100644
--- a/tests/lib/math/min_max_test.dart
+++ b/tests/lib/math/min_max_test.dart
@@ -11,10 +11,28 @@
var inf = double.INFINITY;
var nan = double.NAN;
+// A class that might work if [min] and [max] worked for non-numbers.
+class Wrap implements Comparable {
+ final value;
+ Wrap(this.value);
+ int compare(Wrap other) => value.compare(other.value);
+ bool operator<(Wrap other) => compare(other) < 0;
+ bool operator<=(Wrap other) => compare(other) <= 0;
+ bool operator>(Wrap other) => compare(other) > 0;
+ bool operator>=(Wrap other) => compare(other) >= 0;
+ bool operator==(other) => other is Wrap && compare(other) == 0;
+ String toString() => 'Wrap($value)';
+ int get hashCode => value.hashCode;
+}
+
+var wrap1 = new Wrap(1);
+var wrap2 = new Wrap(2);
+
testMin() {
testMin1();
testMin2();
testMin3();
+ testMinChecks();
}
testMin1() {
@@ -279,10 +297,19 @@
Expect.isFalse(min(inf, inf).isNegative);
}
+testMinChecks() {
+ // Min and max work only on numbers.
+ // These throw a type assertion or ArgumentError.
+ Expect.throws(() => min(wrap1, wrap2));
+ Expect.throws(() => min(wrap1, 0));
+ Expect.throws(() => min(0, wrap2));
+}
+
testMax() {
testMax1();
testMax2();
testMax3();
+ testMaxChecks();
}
testMax1() {
@@ -537,6 +564,14 @@
Expect.isTrue(max(-inf, -inf).isNegative);
}
+testMaxChecks() {
+ // Min and max work only on numbers.
+ // These throw a type assertion or ArgumentError.
+ Expect.throws(() => min(wrap1, wrap2));
+ Expect.throws(() => min(wrap1, 0));
+ Expect.throws(() => min(0, wrap2));
+}
+
main() {
testMin();
testMin();
diff --git a/tests/lib/mirrors/class_mirror_type_variables_test.dart b/tests/lib/mirrors/class_mirror_type_variables_test.dart
index c4149e4..ee7baf9 100644
--- a/tests/lib/mirrors/class_mirror_type_variables_test.dart
+++ b/tests/lib/mirrors/class_mirror_type_variables_test.dart
@@ -22,9 +22,9 @@
values.forEach((e) {
Expect.equals(true, e is TypeVariableMirror);
});
- Expect.equals(const Symbol("R"), values.elementAt(0).simpleName);
- Expect.equals(const Symbol("S"), values.elementAt(1).simpleName);
- Expect.equals(const Symbol("T"), values.elementAt(2).simpleName);
+ Expect.equals(#R, values.elementAt(0).simpleName);
+ Expect.equals(#S, values.elementAt(1).simpleName);
+ Expect.equals(#T, values.elementAt(2).simpleName);
cm = reflectClass(NoTypeParams);
Expect.equals(cm.typeVariables.length, 0);
}
diff --git a/tests/lib/mirrors/closure_mirror_find_in_context_test.dart b/tests/lib/mirrors/closure_mirror_find_in_context_test.dart
new file mode 100644
index 0000000..b26a140
--- /dev/null
+++ b/tests/lib/mirrors/closure_mirror_find_in_context_test.dart
@@ -0,0 +1,151 @@
+// 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.
+
+import "dart:mirrors";
+
+import "stringify.dart";
+
+import "package:expect/expect.dart";
+
+import "closure_mirror_import1.dart";
+import "closure_mirror_import1.dart" as imp1;
+import "closure_mirror_import1.dart" as imp1_hidden
+ hide globalVariableInImport, StaticClass;
+import "closure_mirror_import2.dart" as imp2;
+
+var globalVariable = "globalVariable";
+
+globalFoo() => 17;
+
+class S {
+ static staticFooInS() => "staticFooInS";
+ static var staticInS = "staticInS";
+ var instanceInS = "instanceInS";
+}
+
+class C extends S {
+ static staticFooInC() => "staticFooInC";
+ static var staticInC = "staticInC";
+ var instanceInC = "instanceInC";
+
+ foo() => null;
+
+ bar() {
+ var x = 7;
+ var instanceInC = 11; // Shadowing the instance field.
+ var y = 3; // Not in context.
+ baz() {
+ if (x) {}
+ if (instanceInC) {}
+ };
+ return reflect(baz);
+ }
+
+ baz() {
+ var instanceInC = null; // Shadowing with a null value.
+ return reflect(() => instanceInC);
+ }
+}
+
+main() {
+ C c = new C();
+ ClosureMirror cm = reflect(c.foo);
+
+ var result;
+
+ result = cm.findInContext(#globalVariable);
+ expect("Instance(value = globalVariable)", result);
+
+ result = cm.findInContext(#globalFoo);
+ Expect.isTrue(result is ClosureMirror);
+ expect("Instance(value = 17)", result.apply(const []));
+
+ result = cm.findInContext(#S.staticInS);
+ expect("Instance(value = staticInS)", result);
+
+ result = cm.findInContext(#staticInS);
+ Expect.isFalse(result is InstanceMirror);
+ Expect.equals(null, result);
+
+ result = cm.findInContext(#staticFooInS);
+ Expect.isTrue(result is ClosureMirror);
+ expect("Instance(value = staticFooInS)", result.apply(const []));
+
+ result = cm.findInContext(#C.staticFooInS);
+ Expect.isTrue(result is ClosureMirror);
+ expect("Instance(value = staticFooInS)", result.apply(const []));
+
+ result = cm.findInContext(#C.staticInC);
+ expect("Instance(value = staticInC)", result);
+
+ result = cm.findInContext(#staticInC);
+ expect("Instance(value = staticInC)", result);
+
+ result = cm.findInContext(#C.staticFooInC);
+ Expect.isTrue(result is ClosureMirror);
+ expect("Instance(value = staticFooInC)", result.apply(const []));
+
+ result = cm.findInContext(#staticFooInC);
+ Expect.isTrue(result is ClosureMirror);
+ expect("Instance(value = staticFooInC)", result.apply(const []));
+
+ result = cm.findInContext(#instanceInC);
+ expect("Instance(value = instanceInC)", result);
+
+ result = cm.findInContext(#instanceInS);
+ expect("Instance(value = instanceInS)", result);
+
+ result = cm.findInContext(#globalVariableInImport1);
+ expect("Instance(value = globalVariableInImport1)", result);
+
+ result = cm.findInContext(#StaticClass.staticField);
+ expect("Instance(value = staticField)", result);
+
+ result = cm.findInContext(#StaticClass.staticFunctionInStaticClass);
+ Expect.isTrue(result is ClosureMirror);
+ expect("Instance(value = staticFunctionInStaticClass)",
+ result.apply(const []));
+
+ result = cm.findInContext(#imp1.StaticClass.staticFunctionInStaticClass);
+ Expect.isTrue(result is ClosureMirror);
+ expect("Instance(value = staticFunctionInStaticClass)",
+ result.apply(const []));
+
+ result = cm.findInContext(#imp1.globalVariableInImport1);
+ expect("Instance(value = globalVariableInImport1)", result);
+
+ result = cm.findInContext(#imp2.globalVariableInImport);
+ Expect.isFalse(result is InstanceMirror);
+ Expect.equals(null, result);
+
+ result = cm.findInContext(#imp1.StaticClass.staticField);
+ expect("Instance(value = staticField)", result);
+
+ result = cm.findInContext(#imp1_hidden.StaticClass.staticField);
+ Expect.isFalse(result is InstanceMirror);
+ Expect.equals(null, result);
+
+ result = cm.findInContext(#firstGlobalVariableInImport2);
+ expect("Instance(value = firstGlobalVariableInImport2)", result);
+
+ result = cm.findInContext(#secondGlobalVariableInImport2);
+ Expect.isFalse(result is InstanceMirror);
+ Expect.equals(null, result);
+
+ result = cm.findInContext(#imp2.secondGlobalVariableInImport2);
+ expect("Instance(value = secondGlobalVariableInImport2)", result);
+
+ result = c.bar().findInContext(#x);
+ expect("Instance(value = 7)", result);
+
+ result = c.bar().findInContext(#instanceInC);
+ expect("Instance(value = 11)", result);
+
+ result = c.bar().findInContext(#y);
+ Expect.isFalse(result is InstanceMirror);
+ Expect.equals(null, result);
+
+ result = c.baz().findInContext(#instanceInC);
+ expect("Instance(value = <null>)", result);
+}
diff --git a/tests/lib/mirrors/closure_mirror_import1.dart b/tests/lib/mirrors/closure_mirror_import1.dart
new file mode 100644
index 0000000..2788b94
--- /dev/null
+++ b/tests/lib/mirrors/closure_mirror_import1.dart
@@ -0,0 +1,15 @@
+// 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.
+
+export "closure_mirror_import2.dart" show firstGlobalVariableInImport2;
+
+var globalVariableInImport1 = "globalVariableInImport1";
+
+globalFunctionInImport1() => "globalFunctionInImport1";
+
+class StaticClass {
+ static var staticField = "staticField";
+
+ static staticFunctionInStaticClass() => "staticFunctionInStaticClass";
+}
diff --git a/tests/lib/mirrors/closure_mirror_import2.dart b/tests/lib/mirrors/closure_mirror_import2.dart
new file mode 100644
index 0000000..a14b7a9
--- /dev/null
+++ b/tests/lib/mirrors/closure_mirror_import2.dart
@@ -0,0 +1,6 @@
+// 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.
+
+var firstGlobalVariableInImport2 = "firstGlobalVariableInImport2";
+var secondGlobalVariableInImport2 = "secondGlobalVariableInImport2";
diff --git a/tests/lib/mirrors/equality_test.dart b/tests/lib/mirrors/equality_test.dart
index 1b3b798..77e724f 100644
--- a/tests/lib/mirrors/equality_test.dart
+++ b/tests/lib/mirrors/equality_test.dart
@@ -99,14 +99,14 @@
{'currentMirrorSystem().voidType' : currentMirrorSystem().voidType, /// 02: ok
'thisLibrary.functions[#subroutine].returnType' : /// 02: ok
- thisLibrary.functions[const Symbol('subroutine')].returnType}, /// 02: ok
+ thisLibrary.functions[#subroutine].returnType}, /// 02: ok
{'currentMirrorSystem().dynamicType' : currentMirrorSystem().dynamicType,
'thisLibrary.functions[#main].returnType' :
- thisLibrary.functions[const Symbol('main')].returnType},
+ thisLibrary.functions[#main].returnType},
{'reflectClass(A)' : reflectClass(A),
- 'thisLibrary.classes[#A]' : thisLibrary.classes[const Symbol('A')],
+ 'thisLibrary.classes[#A]' : thisLibrary.classes[#A],
'reflect(new A<int>()).type.originalDeclaration' :
reflect(new A<int>()).type.originalDeclaration},
@@ -114,7 +114,7 @@
'reflect(new A<int>()).type' : reflect(new A<int>()).type}, /// 02: ok
{'reflectClass(B)' : reflectClass(B),
- 'thisLibrary.classes[#B]' : thisLibrary.classes[const Symbol('B')],
+ 'thisLibrary.classes[#B]' : thisLibrary.classes[#B],
'reflect(new B()).type' : reflect(new B()).type},
{'thisLibrary' : thisLibrary,
diff --git a/tests/lib/mirrors/fake_function_test.dart b/tests/lib/mirrors/fake_function_test.dart
index a824be0..058a567 100644
--- a/tests/lib/mirrors/fake_function_test.dart
+++ b/tests/lib/mirrors/fake_function_test.dart
@@ -15,12 +15,12 @@
Expect.isTrue(new WannabeFunction() is Function);
ClosureMirror cm = reflect(new WannabeFunction());
- Expect.equals(7, cm.invoke(const Symbol("call"), [3,4]).reflectee);
- Expect.throws(() => cm.invoke(const Symbol("call"), [3]),
+ Expect.equals(7, cm.invoke(#call, [3,4]).reflectee);
+ Expect.throws(() => cm.invoke(#call, [3]),
(e) => e is NoSuchMethodError,
"Wrong arity");
- Expect.equals(49, cm.invoke(const Symbol("method"), [7]).reflectee);
- Expect.throws(() => cm.invoke(const Symbol("method"), [3, 4]),
+ Expect.equals(49, cm.invoke(#method, [7]).reflectee);
+ Expect.throws(() => cm.invoke(#method, [3, 4]),
(e) => e is NoSuchMethodError,
"Wrong arity");
Expect.equals(7, cm.apply([3,4]).reflectee);
@@ -29,18 +29,16 @@
"Wrong arity");
MethodMirror mm = cm.function;
- Expect.equals(const Symbol("call"), mm.simpleName);
- Expect.equals(reflectClass(WannabeFunction),
- mm.owner);
+ Expect.equals(#call, mm.simpleName);
+ Expect.equals(reflectClass(WannabeFunction), mm.owner);
Expect.isTrue(mm.isRegularMethod);
- Expect.equals(const Symbol("int"), mm.returnType.simpleName);
- Expect.equals(const Symbol("int"), mm.parameters[0].type.simpleName);
- Expect.equals(const Symbol("int"), mm.parameters[1].type.simpleName);
+ Expect.equals(#int, mm.returnType.simpleName);
+ Expect.equals(#int, mm.parameters[0].type.simpleName);
+ Expect.equals(#int, mm.parameters[1].type.simpleName);
ClassMirror km = cm.type;
Expect.equals(reflectClass(WannabeFunction), km);
- Expect.equals(const Symbol("WannabeFunction"), km.simpleName);
- Expect.equals(mm, km.members[const Symbol("call")]);
- Expect.setEquals([const Symbol("call"), const Symbol("method")],
- km.members.keys);
+ Expect.equals(#WannabeFunction, km.simpleName);
+ Expect.equals(mm, km.members[#call]);
+ Expect.setEquals([#call, #method], km.members.keys);
}
diff --git a/tests/lib/mirrors/function_type_mirror_test.dart b/tests/lib/mirrors/function_type_mirror_test.dart
index 4376c83..f712d73 100644
--- a/tests/lib/mirrors/function_type_mirror_test.dart
+++ b/tests/lib/mirrors/function_type_mirror_test.dart
@@ -13,11 +13,11 @@
main() {
TypedefMirror tm = reflectClass(FooFunction);
FunctionTypeMirror ftm = tm.referent;
- Expect.equals(const Symbol("void"), ftm.returnType.simpleName);
- Expect.equals(const Symbol("int"), ftm.parameters[0].type.simpleName);
- Expect.equals(const Symbol("double"), ftm.parameters[1].type.simpleName);
+ Expect.equals(const Symbol('void'), ftm.returnType.simpleName);
+ Expect.equals(#int, ftm.parameters[0].type.simpleName);
+ Expect.equals(#double, ftm.parameters[1].type.simpleName);
ClosureMirror cm = reflect(bar);
ftm = cm.type;
- Expect.equals(const Symbol("dynamic"), ftm.returnType.simpleName);
- Expect.equals(const Symbol("int"), ftm.parameters[0].type.simpleName);
+ Expect.equals(#dynamic, ftm.returnType.simpleName);
+ Expect.equals(#int, ftm.parameters[0].type.simpleName);
}
diff --git a/tests/lib/mirrors/generics_test.dart b/tests/lib/mirrors/generics_test.dart
index d1f05d2..7f6386a 100644
--- a/tests/lib/mirrors/generics_test.dart
+++ b/tests/lib/mirrors/generics_test.dart
@@ -9,6 +9,7 @@
import 'package:expect/expect.dart';
class A<T> {}
+class Z<T> {}
class B extends A {} // Same as class B extends A<dynamic>.
class C extends A
<num, int> // TODO(zarah): Should be "01: static warning".
@@ -18,6 +19,7 @@
class F<R> extends A<int> {}
class G {}
class H<A,B,C> {}
+class I extends G {}
typeParameters(mirror, parameterNames) {
Expect.listEquals(parameterNames.map((n) => new Symbol(n)).toList(),
@@ -30,13 +32,16 @@
main() {
// Declarations.
- typeParameters(reflectClass(A), ['T']); /// 01: ok
- typeParameters(reflectClass(B), []); /// 01: ok
- typeParameters(reflectClass(C), []); /// 01: ok
- typeParameters(reflectClass(D), []); /// 01: ok
- typeParameters(reflectClass(E), ['S']); /// 01: ok
- typeParameters(reflectClass(F), ['R']); /// 01: ok
- typeParameters(reflectClass(G), []); /// 01: ok
+ typeParameters(reflectClass(A), ['T']);
+ typeParameters(reflectClass(G), []);
+ typeParameters(reflectClass(B), []);
+ typeParameters(reflectClass(C), []);
+ typeParameters(reflectClass(D), []);
+ typeParameters(reflectClass(E), ['S']);
+ typeParameters(reflectClass(F), ['R']);
+ typeParameters(reflectClass(G), []);
+ typeParameters(reflectClass(H), ['A', 'B', 'C']);
+ typeParameters(reflectClass(I), []);
typeArguments(reflectClass(A), []);
typeArguments(reflectClass(B), []);
@@ -45,6 +50,8 @@
typeArguments(reflectClass(E), []);
typeArguments(reflectClass(F), []);
typeArguments(reflectClass(G), []);
+ typeArguments(reflectClass(H), []);
+ typeArguments(reflectClass(I), []);
Expect.isTrue(reflectClass(A).isOriginalDeclaration);
Expect.isTrue(reflectClass(B).isOriginalDeclaration);
@@ -53,6 +60,8 @@
Expect.isTrue(reflectClass(E).isOriginalDeclaration);
Expect.isTrue(reflectClass(F).isOriginalDeclaration);
Expect.isTrue(reflectClass(G).isOriginalDeclaration);
+ Expect.isTrue(reflectClass(H).isOriginalDeclaration);
+ Expect.isTrue(reflectClass(I).isOriginalDeclaration);
Expect.equals(reflectClass(A), reflectClass(A).originalDeclaration);
Expect.equals(reflectClass(B), reflectClass(B).originalDeclaration);
@@ -61,16 +70,19 @@
Expect.equals(reflectClass(E), reflectClass(E).originalDeclaration);
Expect.equals(reflectClass(F), reflectClass(F).originalDeclaration);
Expect.equals(reflectClass(G), reflectClass(G).originalDeclaration);
+ Expect.equals(reflectClass(H), reflectClass(H).originalDeclaration);
+ Expect.equals(reflectClass(I), reflectClass(I).originalDeclaration);
// Instantiations.
- typeParameters(reflect(new A<num>()).type, ['T']); /// 01: ok
- typeParameters(reflect(new B<num>()).type, []); /// 01: ok
- typeParameters(reflect(new C()).type, []); /// 01: ok
- typeParameters(reflect(new D()).type, []); /// 01: ok
- typeParameters(reflect(new E()).type, ['S']); /// 01: ok
- typeParameters(reflect(new F<num>()).type, ['R']); /// 01: ok
- typeParameters(reflect(new G()).type, []); /// 01: ok
- typeParameters(reflect(new H()).type, ['A', 'B', 'C']); /// 01: ok
+ typeParameters(reflect(new A<num>()).type, ['T']);
+ typeParameters(reflect(new B<num>()).type, []);
+ typeParameters(reflect(new C()).type, []);
+ typeParameters(reflect(new D()).type, []);
+ typeParameters(reflect(new E()).type, ['S']);
+ typeParameters(reflect(new F<num>()).type, ['R']);
+ typeParameters(reflect(new G()).type, []);
+ typeParameters(reflect(new H()).type, ['A', 'B', 'C']);
+ typeParameters(reflect(new I()).type, []);
var numMirror = reflectClass(num);
var dynamicMirror = currentMirrorSystem().dynamicType;
@@ -89,6 +101,7 @@
typeArguments(reflect(new G()).type, []);
typeArguments(reflect(new H<dynamic, num, dynamic>()).type, /// 01: ok
[dynamicMirror, numMirror, dynamicMirror]); /// 01: ok
+ typeArguments(reflect(new I()).type, []);
Expect.isFalse(reflect(new A<num>()).type.isOriginalDeclaration);
Expect.isTrue(reflect(new B()).type.isOriginalDeclaration);
@@ -98,6 +111,7 @@
Expect.isFalse(reflect(new F<num>()).type.isOriginalDeclaration);
Expect.isTrue(reflect(new G()).type.isOriginalDeclaration);
Expect.isFalse(reflect(new H()).type.isOriginalDeclaration); /// 01: ok
+ Expect.isTrue(reflect(new I()).type.isOriginalDeclaration);
Expect.equals(reflectClass(A),
reflect(new A<num>()).type.originalDeclaration);
@@ -115,6 +129,8 @@
reflect(new G()).type.originalDeclaration);
Expect.equals(reflectClass(H),
reflect(new H()).type.originalDeclaration);
+ Expect.equals(reflectClass(I),
+ reflect(new I()).type.originalDeclaration);
Expect.notEquals(reflect(new A<num>()).type,
reflect(new A<num>()).type.originalDeclaration);
@@ -132,6 +148,8 @@
reflect(new G()).type.originalDeclaration);
Expect.notEquals(reflect(new H()).type, /// 01: ok
reflect(new H()).type.originalDeclaration); /// 01: ok
+ Expect.equals(reflect(new I()).type,
+ reflect(new I()).type.originalDeclaration);
// Library members are all uninstantaited generics or non-generics.
currentMirrorSystem().libraries.values.forEach((libraryMirror) {
@@ -143,4 +161,11 @@
}
});
});
+
+ Expect.equals(reflectClass(A).typeVariables[0].owner, reflectClass(A));
+ Expect.equals(reflectClass(Z).typeVariables[0].owner, reflectClass(Z));
+ Expect.notEquals(reflectClass(A).typeVariables[0],
+ reflectClass(Z).typeVariables[0]);
+ Expect.equals(reflectClass(A).typeVariables[0],
+ reflectClass(A).typeVariables[0]);
}
diff --git a/tests/lib/mirrors/inherit_field_test.dart b/tests/lib/mirrors/inherit_field_test.dart
index d61e3bb..8fc1e5e 100644
--- a/tests/lib/mirrors/inherit_field_test.dart
+++ b/tests/lib/mirrors/inherit_field_test.dart
@@ -19,7 +19,7 @@
void main() {
expect('Variable(s(field) in s(Foo))',
- reflectClass(Foo).members[new Symbol('field')]);
+ reflectClass(Foo).members[#field]);
expect('<null>',
- reflectClass(Bar).members[new Symbol('field')]);
+ reflectClass(Bar).members[#field]);
}
diff --git a/tests/lib/mirrors/intercepted_cache_test.dart b/tests/lib/mirrors/intercepted_cache_test.dart
index 58dff6d..818906d 100644
--- a/tests/lib/mirrors/intercepted_cache_test.dart
+++ b/tests/lib/mirrors/intercepted_cache_test.dart
@@ -18,8 +18,8 @@
main() {
Expect.equals(
- 1, reflect(new Foo(1)).getField(const Symbol('length')).reflectee);
+ 1, reflect(new Foo(1)).getField(#length).reflectee);
Expect.equals(
- 2, reflect(new Foo(2)).getField(const Symbol('length')).reflectee);
- Expect.equals(0, reflect([]).getField(const Symbol('length')).reflectee);
+ 2, reflect(new Foo(2)).getField(#length).reflectee);
+ Expect.equals(0, reflect([]).getField(#length).reflectee);
}
diff --git a/tests/lib/mirrors/invoke_closurization_test.dart b/tests/lib/mirrors/invoke_closurization_test.dart
new file mode 100644
index 0000000..28cdd56
--- /dev/null
+++ b/tests/lib/mirrors/invoke_closurization_test.dart
@@ -0,0 +1,67 @@
+// 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 test.invoke_closurization_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+import 'invoke_test.dart';
+
+class C {
+ instanceMethod(x, y, z) => '$x+$y+$z';
+ static staticFunction(x, y, z) => '$x-$y-$z';
+}
+libraryFunction(x, y, z) => '$x:$y:$z';
+
+testSync() {
+ var result;
+
+ C c = new C();
+ InstanceMirror im = reflect(c);
+ result = im.getField(#instanceMethod);
+ Expect.isTrue(result.reflectee is Function, "Should be closure");
+ Expect.equals("A+B+C", result.reflectee('A', 'B', 'C'));
+
+ ClassMirror cm = reflectClass(C);
+ result = cm.getField(#staticFunction);
+ Expect.isTrue(result.reflectee is Function, "Should be closure");
+ Expect.equals("A-B-C", result.reflectee('A', 'B', 'C'));
+
+ LibraryMirror lm = cm.owner;
+ result = lm.getField(#libraryFunction);
+ Expect.isTrue(result.reflectee is Function, "Should be closure");
+ Expect.equals("A:B:C", result.reflectee('A', 'B', 'C'));
+}
+
+testAsync() {
+ var future;
+
+ C c = new C();
+ InstanceMirror im = reflect(c);
+ future = im.getFieldAsync(#instanceMethod);
+ expectValueThen(future, (result) {
+ Expect.isTrue(result.reflectee is Function, "Should be closure");
+ Expect.equals("A+B+C", result.reflectee('A', 'B', 'C'));
+ });
+
+ ClassMirror cm = reflectClass(C);
+ future = cm.getFieldAsync(#staticFunction);
+ expectValueThen(future, (result) {
+ Expect.isTrue(result.reflectee is Function, "Should be closure");
+ Expect.equals("A-B-C", result.reflectee('A', 'B', 'C'));
+ });
+
+ LibraryMirror lm = cm.owner;
+ future = lm.getFieldAsync(#libraryFunction);
+ expectValueThen(future, (result) {
+ Expect.isTrue(result.reflectee is Function, "Should be closure");
+ Expect.equals("A:B:C", result.reflectee('A', 'B', 'C'));
+ });
+}
+
+main() {
+ testSync();
+ testAsync();
+}
diff --git a/tests/lib/mirrors/invoke_named_test.dart b/tests/lib/mirrors/invoke_named_test.dart
index 2405ba8..da0b54b 100644
--- a/tests/lib/mirrors/invoke_named_test.dart
+++ b/tests/lib/mirrors/invoke_named_test.dart
@@ -6,9 +6,14 @@
import 'dart:mirrors';
+import 'dart:async' show Future;
+
import 'package:expect/expect.dart';
import 'invoke_test.dart';
+// TODO(ahe): Remove this variable (http://dartbug.com/12863).
+bool isDart2js = false;
+
class C {
a(a, {b:'B', c}) => "$a-$b-$c";
b({a:'A', b, c}) => "$a-$b-$c";
@@ -58,7 +63,7 @@
Expect.throws(() => om.invoke(const Symbol('a'), ['X'], {const Symbol('undef') : 'Y'}),
isNoSuchMethodError,
'Unmatched named argument');
-
+
result = om.invoke(const Symbol('b'), []);
Expect.equals('A-null-null', result.reflectee);
result = om.invoke(const Symbol('b'), [], {const Symbol('a') : 'X'});
@@ -137,8 +142,8 @@
expectError(future, isNoSuchMethodError, 'Extra positional arguments');
future = om.invokeAsync(const Symbol('a'), ['X'], {const Symbol('undef') : 'Y'});
expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
+
+
future = om.invokeAsync(const Symbol('b'), []);
expectValueThen(future, (result) {
Expect.equals('A-null-null', result.reflectee);
@@ -156,7 +161,6 @@
future = om.invokeAsync(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'});
expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
future = om.invokeAsync(const Symbol('c'), ['X']);
expectValueThen(future, (result) {
Expect.equals('X-null-C', result.reflectee);
@@ -198,7 +202,6 @@
future = om.invokeAsync(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'});
expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
future = om.invokeAsync(const Symbol('e'), ['X', 'Y', 'Z']);
expectValueThen(future, (result) {
Expect.equals('X-Y-Z', result.reflectee);
@@ -230,7 +233,7 @@
Expect.throws(() => cm.newInstance(const Symbol(''), ['X'], {const Symbol('undef') : 'Y'}),
isNoSuchMethodError,
'Unmatched named argument');
-
+
result = cm.newInstance(const Symbol('b'), []);
Expect.equals('A-null-null', result.reflectee.field);
result = cm.newInstance(const Symbol('b'), [], {const Symbol('a') : 'X'});
@@ -310,8 +313,8 @@
expectError(future, isNoSuchMethodError, 'Extra positional arguments');
future = cm.newInstanceAsync(const Symbol(''), ['X'], {const Symbol('undef') : 'Y'});
expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
+
+
future = cm.newInstanceAsync(const Symbol('b'), []);
expectValueThen(future, (result) {
Expect.equals('A-null-null', result.reflectee.field);
@@ -404,7 +407,7 @@
Expect.throws(() => cm.apply(['X'], {const Symbol('undef') : 'Y'}),
isNoSuchMethodError,
'Unmatched named argument');
-
+
cm = reflect(b);
result = cm.apply([]);
Expect.equals('A-null-null', result.reflectee);
@@ -489,7 +492,7 @@
expectError(future, isNoSuchMethodError, 'Extra positional arguments');
future = cm.applyAsync(['X'], {const Symbol('undef') : 'Y'});
expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
+
cm = reflect(b);
future = cm.applyAsync([]);
@@ -568,17 +571,23 @@
}
main() {
- testSyncInvoke(reflect(new C())); // InstanceMirror
- testSyncInvoke(reflectClass(D)); // ClassMirror
- testSyncInvoke(reflectClass(D).owner); // LibraryMirror
+ isDart2js = true; /// 01: ok
- testAsyncInvoke(reflect(new C())); // InstanceMirror
- testAsyncInvoke(reflectClass(D)); // ClassMirror
- testAsyncInvoke(reflectClass(D).owner); // LibraryMirror
+ testSyncInvoke(reflect(new C())); // InstanceMirror
+ if (!isDart2js) testSyncInvoke(reflectClass(D)); // ClassMirror
+ LibraryMirror lib = reflectClass(D).owner;
+ if (!isDart2js) testSyncInvoke(lib); // LibraryMirror
+
+ testAsyncInvoke(reflect(new C())); // InstanceMirror
+
+ if (isDart2js) return;
+
+ testAsyncInvoke(reflectClass(D)); // ClassMirror
+ testAsyncInvoke(lib); // LibraryMirror
testSyncNewInstance();
testAsyncNewInstance();
-
+
testSyncApply();
testAsyncApply();
}
diff --git a/tests/lib/mirrors/invoke_test.dart b/tests/lib/mirrors/invoke_test.dart
index 3ba6732..2d225d1 100644
--- a/tests/lib/mirrors/invoke_test.dart
+++ b/tests/lib/mirrors/invoke_test.dart
@@ -6,6 +6,8 @@
import 'dart:mirrors';
+import 'dart:async' show Future;
+
import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart";
@@ -18,7 +20,7 @@
set setter(v) => field = 'set $v';
method(x, y, z) => '$x+$y+$z';
toString() => 'a C';
-
+
noSuchMethod(invocation) => 'DNU';
static var staticField = 'initial';
@@ -34,7 +36,7 @@
Future expectValueThen(Future future, Function onValue) {
asyncStart();
- wrappedOnValue(resultIn) {
+ wrappedOnValue(resultIn) {
var resultOut = onValue(resultIn);
asyncEnd();
return resultOut;
@@ -47,7 +49,7 @@
Future expectError(Future future, Function errorPredicate, String reason) {
asyncStart();
- onValue(result) {
+ onValue(result) {
Expect.fail("Error expected ($reason)");
}
onError(e) {
@@ -273,7 +275,7 @@
}).then((result) {
Expect.equals('sbar', result.reflectee);
Expect.equals('sbar', C.staticField);
- return cm.setFieldAsync(const Symbol('staticField'), im);;
+ return cm.setFieldAsync(const Symbol('staticField'), im);
}).then((result) {
Expect.equals(im.reflectee, result.reflectee);
Expect.equals(c, C.staticField);
diff --git a/tests/lib/mirrors/invoke_throws_test.dart b/tests/lib/mirrors/invoke_throws_test.dart
index f3198a1..40fa99c 100644
--- a/tests/lib/mirrors/invoke_throws_test.dart
+++ b/tests/lib/mirrors/invoke_throws_test.dart
@@ -35,36 +35,36 @@
main() {
InstanceMirror im = reflect(new Class.noException());
- Expect.throws(() => im.getField(const Symbol('getter')),
+ Expect.throws(() => im.getField(#getter),
(e) => e is MyException);
- Expect.throws(() => im.setField(const Symbol('setter'), ['arg']),
+ Expect.throws(() => im.setField(#setter, ['arg']),
(e) => e is MyException);
- Expect.throws(() => im.invoke(const Symbol('method'), []),
+ Expect.throws(() => im.invoke(#method, []),
(e) => e is MyException);
- Expect.throws(() => im.invoke(const Symbol('triggerNoSuchMethod'), []),
+ Expect.throws(() => im.invoke(#triggerNoSuchMethod, []),
(e) => e is MyException);
ClassMirror cm = reflectClass(Class);
- Expect.throws(() => cm.getField(const Symbol('staticGetter')),
+ Expect.throws(() => cm.getField(#staticGetter),
(e) => e is MyException);
- Expect.throws(() => cm.setField(const Symbol('staticSetter'), ['arg']),
+ Expect.throws(() => cm.setField(#staticSetter, ['arg']),
(e) => e is MyException);
- Expect.throws(() => cm.invoke(const Symbol('staticFunction'), []),
+ Expect.throws(() => cm.invoke(#staticFunction, []),
(e) => e is MyException);
- Expect.throws(() => cm.newInstance(const Symbol('generative'), []),
+ Expect.throws(() => cm.newInstance(#generative, []),
(e) => e is MyException);
- Expect.throws(() => cm.newInstance(const Symbol('redirecting'), []),
+ Expect.throws(() => cm.newInstance(#redirecting, []),
(e) => e is MyException);
- Expect.throws(() => cm.newInstance(const Symbol('faktory'), []),
+ Expect.throws(() => cm.newInstance(#faktory, []),
(e) => e is MyException);
- Expect.throws(() => cm.newInstance(const Symbol('redirectingFactory'), []),
+ Expect.throws(() => cm.newInstance(#redirectingFactory, []),
(e) => e is MyException);
LibraryMirror lm = reflectClass(Class).owner;
- Expect.throws(() => lm.getField(const Symbol('libraryGetter')),
+ Expect.throws(() => lm.getField(#libraryGetter),
(e) => e is MyException);
- Expect.throws(() => lm.setField(const Symbol('librarySetter'), ['arg']),
+ Expect.throws(() => lm.setField(#librarySetter, ['arg']),
(e) => e is MyException);
- Expect.throws(() => lm.invoke(const Symbol('libraryFunction'), []),
+ Expect.throws(() => lm.invoke(#libraryFunction, []),
(e) => e is MyException);
}
diff --git a/tests/lib/mirrors/is_odd_test.dart b/tests/lib/mirrors/is_odd_test.dart
index c9fdde1..0dc1655 100644
--- a/tests/lib/mirrors/is_odd_test.dart
+++ b/tests/lib/mirrors/is_odd_test.dart
@@ -11,6 +11,6 @@
import 'package:expect/expect.dart';
main() {
- Expect.isTrue(reflect(1).getField(new Symbol('isOdd')).reflectee);
- Expect.isFalse(reflect(2).getField(new Symbol('isOdd')).reflectee);
+ Expect.isTrue(reflect(1).getField(#isOdd).reflectee);
+ Expect.isFalse(reflect(2).getField(#isOdd).reflectee);
}
diff --git a/tests/lib/mirrors/lazy_static_test.dart b/tests/lib/mirrors/lazy_static_test.dart
index d82316b..6420e8e 100644
--- a/tests/lib/mirrors/lazy_static_test.dart
+++ b/tests/lib/mirrors/lazy_static_test.dart
@@ -19,15 +19,15 @@
void main() {
expect('Variable(s(hello) in s(Foo), static)',
- reflectClass(Foo).members[new Symbol('hello')]);
- var reflectee = reflectClass(Foo).getField(new Symbol('hello')).reflectee;
+ reflectClass(Foo).members[#hello]);
+ var reflectee = reflectClass(Foo).getField(#hello).reflectee;
Expect.stringEquals('a, c', reflectee.keys.join(', '));
// Call the lazy getter twice as different things probably happen in the
// underlying implementation.
- reflectee = reflectClass(Foo).getField(new Symbol('hello')).reflectee;
+ reflectee = reflectClass(Foo).getField(#hello).reflectee;
Expect.stringEquals('a, c', reflectee.keys.join(', '));
var value = 'fisk';
Foo.hello = value;
- reflectee = reflectClass(Foo).getField(new Symbol('hello')).reflectee;
+ reflectee = reflectClass(Foo).getField(#hello).reflectee;
Expect.identical(value, reflectee);
}
diff --git a/tests/lib/mirrors/libraries_test.dart b/tests/lib/mirrors/libraries_test.dart
index 6639083..c9613d6 100644
--- a/tests/lib/mirrors/libraries_test.dart
+++ b/tests/lib/mirrors/libraries_test.dart
@@ -18,9 +18,9 @@
LibraryMirror mirrorsLibrary = libraries[Uri.parse('dart:mirrors')];
Expect.isNotNull(mirrorsLibrary, 'mirrorsLibrary is null');
- ClassMirror cls = mirrorsLibrary.classes[const Symbol('LibraryMirror')];
+ ClassMirror cls = mirrorsLibrary.classes[#LibraryMirror];
Expect.isNotNull(cls, 'cls is null');
- Expect.equals(const Symbol('dart.mirrors.LibraryMirror'), cls.qualifiedName);
+ Expect.equals(#dart.mirrors.LibraryMirror, cls.qualifiedName);
Expect.equals(reflectClass(LibraryMirror), cls);
}
diff --git a/tests/lib/mirrors/library_metadata2_test.dart b/tests/lib/mirrors/library_metadata2_test.dart
index 4604f7e..55d3b68 100644
--- a/tests/lib/mirrors/library_metadata2_test.dart
+++ b/tests/lib/mirrors/library_metadata2_test.dart
@@ -6,10 +6,11 @@
import 'library_metadata2_lib1.dart';
-import 'library_metadata2_lib2.dart'; /// 01: compile-time error
+import 'library_metadata2_lib2.dart'; /// 01: runtime error
void main() {
for (var library in currentMirrorSystem().libraries.values) {
- print(library.metadata);
+ print(library.metadata); // Processing @MyConst() in lib2 results in a
+ // runtime error here.
}
}
diff --git a/tests/lib/mirrors/library_metadata_test.dart b/tests/lib/mirrors/library_metadata_test.dart
index 5bb0cec..d6f54a5 100644
--- a/tests/lib/mirrors/library_metadata_test.dart
+++ b/tests/lib/mirrors/library_metadata_test.dart
@@ -11,8 +11,8 @@
main() {
MirrorSystem mirrors = currentMirrorSystem();
- checkMetadata(mirrors.findLibrary(const Symbol('test.library_metadata_test')).first,
+ checkMetadata(mirrors.findLibrary(#test.library_metadata_test).first,
[string, symbol]);
- checkMetadata(mirrors.findLibrary(const Symbol('test.metadata_test')).first,
+ checkMetadata(mirrors.findLibrary(#test.metadata_test).first,
[]);
}
diff --git a/tests/lib/mirrors/metadata_constructed_constant_test.dart b/tests/lib/mirrors/metadata_constructed_constant_test.dart
index df74ff1..0d5e01e 100644
--- a/tests/lib/mirrors/metadata_constructed_constant_test.dart
+++ b/tests/lib/mirrors/metadata_constructed_constant_test.dart
@@ -21,6 +21,6 @@
main() {
var value =
- reflectClass(Foo).methods[const Symbol("m")].metadata.single.reflectee;
+ reflectClass(Foo).methods[#m].metadata.single.reflectee;
Expect.stringEquals('ConstructedConstant($StateError)', '$value');
}
diff --git a/tests/lib/mirrors/metadata_test.dart b/tests/lib/mirrors/metadata_test.dart
index 164a5ae..2608746 100644
--- a/tests/lib/mirrors/metadata_test.dart
+++ b/tests/lib/mirrors/metadata_test.dart
@@ -53,18 +53,18 @@
MirrorSystem mirrors = currentMirrorSystem();
ClassMirror myClassMirror = reflectClass(MyClass);
checkMetadata(myClassMirror, [symbol, string]);
- LibraryMirror lib = mirrors.findLibrary(const Symbol('test.metadata_test')).first;
- MethodMirror function = lib.functions[const Symbol('main')];
+ LibraryMirror lib = mirrors.findLibrary(#test.metadata_test).first;
+ MethodMirror function = lib.functions[#main];
checkMetadata(function, [symbol, string, symbol]);
- MethodMirror method = myClassMirror.methods[const Symbol('myMethod')];
+ MethodMirror method = myClassMirror.methods[#myMethod];
checkMetadata(method, [string, symbol, string]);
- method = myClassMirror.methods[const Symbol('myOtherMethod')];
+ method = myClassMirror.methods[#myOtherMethod];
checkMetadata(method, []);
- VariableMirror xMirror = myClassMirror.variables[const Symbol('x')];
+ VariableMirror xMirror = myClassMirror.variables[#x];
checkMetadata(xMirror, [hest, hest, symbol]);
- VariableMirror yMirror = myClassMirror.variables[const Symbol('y')];
+ VariableMirror yMirror = myClassMirror.variables[#y];
checkMetadata(yMirror, []);
// TODO(ahe): Test local functions.
diff --git a/tests/lib/mirrors/method_mirror_properties_test.dart b/tests/lib/mirrors/method_mirror_properties_test.dart
index c29c6f8..834871f 100644
--- a/tests/lib/mirrors/method_mirror_properties_test.dart
+++ b/tests/lib/mirrors/method_mirror_properties_test.dart
@@ -48,30 +48,30 @@
checkKinds(closureMirror.function,
[true, false, false, false, false]);
var libraryMirror = reflectClass(C).owner;
- checkKinds(libraryMirror.getters[const Symbol("topGetter")],
+ checkKinds(libraryMirror.getters[#topGetter],
[true, false, true, false, false]);
checkKinds(libraryMirror.setters[const Symbol("topSetter=")],
[true, false, false, true, false]);
var classMirror;
classMirror = reflectClass(C);
- checkKinds(classMirror.members[const Symbol("foo")],
+ checkKinds(classMirror.members[#foo],
[true, false, false, false, false]);
- checkKinds(classMirror.members[const Symbol("priv")],
+ checkKinds(classMirror.members[#priv],
[false, false, true, false, false]);
checkKinds(classMirror.members[const Symbol("priv=")],
[false, false, false, true, false]);
- checkKinds(classMirror.constructors[const Symbol("C")],
+ checkKinds(classMirror.constructors[#C],
[false, false, false, false, true]);
- checkKinds(classMirror.constructors[const Symbol("C.other")],
+ checkKinds(classMirror.constructors[#C.other],
[false, false, false, false, true]);
- checkKinds(classMirror.constructors[const Symbol("C.other2")],
+ checkKinds(classMirror.constructors[#C.other2],
[false, false, false, false, true]);
classMirror = reflectClass(AbstractC);
- checkKinds(classMirror.constructors[const Symbol("AbstractC")],
+ checkKinds(classMirror.constructors[#AbstractC],
[false, false, false, false, true]);
- checkKinds(classMirror.members[const Symbol("bar")],
+ checkKinds(classMirror.members[#bar],
[false, true, false, false, false]);
- checkKinds(classMirror.members[const Symbol("priv")],
+ checkKinds(classMirror.members[#priv],
[false, true, true, false, false]);
checkKinds(classMirror.members[const Symbol("priv=")],
[false, true, false, true, false]);
diff --git a/tests/lib/mirrors/method_mirror_returntype_test.dart b/tests/lib/mirrors/method_mirror_returntype_test.dart
index 5d13ece..cd525bb 100644
--- a/tests/lib/mirrors/method_mirror_returntype_test.dart
+++ b/tests/lib/mirrors/method_mirror_returntype_test.dart
@@ -23,27 +23,27 @@
mm = reflect(intFunc).function;
Expect.equals(true, mm.returnType is TypeMirror);
- Expect.equals(const Symbol("int"), mm.returnType.simpleName);
+ Expect.equals(#int, mm.returnType.simpleName);
Expect.equals(true, mm.returnType.owner is LibraryMirror);
mm = reflect(dynamicFunc1).function;
Expect.equals(true, mm.returnType is TypeMirror);
- Expect.equals(const Symbol("dynamic"), mm.returnType.simpleName);
+ Expect.equals(#dynamic, mm.returnType.simpleName);
mm = reflect(dynamicFunc2).function;
Expect.equals(true, mm.returnType is TypeMirror);
- Expect.equals(const Symbol("dynamic"), mm.returnType.simpleName);
+ Expect.equals(#dynamic, mm.returnType.simpleName);
mm = reflect(voidFunc).function;
Expect.equals(true, mm.returnType is TypeMirror);
Expect.equals(const Symbol("void"), mm.returnType.simpleName);
ClassMirror cm = reflectClass(C);
- mm = cm.members[const Symbol("getE")];
+ mm = cm.members[#getE];
Expect.equals(true, mm.returnType is TypeMirror);
// The spec for this is ambigious and needs to be updated before it is clear
// what has to be returned.
//Expect.equals("E", _n(mm.returnType.simpleName));
Expect.equals(true, mm.owner is ClassMirror);
- Expect.equals(const Symbol("C"), mm.owner.simpleName);
+ Expect.equals(#C, mm.owner.simpleName);
}
diff --git a/tests/lib/mirrors/method_mirror_source_test.dart b/tests/lib/mirrors/method_mirror_source_test.dart
index fcbc7c6..094e36d 100644
--- a/tests/lib/mirrors/method_mirror_source_test.dart
+++ b/tests/lib/mirrors/method_mirror_source_test.dart
@@ -55,35 +55,35 @@
main() {
// Top-level members
LibraryMirror lib = reflectClass(C).owner;
- expectSource(lib.members[const Symbol("foo1")],
+ expectSource(lib.members[#foo1],
"foo1() {}");
- expectSource(lib.members[const Symbol("x")],
+ expectSource(lib.members[#x],
"int get x => 42;");
expectSource(lib.members[const Symbol("x=")],
"set x(value) { }");
// Class members
ClassMirror cm = reflectClass(C);
- expectSource(cm.members[const Symbol("foo")],
+ expectSource(cm.members[#foo],
"static dynamic foo() {\n"
" // Happy foo.\n"
" }");
- expectSource(cm.members[const Symbol("bar")],
+ expectSource(cm.members[#bar],
"void bar() { /* Not so happy bar. */ }");
- expectSource(cm.members[const Symbol("someX")],
+ expectSource(cm.members[#someX],
"num get someX =>\n"
" 181;");
expectSource(cm.members[const Symbol("someX=")],
"set someX(v) {\n"
" // Discard this one.\n"
" }");
- expectSource(cm.constructors[const Symbol("C")],
+ expectSource(cm.constructors[#C],
"C(this._x, y)\n"
" : _y = y,\n"
" super();");
- expectSource(cm.constructors[const Symbol("C.other")],
+ expectSource(cm.constructors[#C.other],
"factory C.other(num z) {}");
- expectSource(cm.constructors[const Symbol("C.other3")],
+ expectSource(cm.constructors[#C.other3],
"factory C.other3() = C.other2;");
// Closures
diff --git a/tests/lib/mirrors/mirrors_resolve_fields_test.dart b/tests/lib/mirrors/mirrors_resolve_fields_test.dart
index f513ae2..cb3044f 100644
--- a/tests/lib/mirrors/mirrors_resolve_fields_test.dart
+++ b/tests/lib/mirrors/mirrors_resolve_fields_test.dart
@@ -17,6 +17,6 @@
main() {
var mirrors = currentMirrorSystem();
var classMirror = reflectClass(A);
- var instanceMirror = classMirror.newInstance(const Symbol(''),[]);
+ var instanceMirror = classMirror.newInstance(const Symbol(''), []);
Expect.equals(A._STATE_INITIAL, instanceMirror.reflectee._state);
}
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index b86acd6..b0d1b84 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -239,12 +239,12 @@
expect(classMirror.simpleName, equals(const Symbol('Class')));
expect(classMirror.qualifiedName, equals(const Symbol('MirrorsTest.Class')));
- if (!isDart2js) { // TODO(ahe): Implement this in dart2js.
- TypeVariableMirror typeVariable = classMirror.typeVariables.single;
- expect(typeVariable.simpleName, equals(const Symbol('T')));
- expect(typeVariable.qualifiedName,
- equals(const Symbol('MirrorsTest.Class.T')));
+ TypeVariableMirror typeVariable = classMirror.typeVariables.single;
+ expect(typeVariable.simpleName, equals(const Symbol('T')));
+ expect(typeVariable.qualifiedName,
+ equals(const Symbol('MirrorsTest.Class.T')));
+ if (!isDart2js) { // TODO(ahe): Implement this in dart2js.
expect(typedefMirror.simpleName, equals(const Symbol('Typedef')));
expect(typedefMirror.qualifiedName,
equals(const Symbol('MirrorsTest.Typedef')));
diff --git a/tests/lib/mirrors/null_test.dart b/tests/lib/mirrors/null_test.dart
index 10b92f3..72f5e23 100644
--- a/tests/lib/mirrors/null_test.dart
+++ b/tests/lib/mirrors/null_test.dart
@@ -10,25 +10,25 @@
main() {
InstanceMirror nullMirror = reflect(null);
- Expect.isTrue(nullMirror.getField(const Symbol('hashCode')).reflectee is int);
+ Expect.isTrue(nullMirror.getField(#hashCode).reflectee is int);
Expect.equals(null.hashCode,
- nullMirror.getField(const Symbol('hashCode')).reflectee);
+ nullMirror.getField(#hashCode).reflectee);
Expect.equals('Null',
- nullMirror.getField(const Symbol('runtimeType')).reflectee
+ nullMirror.getField(#runtimeType).reflectee
.toString());
- Expect.isTrue(nullMirror.invoke(const Symbol('=='), [null]).reflectee);
- Expect.isFalse(nullMirror.invoke(const Symbol('=='), [new Object()])
+ Expect.isTrue(nullMirror.invoke(#==, [null]).reflectee);
+ Expect.isFalse(nullMirror.invoke(#==, [new Object()])
.reflectee);
Expect.equals('null',
- nullMirror.invoke(const Symbol('toString'), []).reflectee);
- Expect.throws(() => nullMirror.invoke(const Symbol('notDefined'), []),
+ nullMirror.invoke(#toString, []).reflectee);
+ Expect.throws(() => nullMirror.invoke(#notDefined, []),
(e) => e is NoSuchMethodError,
'noSuchMethod');
ClassMirror NullMirror = nullMirror.type;
Expect.equals(reflectClass(Null), NullMirror);
- Expect.equals(const Symbol('Null'), NullMirror.simpleName);
- Expect.equals(const Symbol('Object'), NullMirror.superclass.simpleName);
+ Expect.equals(#Null, NullMirror.simpleName);
+ Expect.equals(#Object, NullMirror.superclass.simpleName);
Expect.equals(null, NullMirror.superclass.superclass);
Expect.listEquals([], NullMirror.superinterfaces);
Expect.equals(currentMirrorSystem().libraries[Uri.parse('dart:core')],
diff --git a/tests/lib/mirrors/parameter_metadata_test.dart b/tests/lib/mirrors/parameter_metadata_test.dart
index 987e059..f27a149 100644
--- a/tests/lib/mirrors/parameter_metadata_test.dart
+++ b/tests/lib/mirrors/parameter_metadata_test.dart
@@ -9,7 +9,7 @@
import 'metadata_test.dart';
const m1 = 'm1';
-const m2 = const Symbol('m2');
+const m2 = #m2;
const m3 = const CustomAnnotation(3);
class CustomAnnotation {
@@ -33,23 +33,23 @@
main() {
ClassMirror cm = reflectClass(B);
- checkMetadata(cm.constructors[const Symbol('B.foo')].parameters[0], []);
+ checkMetadata(cm.constructors[#B.foo].parameters[0], []);
- checkMetadata(cm.constructors[const Symbol('B.bar')].parameters[0], [m3, m2]);
- checkMetadata(cm.constructors[const Symbol('B.bar')].parameters[1], []);
+ checkMetadata(cm.constructors[#B.bar].parameters[0], [m3, m2]);
+ checkMetadata(cm.constructors[#B.bar].parameters[1], []);
- checkMetadata(cm.members[const Symbol('baz')].parameters[0], [m1]);
- checkMetadata(cm.members[const Symbol('baz')].parameters[1], [m2]);
- checkMetadata(cm.members[const Symbol('baz')].parameters[2], [m3]);
+ checkMetadata(cm.members[#baz].parameters[0], [m1]);
+ checkMetadata(cm.members[#baz].parameters[1], [m2]);
+ checkMetadata(cm.members[#baz].parameters[2], [m3]);
- checkMetadata(cm.members[const Symbol('qux')].parameters[0], []);
- checkMetadata(cm.members[const Symbol('qux')].parameters[1], [m3, m2, m1]);
+ checkMetadata(cm.members[#qux].parameters[0], []);
+ checkMetadata(cm.members[#qux].parameters[1], [m3, m2, m1]);
- checkMetadata(cm.members[const Symbol('quux')].parameters[0], []);
- checkMetadata(cm.members[const Symbol('quux')].parameters[1], []);
+ checkMetadata(cm.members[#quux].parameters[0], []);
+ checkMetadata(cm.members[#quux].parameters[1], []);
- checkMetadata(cm.members[const Symbol('corge')].parameters[0], [m1]);
- checkMetadata(cm.members[const Symbol('corge')].parameters[1], [m2]);
+ checkMetadata(cm.members[#corge].parameters[0], [m1]);
+ checkMetadata(cm.members[#corge].parameters[1], [m2]);
checkMetadata(cm.members[const Symbol('x=')].parameters[0], [m2]);
}
diff --git a/tests/lib/mirrors/parameter_test.dart b/tests/lib/mirrors/parameter_test.dart
index 5e3518b..ac395bd 100644
--- a/tests/lib/mirrors/parameter_test.dart
+++ b/tests/lib/mirrors/parameter_test.dart
@@ -47,19 +47,17 @@
ClassMirror cm = reflectClass(B);
Map<Symbol, MethodMirror> constructors = cm.constructors;
- List<Symbol> constructorKeys = [
- const Symbol('B'), const Symbol('B.bar'), const Symbol('B.baz'),
- const Symbol('B.foo'), const Symbol('B.quux'), const Symbol('B.qux'),
- const Symbol('B.corge')];
+ List<Symbol> constructorKeys =
+ [#B, #B.bar, #B.baz, #B.foo, #B.quux, #B.qux, #B.corge];
Expect.setEquals(constructorKeys, constructors.keys);
- MethodMirror unnamedConstructor = constructors[const Symbol('B')];
+ MethodMirror unnamedConstructor = constructors[#B];
expect('Method(s(B) in s(B), constructor)', unnamedConstructor);
expect('[]', unnamedConstructor.parameters);
expect('Class(s(B) in s(test.parameter_test), top-level)',
unnamedConstructor.returnType);
- MethodMirror fooConstructor = constructors[const Symbol('B.foo')];
+ MethodMirror fooConstructor = constructors[#B.foo];
expect('Method(s(B.foo) in s(B), constructor)', fooConstructor);
expect('[Parameter(s(x) in s(B.foo),'
' type = Class(s(int) in s(dart.core), top-level))]',
@@ -67,7 +65,7 @@
expect('Class(s(B) in s(test.parameter_test), top-level)',
fooConstructor.returnType);
- MethodMirror barConstructor = constructors[const Symbol('B.bar')];
+ MethodMirror barConstructor = constructors[#B.bar];
expect('Method(s(B.bar) in s(B), constructor)', barConstructor);
expect('[Parameter(s(z) in s(B.bar),'
' type = Class(s(int) in s(dart.core), top-level)), '
@@ -80,7 +78,7 @@
// dart2js stops testing here.
return; /// 01: ok
- MethodMirror bazConstructor = constructors[const Symbol('B.baz')];
+ MethodMirror bazConstructor = constructors[#B.baz];
expect('Method(s(B.baz) in s(B), constructor)', bazConstructor);
expect('[Parameter(s(x) in s(B.baz), final,'
' type = Class(s(int) in s(dart.core), top-level)), '
@@ -92,7 +90,7 @@
expect('Class(s(B) in s(test.parameter_test), top-level)',
bazConstructor.returnType);
- MethodMirror quxConstructor = constructors[const Symbol('B.qux')];
+ MethodMirror quxConstructor = constructors[#B.qux];
expect('Method(s(B.qux) in s(B), constructor)', quxConstructor);
expect('[Parameter(s(x) in s(B.qux),'
' type = Class(s(int) in s(dart.core), top-level)), '
@@ -103,7 +101,7 @@
expect('Class(s(B) in s(test.parameter_test), top-level)',
quxConstructor.returnType);
- MethodMirror quuxConstructor = constructors[const Symbol('B.quux')];
+ MethodMirror quuxConstructor = constructors[#B.quux];
expect('Method(s(B.quux) in s(B), constructor)', quuxConstructor);
expect('[Parameter(s(x) in s(B.quux),'
' type = Class(s(int) in s(dart.core), top-level)), '
@@ -114,7 +112,7 @@
expect('Class(s(B) in s(test.parameter_test), top-level)',
quuxConstructor.returnType);
- MethodMirror corgeConstructor = constructors[const Symbol('B.corge')];
+ MethodMirror corgeConstructor = constructors[#B.corge];
expect('Method(s(B.corge) in s(B), constructor)', corgeConstructor);
expect('[Parameter(s(x) in s(B.corge), optional, named,'
' value = Instance(value = 51),'
@@ -126,7 +124,7 @@
expect('Class(s(B) in s(test.parameter_test), top-level)',
corgeConstructor.returnType);
- MethodMirror xGetter = cm.getters[const Symbol('x')];
+ MethodMirror xGetter = cm.getters[#x];
expect('Method(s(x) in s(B), getter)', xGetter);
expect('[]', xGetter.parameters);
@@ -136,21 +134,21 @@
' type = Type(s(dynamic), top-level))]',
xSetter.parameters);
- MethodMirror grault = cm.members[const Symbol("grault")];
+ MethodMirror grault = cm.members[#grault];
expect('Method(s(grault) in s(B))', grault);
expect('[Parameter(s(x) in s(grault), optional,'
' type = Class(s(int) in s(dart.core), top-level))]',
grault.parameters);
expect('Instance(value = <null>)', grault.parameters[0].defaultValue);
- MethodMirror garply = cm.members[const Symbol("garply")];
+ MethodMirror garply = cm.members[#garply];
expect('Method(s(garply) in s(B))', garply);
expect('[Parameter(s(y) in s(garply), optional, named,'
' type = Class(s(int) in s(dart.core), top-level))]',
garply.parameters);
expect('Instance(value = <null>)', garply.parameters[0].defaultValue);
- MethodMirror waldo = cm.members[const Symbol("waldo")];
+ MethodMirror waldo = cm.members[#waldo];
expect('Method(s(waldo) in s(B))', waldo);
expect('[Parameter(s(z) in s(waldo),'
' type = Class(s(int) in s(dart.core), top-level))]',
@@ -159,7 +157,7 @@
cm = reflectClass(C);
- MethodMirror fooInC = cm.members[const Symbol("foo")];
+ MethodMirror fooInC = cm.members[#foo];
expect('Method(s(foo) in s(C))', fooInC);
expect('[Parameter(s(a) in s(foo),'
' type = Class(s(int) in s(dart.core), top-level)), '
@@ -168,7 +166,7 @@
' upperBound = Class(s(int) in s(dart.core), top-level)))]',
fooInC.parameters);
- MethodMirror barInC = cm.members[const Symbol("bar")];
+ MethodMirror barInC = cm.members[#bar];
expect('Method(s(bar) in s(C))', barInC);
expect('[Parameter(s(a) in s(bar),'
' type = TypeVariable(s(S) in s(C),'
diff --git a/tests/lib/mirrors/redirecting_factory_test.dart b/tests/lib/mirrors/redirecting_factory_test.dart
index 7da01a2..1d0059f 100644
--- a/tests/lib/mirrors/redirecting_factory_test.dart
+++ b/tests/lib/mirrors/redirecting_factory_test.dart
@@ -60,25 +60,25 @@
Expect.equals(2, instanceMirror.reflectee.field);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryNoOptional'), [8, 6]);
+ #redirectingFactoryNoOptional, [8, 6]);
Expect.equals(2, instanceMirror.reflectee.field);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryUnnamedOptional'), [43, 1]);
+ #redirectingFactoryUnnamedOptional, [43, 1]);
Expect.equals(42, instanceMirror.reflectee.field);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryMoreUnnamedOptional'), [43, 1]);
+ #redirectingFactoryMoreUnnamedOptional, [43, 1]);
Expect.equals(40, instanceMirror.reflectee.field);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryStringIntTypeParameters'), [43, 1]);
+ #redirectingFactoryStringIntTypeParameters, [43, 1]);
Expect.equals(42, instanceMirror.reflectee.field);
Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
Expect.isFalse(instanceMirror.reflectee is Class<int, String>);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryStringTypeParameters'), [43, 1]);
+ #redirectingFactoryStringTypeParameters, [43, 1]);
Expect.equals(42, instanceMirror.reflectee.field);
Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
Expect.isTrue(instanceMirror.reflectee is Class<String, String>);
@@ -89,34 +89,34 @@
if (isDart2js) return;
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryUnnamedOptional'), [43]);
+ #redirectingFactoryUnnamedOptional, [43]);
Expect.equals(1, instanceMirror.reflectee.field);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryNamedOptional'), [43]);
+ #redirectingFactoryNamedOptional, [43]);
Expect.equals(1, instanceMirror.reflectee.field);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryNamedOptional'),
+ #redirectingFactoryNamedOptional,
[43],
- new Map()..[const Symbol('b')] = 1);
+ new Map()..[#b] = 1);
Expect.equals(42, instanceMirror.reflectee.field);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryMoreNamedOptional'),
+ #redirectingFactoryMoreNamedOptional,
[43],
- new Map()..[const Symbol('b')] = 1);
+ new Map()..[#b] = 1);
Expect.equals(40, instanceMirror.reflectee.field);
classMirror = reflect(new Class<String, int>(42)).type;
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryTypeParameters'), [43, 1]);
+ #redirectingFactoryTypeParameters, [43, 1]);
Expect.equals(42, instanceMirror.reflectee.field);
Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
Expect.isFalse(instanceMirror.reflectee is Class<int, String>);
instanceMirror = classMirror.newInstance(
- const Symbol('redirectingFactoryReversedTypeParameters'), [43, 1]);
+ #redirectingFactoryReversedTypeParameters, [43, 1]);
Expect.equals(42, instanceMirror.reflectee.field);
Expect.isTrue(instanceMirror.reflectee is Class<int, String>);
Expect.isFalse(instanceMirror.reflectee is Class<String, int>);
diff --git a/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart b/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart
index 4d18126..b19bfc2 100644
--- a/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart
+++ b/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart
@@ -18,7 +18,7 @@
print(instance);
bool threw = false;
try {
- m.newInstance(const Symbol('noSuchConstructor'), []);
+ m.newInstance(#noSuchConstructor, []);
throw 'Expected an exception';
} on NoSuchMethodError catch (e) {
print(e);
diff --git a/tests/lib/mirrors/return_type_test.dart b/tests/lib/mirrors/return_type_test.dart
index ebc208a..6b90061 100644
--- a/tests/lib/mirrors/return_type_test.dart
+++ b/tests/lib/mirrors/return_type_test.dart
@@ -28,10 +28,10 @@
'h: Method(s(h) in s(B)), '
'i: Method(s(i) in s(B))}', methods);
- var f = methods[const Symbol('f')];
- var g = methods[const Symbol('g')];
- var h = methods[const Symbol('h')];
- var i = methods[const Symbol('i')];
+ var f = methods[#f];
+ var g = methods[#g];
+ var h = methods[#h];
+ var i = methods[#i];
expect('Type(s(dynamic), top-level)', f.returnType);
expect('Class(s(int) in s(dart.core), top-level)', g.returnType);
diff --git a/tests/lib/mirrors/to_string_test.dart b/tests/lib/mirrors/to_string_test.dart
index ac58b2a..e8e4e30 100644
--- a/tests/lib/mirrors/to_string_test.dart
+++ b/tests/lib/mirrors/to_string_test.dart
@@ -20,7 +20,7 @@
expect("TypeMirror on 'dynamic'", mirrors.dynamicType);
expect("TypeMirror on 'void'", mirrors.voidType);
expect("LibraryMirror on 'test.to_string_test'",
- mirrors.findLibrary(const Symbol('test.to_string_test')).single);
+ mirrors.findLibrary(#test.to_string_test).single);
expect("InstanceMirror on 1", reflect(1));
expect("ClassMirror on 'Foo'", reflectClass(Foo));
expect("VariableMirror on 'field'",
diff --git a/tests/lib/mirrors/top_level_accessors_test.dart b/tests/lib/mirrors/top_level_accessors_test.dart
index b535415..232b47c 100644
--- a/tests/lib/mirrors/top_level_accessors_test.dart
+++ b/tests/lib/mirrors/top_level_accessors_test.dart
@@ -19,10 +19,10 @@
main() {
LibraryMirror library = currentMirrorSystem()
- .findLibrary(const Symbol('test.top_level_accessors_test')).single;
+ .findLibrary(#test.top_level_accessors_test).single;
field = 42;
- Expect.equals(42, library.getField(const Symbol('accessor')).reflectee);
- Expect.equals(87, library.setField(const Symbol('accessor'), 87).reflectee);
+ Expect.equals(42, library.getField(#accessor).reflectee);
+ Expect.equals(87, library.setField(#accessor, 87).reflectee);
Expect.equals(87, field);
- Expect.equals(87, library.getField(const Symbol('accessor')).reflectee);
+ Expect.equals(87, library.getField(#accessor).reflectee);
}
diff --git a/tests/lib/mirrors/typearguments_mirror_test.dart b/tests/lib/mirrors/typearguments_mirror_test.dart
index 855d842..3e6ec36 100644
--- a/tests/lib/mirrors/typearguments_mirror_test.dart
+++ b/tests/lib/mirrors/typearguments_mirror_test.dart
@@ -23,8 +23,6 @@
Expect.equals(cm, reflectClass(Foo));
Expect.equals(cm, reflectClass((new Foo().runtimeType)));
- print((reflect(new Foo()).type).runtimeType);
- print(cm.runtimeType);
Expect.equals(cm1, reflect(new Foo<String>()).type);
expect('[]', cm.typeArguments);
diff --git a/tests/lib/mirrors/typevariable_mirror_metadata_test.dart b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
index 9994988..aa59870 100644
--- a/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
+++ b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
@@ -9,7 +9,7 @@
import "metadata_test.dart";
const m1 = 'm1';
-const m2 = const Symbol('m2');
+const m2 = #m2;
const m3 = 3;
class A <S, @m1 @m2 T> {
@@ -35,12 +35,12 @@
checkMetadata(cm.typeVariables[0], []);
checkMetadata(cm.typeVariables[1], [m1, m2]);
// Check for conflicts.
- checkMetadata(cm.methods[const Symbol('T')], [m3]);
+ checkMetadata(cm.methods[#T], [m3]);
cm = reflectClass(B);
checkMetadata(cm.typeVariables[0], [m3]);
// Check for conflicts.
- checkMetadata(cm.members[const Symbol('T')], [m1, m2]);
+ checkMetadata(cm.members[#T], [m1, m2]);
TypedefMirror tm = reflectClass(Predicate);
FunctionTypeMirror ftm = tm.referent;
diff --git a/tests/lib/typed_data/float32x4_clamp_test.dart b/tests/lib/typed_data/float32x4_clamp_test.dart
new file mode 100644
index 0000000..816fe0d
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_clamp_test.dart
@@ -0,0 +1,39 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10
+
+// Library tag to be able to run in html test framework.
+library float32x4_clamp_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void testClampLowerGreaterThanUpper() {
+ Float32x4 l = new Float32x4(1.0, 1.0, 1.0, 1.0);
+ Float32x4 u = new Float32x4(-1.0, -1.0, -1.0, -1.0);
+ Float32x4 z = new Float32x4.zero();
+ Float32x4 a = z.clamp(l, u);
+ Expect.equals(a.x, 1.0);
+ Expect.equals(a.y, 1.0);
+ Expect.equals(a.z, 1.0);
+ Expect.equals(a.w, 1.0);
+}
+
+void testClamp() {
+ Float32x4 l = new Float32x4(-1.0, -1.0, -1.0, -1.0);
+ Float32x4 u = new Float32x4(1.0, 1.0, 1.0, 1.0);
+ Float32x4 z = new Float32x4.zero();
+ Float32x4 a = z.clamp(l, u);
+ Expect.equals(a.x, 0.0);
+ Expect.equals(a.y, 0.0);
+ Expect.equals(a.z, 0.0);
+ Expect.equals(a.w, 0.0);
+}
+
+main() {
+ for (int i = 0; i < 2000; i++) {
+ testClampLowerGreaterThanUpper();
+ testClamp();
+ }
+}
diff --git a/tests/lib/typed_data/float32x4_test.dart b/tests/lib/typed_data/float32x4_test.dart
index 41401b8..bc1b164 100644
--- a/tests/lib/typed_data/float32x4_test.dart
+++ b/tests/lib/typed_data/float32x4_test.dart
@@ -232,13 +232,13 @@
testConversions() {
var m = new Uint32x4(0x3F800000, 0x40000000, 0x40400000, 0x40800000);
- var n = m.toFloat32x4();
+ var n = new Float32x4.fromUint32x4Bits(m);
Expect.equals(1.0, n.x);
Expect.equals(2.0, n.y);
Expect.equals(3.0, n.z);
Expect.equals(4.0, n.w);
n = new Float32x4(5.0, 6.0, 7.0, 8.0);
- m = n.toUint32x4();
+ m = new Uint32x4.fromFloat32x4Bits(n);
Expect.equals(0x40A00000, m.x);
Expect.equals(0x40C00000, m.y);
Expect.equals(0x40E00000, m.z);
@@ -246,16 +246,16 @@
// Flip sign using bit-wise operators.
n = new Float32x4(9.0, 10.0, 11.0, 12.0);
m = new Uint32x4(0x80000000, 0x80000000, 0x80000000, 0x80000000);
- var nMask = n.toUint32x4();
+ var nMask = new Uint32x4.fromFloat32x4Bits(n);
nMask = nMask ^ m; // flip sign.
- n = nMask.toFloat32x4();
+ n = new Float32x4.fromUint32x4Bits(nMask);
Expect.equals(-9.0, n.x);
Expect.equals(-10.0, n.y);
Expect.equals(-11.0, n.z);
Expect.equals(-12.0, n.w);
- nMask = n.toUint32x4();
+ nMask = new Uint32x4.fromFloat32x4Bits(n);
nMask = nMask ^ m; // flip sign.
- n = nMask.toFloat32x4();
+ n = new Float32x4.fromUint32x4Bits(nMask);
Expect.equals(9.0, n.x);
Expect.equals(10.0, n.y);
Expect.equals(11.0, n.z);
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index 1c5f860..3b8c383 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -528,15 +528,15 @@
file.create().then((ignore) {
file.open(mode: WRITE).then((RandomAccessFile openedFile) {
// Write bytes from 0 to 7.
- openedFile.writeFrom([0], 0, 1);
- openedFile.writeFrom(const [1], 0, 1);
- openedFile.writeFrom(new MyListOfOneElement(2), 0, 1);
+ openedFile.writeFromSync([0], 0, 1);
+ openedFile.writeFromSync(const [1], 0, 1);
+ openedFile.writeFromSync(new MyListOfOneElement(2), 0, 1);
var x = 12345678901234567890123456789012345678901234567890;
var y = 12345678901234567890123456789012345678901234567893;
- openedFile.writeFrom([y - x], 0, 1);
- openedFile.writeFrom([260], 0, 1); // 260 = 256 + 4 = 0x104.
- openedFile.writeFrom(const [261], 0, 1);
- openedFile.writeFrom(new MyListOfOneElement(262), 0, 1);
+ openedFile.writeFromSync([y - x], 0, 1);
+ openedFile.writeFromSync([260], 0, 1); // 260 = 256 + 4 = 0x104.
+ openedFile.writeFromSync(const [261], 0, 1);
+ openedFile.writeFromSync(new MyListOfOneElement(262), 0, 1);
x = 12345678901234567890123456789012345678901234567890;
y = 12345678901234567890123456789012345678901234568153;
openedFile.writeFrom([y - x], 0, 1).then((ignore) {
diff --git a/tests/standalone/io/https_bad_certificate_client.dart b/tests/standalone/io/https_bad_certificate_client.dart
index 4fe59a9..62e9039 100644
--- a/tests/standalone/io/https_bad_certificate_client.dart
+++ b/tests/standalone/io/https_bad_certificate_client.dart
@@ -38,10 +38,11 @@
HttpClient client = new HttpClient();
- var testFutures = [];
+ var testFutures = []; // The three async getUrl calls run simultaneously.
testFutures.add(client.getUrl(Uri.parse('https://$HOST_NAME:$port/$result'))
.then((HttpClientRequest request) {
- expect(false);
+ expect(result == 'true'); // The session cache may keep the session.
+ return request.close();
}, onError: (e) {
expect(e is HandshakeException || e is SocketException);
}));
@@ -50,7 +51,7 @@
testFutures.add(client.getUrl(Uri.parse('https://$HOST_NAME:$port/$result'))
.then((HttpClientRequest request) {
expect(result == 'true');
- request.close().then((result) { });
+ return request.close();
}, onError: (e) {
if (result == 'false') expect (e is HandshakeException ||
e is SocketException);
@@ -62,7 +63,8 @@
client.badCertificateCallback = null;
testFutures.add(client.getUrl(Uri.parse('https://$HOST_NAME:$port/$result'))
.then((HttpClientRequest request) {
- expect(false);
+ expect(result == 'true'); // The session cache may keep the session.
+ return request.close();
}, onError: (e) {
expect(e is HandshakeException || e is SocketException);
}));
diff --git a/tests/standalone/io/internet_address_test.dart b/tests/standalone/io/internet_address_test.dart
index 22c4a66..fd4b358 100644
--- a/tests/standalone/io/internet_address_test.dart
+++ b/tests/standalone/io/internet_address_test.dart
@@ -32,6 +32,18 @@
Expect.equals("::", any6.address);
}
+void testLookup() {
+ InternetAddress.lookup("127.0.0.1").then((addresses) {
+ Expect.equals(1, addresses.length);
+ Expect.equals("127.0.0.1", addresses[0].address);
+ });
+
+ InternetAddress.lookup("::1").then((addresses) {
+ Expect.equals(1, addresses.length);
+ Expect.equals("::1", addresses[0].address);
+ });
+}
+
void testReverseLookup() {
InternetAddress.lookup('localhost').then((addrs) {
addrs.first.reverse().then((addr) {
@@ -50,5 +62,6 @@
void main() {
testDefaultAddresses();
+ testLookup();
testReverseLookup();
}
diff --git a/tests/standalone/io/process_sync_script.dart b/tests/standalone/io/process_sync_script.dart
index d8aab9c..5369124 100644
--- a/tests/standalone/io/process_sync_script.dart
+++ b/tests/standalone/io/process_sync_script.dart
@@ -4,6 +4,7 @@
//
// Utility script to generate some output on stdout and stderr.
+import "dart:async";
import "dart:math";
import "dart:io";
@@ -20,5 +21,7 @@
stdout.write(stdoutBlock);
stderr.write(stderrBlock);
}
- exit(int.parse(options.arguments[3]));
+ Future.wait([stdout.close(), stderr.close()]).then((_) {
+ exit(int.parse(options.arguments[3]));
+ });
}
diff --git a/tests/standalone/io/process_sync_test.dart b/tests/standalone/io/process_sync_test.dart
index 04bc59f..55af831 100644
--- a/tests/standalone/io/process_sync_test.dart
+++ b/tests/standalone/io/process_sync_test.dart
@@ -50,10 +50,8 @@
// The buffer size used in process.h.
var kBufferSize = 16 * 1024;
test(1, kBufferSize, kBufferSize, 0);
- test(1, kBufferSize - 1, kBufferSize + 1, 0);
- test(kBufferSize - 1, 1, 1, 0);
- test(kBufferSize, 1, 1, 0);
- test(kBufferSize + 1, 1, 1, 0);
+ test(1, kBufferSize - 1, kBufferSize - 1, 0);
+ test(1, kBufferSize + 1, kBufferSize + 1, 0);
test(10, 10, 10, 1);
test(10, 10, 10, 255);
diff --git a/tests/standalone/io/secure_server_client_certificate_test.dart b/tests/standalone/io/secure_server_client_certificate_test.dart
index b2e3850..12d284d 100644
--- a/tests/standalone/io/secure_server_client_certificate_test.dart
+++ b/tests/standalone/io/secure_server_client_certificate_test.dart
@@ -12,8 +12,8 @@
const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";
-void testClientCertificate() {
- asyncStart();
+Future testClientCertificate() {
+ var completer = new Completer();
SecureServerSocket.bind(HOST_NAME,
0,
CERTIFICATE,
@@ -34,14 +34,15 @@
clientEnd.close();
serverEnd.close();
server.close();
- asyncEnd();
+ completer.complete();
});
});
});
+ return completer.future;
}
-void testRequiredClientCertificate() {
- asyncStart();
+Future testRequiredClientCertificate() {
+ var completer = new Completer();
SecureServerSocket.bind(HOST_NAME,
0,
CERTIFICATE,
@@ -62,53 +63,11 @@
clientEnd.close();
serverEnd.close();
server.close();
- asyncEnd();
+ completer.complete();
});
});
});
-}
-
-void testNoClientCertificate() {
- asyncStart();
- SecureServerSocket.bind(HOST_NAME,
- 0,
- CERTIFICATE,
- requestClientCertificate: true).then((server) {
- var clientEndFuture = SecureSocket.connect(HOST_NAME,
- server.port);
- server.listen((serverEnd) {
- X509Certificate certificate = serverEnd.peerCertificate;
- Expect.isNull(certificate);
- clientEndFuture.then((clientEnd) {
- clientEnd.close();
- serverEnd.close();
- server.close();
- asyncEnd();
- });
- });
- });
-}
-
-void testNoRequiredClientCertificate() {
- asyncStart();
- bool clientError = false;
- SecureServerSocket.bind(HOST_NAME,
- 0,
- CERTIFICATE,
- requireClientCertificate: true).then((server) {
- Future clientDone = SecureSocket.connect(HOST_NAME, server.port)
- .catchError((e) { clientError = true; });
- server.listen((serverEnd) {
- Expect.fail("Got a unverifiable connection");
- },
- onError: (e) {
- clientDone.then((_) {
- Expect.isTrue(clientError);
- server.close();
- asyncEnd();
- });
- });
- });
+ return completer.future;
}
void main() {
@@ -117,8 +76,8 @@
password: 'dartdart',
useBuiltinRoots: false);
- testClientCertificate();
- testRequiredClientCertificate();
- testNoClientCertificate();
- testNoRequiredClientCertificate();
+ asyncStart();
+ testClientCertificate()
+ .then((_) => testRequiredClientCertificate())
+ .then((_) => asyncEnd());
}
diff --git a/tests/standalone/io/secure_server_client_no_certificate_test.dart b/tests/standalone/io/secure_server_client_no_certificate_test.dart
new file mode 100644
index 0000000..6891e5d
--- /dev/null
+++ b/tests/standalone/io/secure_server_client_no_certificate_test.dart
@@ -0,0 +1,70 @@
+// 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.
+
+import "dart:async";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "package:path/path.dart";
+
+const HOST_NAME = "localhost";
+const CERTIFICATE = "localhost_cert";
+
+Future testNoClientCertificate() {
+ var completer = new Completer();
+ SecureServerSocket.bind(HOST_NAME,
+ 0,
+ CERTIFICATE,
+ requestClientCertificate: true).then((server) {
+ var clientEndFuture = SecureSocket.connect(HOST_NAME,
+ server.port);
+ server.listen((serverEnd) {
+ X509Certificate certificate = serverEnd.peerCertificate;
+ Expect.isNull(certificate);
+ clientEndFuture.then((clientEnd) {
+ clientEnd.close();
+ serverEnd.close();
+ server.close();
+ completer.complete();
+ });
+ });
+ });
+ return completer.future;
+}
+
+Future testNoRequiredClientCertificate() {
+ var completer = new Completer();
+ bool clientError = false;
+ SecureServerSocket.bind(HOST_NAME,
+ 0,
+ CERTIFICATE,
+ requireClientCertificate: true).then((server) {
+ Future clientDone = SecureSocket.connect(HOST_NAME, server.port)
+ .catchError((e) { clientError = true; });
+ server.listen((serverEnd) {
+ Expect.fail("Got a unverifiable connection");
+ },
+ onError: (e) {
+ clientDone.then((_) {
+ Expect.isTrue(clientError);
+ server.close();
+ completer.complete();
+ });
+ });
+ });
+ return completer.future;
+}
+
+void main() {
+ String certificateDatabase = join(dirname(Platform.script), 'pkcert');
+ SecureSocket.initialize(database: certificateDatabase,
+ password: 'dartdart',
+ useBuiltinRoots: false);
+
+ asyncStart();
+ testNoRequiredClientCertificate()
+ .then((_) => testNoClientCertificate())
+ .then((_) => asyncEnd());
+}
diff --git a/tests/standalone/io/socket_exception_test.dart b/tests/standalone/io/socket_exception_test.dart
index 2966e85..6381558 100644
--- a/tests/standalone/io/socket_exception_test.dart
+++ b/tests/standalone/io/socket_exception_test.dart
@@ -154,6 +154,7 @@
}
static void clientSocketAddCloseErrorTest() {
+ asyncStart();
ServerSocket.bind("127.0.0.1", 0).then((server) {
var completer = new Completer();
server.listen((socket) {
@@ -179,7 +180,6 @@
client.add(new List.filled(SIZE, 0));
// Destroy other socket now.
completer.complete(null);
- asyncStart();
client.done.then(
(_) {
Expect.fail("Expected error");
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index 5e01f11..4e88e15 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -51,12 +51,12 @@
onTest(testCase);
}
- var testCaseCrash = _makeCrashTestCase("crash", [CRASH]);
- var testCasePass = _makeNormalTestCase("pass", [PASS]);
- var testCaseFail = _makeNormalTestCase("fail", [FAIL]);
- var testCaseTimeout = _makeNormalTestCase("timeout", [TIMEOUT]);
+ var testCaseCrash = _makeCrashTestCase("crash", [Expectation.CRASH]);
+ var testCasePass = _makeNormalTestCase("pass", [Expectation.PASS]);
+ var testCaseFail = _makeNormalTestCase("fail", [Expectation.FAIL]);
+ var testCaseTimeout = _makeNormalTestCase("timeout", [Expectation.TIMEOUT]);
var testCaseFailUnexpected =
- _makeNormalTestCase("fail-unexpected", [PASS]);
+ _makeNormalTestCase("fail-unexpected", [Expectation.PASS]);
enqueueTestCase(testCaseCrash);
enqueueTestCase(testCasePass);
@@ -94,7 +94,7 @@
return new TestCase(name,
[command],
configuration,
- new Set<String>.from(expectations));
+ new Set<Expectation>.from(expectations));
}
}
diff --git a/tests/standalone/io/uri_platform_test.dart b/tests/standalone/io/uri_platform_test.dart
index 599f2a8..cc67760 100644
--- a/tests/standalone/io/uri_platform_test.dart
+++ b/tests/standalone/io/uri_platform_test.dart
@@ -36,4 +36,7 @@
Expect.equals("a/b", new Uri.file("a/b").toFilePath());
Expect.equals("a\\b", new Uri.file("a\\b").toFilePath());
}
+
+ Expect.equals(Uri.base,
+ new Uri.file(Directory.current.path + Platform.pathSeparator));
}
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 31d7a2f..26d3202 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -250,8 +250,8 @@
void testUsePOST() {
+ asyncStart();
createServer().then((server) {
- asyncStart();
server.transform(new WebSocketTransformer()).listen((webSocket) {
Expect.fail("No connection expected");
}, onError: (e) {
@@ -336,7 +336,7 @@
});
}
- testIndivitualUpgrade(int connections) {
+ testIndividualUpgrade(int connections) {
createServer().then((server) {
server.listen((request) {
if (WebSocketTransformer.isUpgradeRequest(request)) {
@@ -402,7 +402,7 @@
testNoUpgrade();
testUsePOST();
testConnections(10, 3002, "Got tired");
- testIndivitualUpgrade(5);
+ testIndividualUpgrade(5);
}
}
@@ -415,7 +415,9 @@
main() {
+ asyncStart();
new SecurityConfiguration(secure: false).runTests();
initializeSSL();
new SecurityConfiguration(secure: true).runTests();
+ asyncEnd();
}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index b8028ab..30a2a3a 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -13,7 +13,7 @@
io/dependency_graph_test: Skip # http/dartbug.com/12449
io/status_file_parser_test: Skip # http/dartbug.com/12449
-package/invalid_uri_test: Fail, OK # Fails intentionally
+package/invalid_uri_test: Fail, OK # CompileTimeErrors intentionally
[ $runtime == vm && $system == windows ]
io/file_system_watcher_test: Pass, Timeout # Issue 13228
@@ -51,11 +51,9 @@
io/directory_non_ascii_test: Pass, Fail
io/process_non_ascii_test: Pass, Fail
-[ $runtime == vm && $system == windows ]
+[ $runtime == vm ]
io/http_server_early_client_close_test: Crash, Pass # Issue 12982
-
-[ $compiler == none && $runtime == vm && $system == windows && $mode == debug ]
-io/secure_socket_bad_data_test: Crash, Pass # co19-roll r576: Please triage this failure
+io/secure_socket_bad_data_test: Crash, Pass # 12982
[ $compiler == none && $runtime == drt ]
typed_data_isolate_test: Skip # This test uses dart:io
@@ -121,7 +119,7 @@
int_array_test: Skip # dart:typed_data support needed.
io/web_socket_protocol_processor_test: Skip # Importing code with external keyword
int_array_load_elimination_test: Skip # This is a VM test
-medium_integer_test: Fail, OK # Test fails with JS number semantics: issue 1533.
+medium_integer_test: RuntimeError, OK # Test fails with JS number semantics: issue 1533.
io/process_exit_negative_test: Fail, OK # relies on a static error that is a warning now.
package/package_isolate_test: Skip # spawnUri does not work in dart2js. See issue 3051
debugger/*: Skip # Do not run standalone vm debugger tests with dart2js.
@@ -131,15 +129,15 @@
http_launch_test: Skip
javascript_int_overflow_test: Skip
javascript_int_overflow_literal_test: Skip
-oom_error_stacktrace_test: Fail, OK # (OOM on JS may produce a stacktrace).
+oom_error_stacktrace_test: RuntimeError, OK # (OOM on JS may produce a stacktrace).
vmservice/*: Skip # Do not run standalone vm service tests with dart2js.
[ $compiler == dart2js && $jscl ]
-assert_test: Fail, OK # Assumes unspecified fields on the AssertionError.
-deoptimization_test: Fail, OK # Requires bigint.
-out_of_memory_test: Fail, OK # d8 handles much larger arrays than Dart VM.
-io/options_test: Fail, OK # Cannot pass options to d8.
+assert_test: RuntimeError, OK # Assumes unspecified fields on the AssertionError.
+deoptimization_test: RuntimeError, OK # Requires bigint.
+out_of_memory_test: RuntimeError, OK # d8 handles much larger arrays than Dart VM.
+io/options_test: CompileTimeError, OK # Cannot pass options to d8.
[ $compiler == dart2js && $runtime == none ]
io/options_test: Fail
diff --git a/tests/standalone/typed_data_test.dart b/tests/standalone/typed_data_test.dart
index 47a1787..99ab2a3 100644
--- a/tests/standalone/typed_data_test.dart
+++ b/tests/standalone/typed_data_test.dart
@@ -143,8 +143,17 @@
testSetRangeHelper(new Uint8ClampedList(3));
}
-void testIndexOutOfRangeHelper(typed_data) {
- List<int> list = const [0, 1, 2, 3];
+class C {
+ final x;
+ C(this.x);
+ operator<(o) => false;
+ operator>=(o) => false;
+ operator*(o) => x;
+}
+
+void testIndexOutOfRangeHelper(typed_data, value) {
+ List<int> list = new List<int>(typed_data.length + 1);
+ for (int i = 0; i < list.length; i++) list[i] = i;
Expect.throws(() {
typed_data.setRange(0, 4, list);
@@ -153,11 +162,36 @@
Expect.throws(() {
typed_data.setRange(3, 4, list);
});
+
+ Expect.throws(() {
+ typed_data[new C(-4000000)] = value;
+ });
+
+ Expect.throws(() {
+ var size = typed_data.elementSizeInBytes;
+ var i = (typed_data.length - 1) * size + 1;
+ typed_data[new C(i)] = value;
+ });
+
+ Expect.throws(() {
+ typed_data[new C(-1)] = value;
+ });
}
void testIndexOutOfRange() {
- testIndexOutOfRangeHelper(new Uint8List(3));
- testIndexOutOfRangeHelper(new Uint8ClampedList(3));
+ testIndexOutOfRangeHelper(new Int8List(3), 0);
+ testIndexOutOfRangeHelper(new Uint8List(3), 0);
+ testIndexOutOfRangeHelper(new Uint8ClampedList(3), 0);
+ testIndexOutOfRangeHelper(new Int16List(3), 0);
+ testIndexOutOfRangeHelper(new Uint16List(3), 0);
+ testIndexOutOfRangeHelper(new Int32List(3), 0);
+ testIndexOutOfRangeHelper(new Uint32List(3), 0);
+ testIndexOutOfRangeHelper(new Int64List(3), 0);
+ testIndexOutOfRangeHelper(new Uint64List(3), 0);
+ testIndexOutOfRangeHelper(new Float32List(3), 0.0);
+ testIndexOutOfRangeHelper(new Float64List(3), 0.0);
+ testIndexOutOfRangeHelper(new Int64List(3), 0);
+ testIndexOutOfRangeHelper(new Uint64List(3), 0);
}
void testIndexOfHelper(list) {
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 34e6ff0..f2e6744 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -19,3 +19,6 @@
[ $system == macos || $system == windows ]
*_layout_test: Skip
+
+[ $compiler == none && $runtime == drt && $system == linux ]
+png_layout_test: Fail # Issue 13540
diff --git a/tools/VERSION b/tools/VERSION
index 67cdb56..fd38c45 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 7
-BUILD 5
-PATCH 3
+BUILD 6
+PATCH 0
diff --git a/tools/create_editor.py b/tools/create_editor.py
index 6c95963..9af3a18 100644
--- a/tools/create_editor.py
+++ b/tools/create_editor.py
@@ -45,7 +45,7 @@
return join(parent, 'ant')
-def ProcessEditorArchive(archive, outDir):
+def ProcessEditorArchive(arch, archive, outDir):
tempDir = join(GetEditorTemp(), 'editor.out')
try:
os.makedirs(tempDir)
@@ -60,6 +60,14 @@
else:
subprocess.call(['unzip', '-q', archive, '-d', tempDir])
+ if arch == 'x64':
+ if utils.GuessOS() == 'macos':
+ inifile = join(tempDir, 'dart', 'DartEditor.app', 'Contents', 'MacOS',
+ 'DartEditor.ini')
+ else:
+ inifile = join(tempDir, 'dart', 'DartEditor.ini')
+ Modify64BitDartEditorIni(inifile)
+
for src in glob.glob(join(tempDir, 'dart', '*')):
shutil.move(src, outDir)
@@ -67,6 +75,17 @@
os.unlink(archive)
+def Modify64BitDartEditorIni(iniFilePath):
+ f = open(iniFilePath, 'r')
+ lines = f.readlines()
+ f.close()
+ lines[lines.index('-Xms40m\n')] = '-Xms256m\n'
+ lines[lines.index('-Xmx1000m\n')] = '-Xmx2000m\n'
+ f = open(iniFilePath, 'w')
+ f.writelines(lines);
+ f.close()
+
+
def GetEditorTemp():
return join(BUILD, 'editor.build.temp')
@@ -188,7 +207,7 @@
archives = glob.glob(join(OUTPUT, '*.zip'))
if archives:
- ProcessEditorArchive(archives[0], OUTPUT)
+ ProcessEditorArchive(arch, archives[0], OUTPUT)
if os.path.exists(GetEditorTemp()):
shutil.rmtree(GetEditorTemp())
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index ecba37c..f70bdfc 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -194,13 +194,13 @@
os.makedirs(join(LIB, 'html'))
- for library in [join('_internal', 'compiler'),
+ for library in [join('_chrome', 'dart2js'), join('_chrome', 'dartium'),
+ join('_internal', 'compiler'),
join('_internal', 'dartdoc'),
join('_internal', 'pub', 'resource'),
join('_internal', 'lib'),
'async', 'collection', '_collection_dev', 'convert',
'core', 'crypto', 'io', 'isolate',
- join('chrome', 'dart2js'), join('chrome', 'dartium'),
join('html', 'dart2js'), join('html', 'dartium'),
join('html', 'html_common'),
join('indexed_db', 'dart2js'), join('indexed_db', 'dartium'),
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 3b969ac..a68c856 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -127,9 +127,6 @@
" */"
],
"members": {
- "createElement": [
- "/// Deprecated: use new Element.tag(tagName) instead."
- ],
"querySelector": [
"/**",
" * Finds the first descendant element of this document that matches the",
@@ -359,6 +356,11 @@
" *",
" * Calling `open` again on a currently active request is equivalent to",
" * calling `abort`.",
+ " *",
+ " * Note: Most simple HTTP requests can be accomplished using the [getString],",
+ " * [request], [requestCrossOrigin], or [postFormData] methods. Use of this",
+ " * `open` method is intended only for more complext HTTP requests where",
+ " * finer-grained control is needed.",
" */"
],
"overrideMimeType": [
@@ -443,6 +445,11 @@
"/**",
" * Send the request with any given `data`.",
" *",
+ " * Note: Most simple HTTP requests can be accomplished using the [getString],",
+ " * [request], [requestCrossOrigin], or [postFormData] methods. Use of this",
+ " * `send` method is intended only for more complext HTTP requests where",
+ " * finer-grained control is needed.",
+ " *",
" * See also:",
" *",
" * * [send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)",
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index ca2ccd0..1e356fe 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -32,6 +32,10 @@
interface Document {
[Suppressed] DOMObject getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
CanvasRenderingContext getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
+ [Custom] Element createElement(DOMString tagName);
+ [Custom] Element createElement(DOMString localName, DOMString typeExtension);
+ [Custom] Element createElementNS(DOMString namespaceURI, DOMString qualifiedName);
+ [Custom] Element createElementNS(DOMString namespaceURI, DOMString qualifiedName, DOMString typeExtension);
};
[Supplemental]
diff --git a/tools/dom/scripts/chromegenerator.py b/tools/dom/scripts/chromegenerator.py
index 73d504c..e537c85 100755
--- a/tools/dom/scripts/chromegenerator.py
+++ b/tools/dom/scripts/chromegenerator.py
@@ -17,10 +17,10 @@
API_DIR = "../../../third_party/chrome/idl/"
# The path to the custom overrides directory, containing override files.
-OVERRIDES_DIR = "../src/chrome/custom_dart/"
+OVERRIDES_DIR = "../src/_chrome/custom_dart/"
# The path to where the generated .dart files should be saved.
-OUTPUT_DIR = "../src/chrome/"
+OUTPUT_DIR = "../src/_chrome/"
# The path to where the output template file is. This file will be populated
# with TEMPLATE_CONTENT, followed by the list of generated .dart files.
@@ -34,7 +34,7 @@
// BSD-style license that can be found in the LICENSE file.
// DO NOT EDIT
-// Auto-generated dart:chrome library.
+// Auto-generated dart:_chrome library.
/// Native wrappers for the Chrome packaged app APIs.
///
@@ -43,7 +43,7 @@
///
/// For more information on these APIs, see the
/// [chrome.* API documentation](http://developer.chrome.com/apps/api_index.html).
-library chrome;
+library _chrome;
import 'dart:_foreign_helper' show JS;
/* TODO(sashab): Add "show convertDartClosureToJS" once 'show' works. */
@@ -51,15 +51,15 @@
import 'dart:html_common';
import 'dart:html';
-part "$AUXILIARY_DIR/chrome/utils.dart";
-part "$AUXILIARY_DIR/chrome/chrome.dart";
+part "$AUXILIARY_DIR/_chrome/utils.dart";
+part "$AUXILIARY_DIR/_chrome/_chrome.dart";
// Generated files below this line.
"""
# The format for adding files to TEMPLATE_CONTENT. Will be substituted with the
# filename (not including the extension) of the IDL/JSON file.
-TEMPLATE_FILE_FORMAT = 'part "$AUXILIARY_DIR/chrome/%s.dart";'
+TEMPLATE_FILE_FORMAT = 'part "$AUXILIARY_DIR/_chrome/%s.dart";'
# A list of schema files to generate.
# TODO(sashab): Later, use the ones from API_DIR/api.gyp and
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index 3f6f017..928c1cc 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -511,7 +511,6 @@
'XMLHttpRequest.response': _all_but_ie9_annotations,
'XMLHttpRequestEventTarget.onloadend': _all_but_ie9_annotations,
'XMLHttpRequestEventTarget.onprogress': _all_but_ie9_annotations,
- 'XMLHttpRequestProgressEvent': _webkit_experimental_annotations,
'XSLTProcessor': [
"@SupportedBrowser(SupportedBrowser.CHROME)",
"@SupportedBrowser(SupportedBrowser.FIREFOX)",
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 1de4ede..3bb58bc 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -709,6 +709,10 @@
def to_dart_conversion(self, value, interface_name=None, attributes=None):
return 'Dart%s::toDart(%s)' % (self._idl_type, value)
+ def return_to_dart_conversion(self, value,
+ interface_name=None, attributes=None):
+ return 'Dart%s::returnToDart(args, %s)' % (self._idl_type, value)
+
def custom_to_dart(self):
return self._data.custom_to_dart
@@ -832,6 +836,13 @@
return 'DartDOMWrapper::vectorToDart(%s)' % value
return 'DartDOMWrapper::vectorToDart<%s>(%s)' % (self._item_info.bindings_class(), value)
+ def return_to_dart_conversion(self, value,
+ interface_name=None, attributes=None):
+ return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
+ value,
+ interface_name,
+ attributes)
+
def conversion_includes(self):
return self._item_info.conversion_includes()
@@ -889,6 +900,13 @@
function_name += 'WithNullCheck'
return '%s(%s)' % (function_name, value)
+ def return_to_dart_conversion(self, value,
+ interface_name=None, attributes=None):
+ return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
+ value,
+ interface_name,
+ attributes)
+
def webcore_getter_name(self):
return self._data.webcore_getter_name
@@ -917,7 +935,7 @@
return 'receiver->'
return 'receiver->propertyReference().'
- def to_dart_conversion(self, value, interface_name, attributes):
+ def to_conversion_cast(self, value, interface_name, attributes):
svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix',
'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform']
conversion_cast = '%s::create(%s)'
@@ -932,7 +950,17 @@
else:
conversion_cast = 'static_cast<%s*>(%s)'
conversion_cast = conversion_cast % (self.native_type(), value)
- return 'Dart%s::toDart(%s)' % (self._idl_type, conversion_cast)
+ return '%s' % (conversion_cast)
+
+ def to_dart_conversion(self, value, interface_name, attributes):
+ return 'Dart%s::toDart(%s)' % (self._idl_type, self.to_conversion_cast(value, interface_name, attributes))
+
+ def return_to_dart_conversion(self, value, interface_name, attr):
+ return 'Dart%s::returnToDart(args, %s)' % (self._idl_type,
+ self.to_conversion_cast(
+ value,
+ interface_name,
+ attr))
def argument_expression(self, name, interface_name):
return name if interface_name.endswith('List') else '%s->propertyReference()' % name
@@ -949,6 +977,12 @@
def to_dart_conversion(self, value, interface_name, attributes):
return 'DartUtilities::arrayBufferViewToDart(%s)' % value
+ def return_to_dart_conversion(self, value, interface_name, attributes):
+ return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
+ value,
+ interface_name,
+ attributes)
+
def to_native_info(self, idl_node, interface_name):
return '%s.get()', 'RefPtr<%s>' % self._idl_type, 'DartUtilities', 'dartTo%s' % self._idl_type
@@ -966,6 +1000,12 @@
function_name = function_name[0].lower() + function_name[1:]
return '%s(%s)' % (function_name, value)
+ def return_to_dart_conversion(self, value, interface_name, attributes):
+ return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
+ value,
+ interface_name,
+ attributes)
+
def to_native_info(self, idl_node, interface_name):
return '%s.get()', 'RefPtr<%s>' % self._idl_type, 'DartUtilities', 'dartTo%s' % self._idl_type
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 7242512..791591b 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -60,7 +60,6 @@
'StringCallback': '_StringCallback',
'WebGLVertexArrayObjectOES': 'VertexArrayObject',
'XMLHttpRequest': 'HttpRequest',
- 'XMLHttpRequestProgressEvent': 'HttpRequestProgressEvent',
'XMLHttpRequestUpload': 'HttpRequestUpload',
}, **typed_array_renames))
@@ -121,6 +120,7 @@
'WebKitSourceBufferList',
'WorkerLocation', # Workers
'WorkerNavigator', # Workers
+ 'XMLHttpRequestProgressEvent',
]
for interface in _removed_html_interfaces:
@@ -175,6 +175,7 @@
'CSSStyleDeclaration.setProperty',
'CSSStyleDeclaration.var',
'DeviceOrientationEvent.initDeviceOrientationEvent',
+ 'Document.createElement',
'Document.createEvent',
'Document.createNodeIterator',
'Document.createTextNode',
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 40c75d0..7c5ec12 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -420,8 +420,6 @@
"JS('bool', '#.xmlspace !== undefined && #.xmllang !== undefined', "
"element, element)"),
'TouchList': "JS('bool', '!!document.createTouchList')",
- 'XMLHttpRequestProgressEvent':
- "Device.isEventTypeSupported('XMLHttpRequestProgressEvent')",
'WebGLRenderingContext': "JS('bool', '!!(window.WebGLRenderingContext)')",
'WebKitPoint': "JS('bool', '!!(window.WebKitPoint)')",
'WebSocket': "JS('bool', 'typeof window.WebSocket != \"undefined\"')",
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index d36e0cd..8dbe0e2 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -411,17 +411,45 @@
ext_attrs = self._interface.ext_attrs
+ to_dart_emitter.Emit(
+ ' static Dart_Handle toDart(NativeType* value)\n'
+ ' {\n'
+ ' if (!value)\n'
+ ' return Dart_Null();\n'
+ ' DartDOMData* domData = DartDOMData::current();\n'
+ ' Dart_WeakPersistentHandle result =\n'
+ ' DartDOMWrapper::lookupWrapper(domData, isNode, value);\n'
+ ' if (result)\n'
+ ' return Dart_HandleFromWeakPersistent(result);\n'
+ ' return createWrapper(value);\n'
+ ' }\n'
+ ' static void returnToDart(Dart_NativeArguments args,\n'
+ ' NativeType* value)\n'
+ ' {\n'
+ ' if (value) {\n'
+ ' DartDOMData* domData = static_cast<DartDOMData*>(\n'
+ ' Dart_GetNativeIsolateData(args));\n'
+ ' Dart_WeakPersistentHandle result =\n'
+ ' DartDOMWrapper::lookupWrapper(domData, isNode, value);\n'
+ ' if (result)\n'
+ ' Dart_SetWeakHandleReturnValue(args, result);\n'
+ ' else\n'
+ ' Dart_SetReturnValue(args, createWrapper(value));\n'
+ ' }\n'
+ ' }\n',
+ )
+
if ('CustomToV8' in ext_attrs or
'PureInterface' in ext_attrs or
'CPPPureInterface' in ext_attrs or
self._interface_type_info.custom_to_dart()):
to_dart_emitter.Emit(
- ' static Dart_Handle toDart(NativeType* value);\n')
+ ' static Dart_Handle createWrapper(NativeType* value);\n')
else:
to_dart_emitter.Emit(
- ' static Dart_Handle toDart(NativeType* value)\n'
+ ' static Dart_Handle createWrapper(NativeType* value)\n'
' {\n'
- ' return DartDOMWrapper::toDart<Dart$(INTERFACE)>(value);\n'
+ ' return DartDOMWrapper::createWrapper<Dart$(INTERFACE)>(value);\n'
' }\n',
INTERFACE=self._interface.id)
@@ -709,6 +737,7 @@
cpp_arguments = []
runtime_check = None
raises_exceptions = raises_dom_exception or arguments
+ needs_custom_element_callbacks = False
# TODO(antonm): unify with ScriptState below.
requires_stack_info = (ext_attrs.get('CallWith') == 'ScriptArguments|ScriptState' or
@@ -760,6 +789,10 @@
if 'Reflect' in ext_attrs:
cpp_arguments = [self._GenerateWebCoreReflectionAttributeName(node)]
+ if ext_attrs.get('CustomElementCallbacks') == 'Enable':
+ self._cpp_impl_includes.add('"core/dom/CustomElementCallbackDispatcher.h"')
+ needs_custom_element_callbacks = True
+
if return_type_is_nullable:
cpp_arguments = ['isNull']
@@ -882,6 +915,9 @@
' return;\n',
INDEX=len(arguments) + 1)
+ if needs_custom_element_callbacks:
+ body_emitter.Emit(' CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;\n');
+
# Emit arguments.
start_index = 1 if needs_receiver else 0
for i, argument in enumerate(arguments):
@@ -1005,9 +1041,14 @@
set_return_value = 'DartUtilities::setDartStringReturnValueWithNullCheck(args, %s)' % (value_expression)
else:
set_return_value = 'DartUtilities::setDartStringReturnValue(args, %s)' % (value_expression)
+ elif return_type_info.dart_type() == 'num' and return_type_info.native_type() == 'double':
+ set_return_value = 'Dart_SetDoubleReturnValue(args, %s)' % (value_expression)
else:
- to_dart_conversion = return_type_info.to_dart_conversion(value_expression, self._interface.id, ext_attrs)
- set_return_value = 'Dart_SetReturnValue(args, %s)' % (to_dart_conversion)
+ return_to_dart_conversion = return_type_info.return_to_dart_conversion(
+ value_expression,
+ self._interface.id,
+ ext_attrs)
+ set_return_value = '%s' % (return_to_dart_conversion)
invocation_emitter.Emit(
' $RETURN_VALUE;\n',
RETURN_VALUE=set_return_value)
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index a9c293d..bd6e04c 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -154,11 +154,17 @@
var _onData;
final bool _useCapture;
- _EventStreamSubscription(this._target, this._eventType, this._onData,
- this._useCapture) {
+ _EventStreamSubscription(this._target, this._eventType, onData,
+ this._useCapture) : _onData = _wrapZone(onData) {
_tryResume();
}
+ static _wrapZone(callback) {
+ // For performance reasons avoid wrapping if we are in the root zone.
+ if (Zone.current == Zone.ROOT) return callback;
+ return Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ }
+
void cancel() {
if (_canceled) return;
@@ -177,7 +183,7 @@
// Remove current event listener.
_unlisten();
- _onData = handleData;
+ _onData = _wrapZone(handleData);
_tryResume();
}
diff --git a/tools/dom/src/chrome/chrome.dart b/tools/dom/src/_chrome/_chrome.dart
similarity index 100%
rename from tools/dom/src/chrome/chrome.dart
rename to tools/dom/src/_chrome/_chrome.dart
diff --git a/tools/dom/src/chrome/app_runtime.dart b/tools/dom/src/_chrome/app_runtime.dart
similarity index 100%
rename from tools/dom/src/chrome/app_runtime.dart
rename to tools/dom/src/_chrome/app_runtime.dart
diff --git a/tools/dom/src/chrome/app_window.dart b/tools/dom/src/_chrome/app_window.dart
similarity index 100%
rename from tools/dom/src/chrome/app_window.dart
rename to tools/dom/src/_chrome/app_window.dart
diff --git a/tools/dom/src/chrome/custom_dart/app_window.AppWindow.contentWindow.dart b/tools/dom/src/_chrome/custom_dart/app_window.AppWindow.contentWindow.dart
similarity index 100%
rename from tools/dom/src/chrome/custom_dart/app_window.AppWindow.contentWindow.dart
rename to tools/dom/src/_chrome/custom_dart/app_window.AppWindow.contentWindow.dart
diff --git a/tools/dom/src/chrome/custom_dart/app_window.AppWindow.getBounds.dart b/tools/dom/src/_chrome/custom_dart/app_window.AppWindow.getBounds.dart
similarity index 100%
rename from tools/dom/src/chrome/custom_dart/app_window.AppWindow.getBounds.dart
rename to tools/dom/src/_chrome/custom_dart/app_window.AppWindow.getBounds.dart
diff --git a/tools/dom/src/chrome/custom_dart/app_window.create.dart b/tools/dom/src/_chrome/custom_dart/app_window.create.dart
similarity index 100%
rename from tools/dom/src/chrome/custom_dart/app_window.create.dart
rename to tools/dom/src/_chrome/custom_dart/app_window.create.dart
diff --git a/tools/dom/src/chrome/custom_dart/app_window.current.dart b/tools/dom/src/_chrome/custom_dart/app_window.current.dart
similarity index 100%
rename from tools/dom/src/chrome/custom_dart/app_window.current.dart
rename to tools/dom/src/_chrome/custom_dart/app_window.current.dart
diff --git a/tools/dom/src/chrome/file_system.dart b/tools/dom/src/_chrome/file_system.dart
similarity index 100%
rename from tools/dom/src/chrome/file_system.dart
rename to tools/dom/src/_chrome/file_system.dart
diff --git a/tools/dom/src/chrome/utils.dart b/tools/dom/src/_chrome/utils.dart
similarity index 100%
rename from tools/dom/src/chrome/utils.dart
rename to tools/dom/src/_chrome/utils.dart
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart
index 3ad3381..aa2c8f0 100644
--- a/tools/dom/src/dart2js_CustomElementSupport.dart
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart
@@ -8,14 +8,22 @@
return receiver.created();
}
-_makeCreatedCallbackMethod() {
+_callEnteredView(receiver) {
+ return receiver.enteredView();
+}
+
+_callLeftView(receiver) {
+ return receiver.leftView();
+}
+
+_makeCallbackMethod(callback) {
return JS('',
'''((function(invokeCallback) {
return function() {
return invokeCallback(this);
};
})(#))''',
- convertDartClosureToJS(_callCreated, 1));
+ convertDartClosureToJS(callback, 1));
}
const _typeNameToTag = const {
@@ -77,10 +85,18 @@
var properties = JS('=Object', '{}');
- var jsCreatedCallback = _makeCreatedCallbackMethod();
-
JS('void', '#.createdCallback = #', properties,
- JS('=Object', '{value: #}', jsCreatedCallback));
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callCreated)));
+ JS('void', '#.enteredViewCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
+ JS('void', '#.leftViewCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
+
+ // TODO(blois): Bug 13220- remove once transition is complete
+ JS('void', '#.enteredDocumentCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
+ JS('void', '#.leftDocumentCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
var baseProto = JS('=Object', '#.prototype', baseConstructor);
var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index 333d747..8991ee1 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -6,7 +6,7 @@
class _ConsoleVariables {
Map<String, Object> _data = new Map<String, Object>();
-
+
/**
* Forward member accesses to the backing JavaScript object.
*/
@@ -22,7 +22,7 @@
return Function.apply(_data[member], invocation.positionalArguments, invocation.namedArguments);
}
}
-
+
void clear() => _data.clear();
/**
@@ -93,6 +93,17 @@
return new UnsupportedError('[info: $fileName:$lineNo]');
}
+ static bool isTypeSubclassOf(Type type, Type other) {
+ if (type == other) {
+ return true;
+ }
+ var superclass = reflectClass(type).superclass;
+ if (superclass != null) {
+ return isTypeSubclassOf(superclass.reflectedType, other);
+ }
+ return false;
+ }
+
static window() native "Utils_window";
static forwardingPrint(String message) native "Utils_forwardingPrint";
static void spawnDomFunction(Function f, int replyTo) native "Utils_spawnDomFunction";
@@ -161,13 +172,13 @@
sb.write("final $arg");
args[arg] = value;
}
-
+
addArg("\$var", _consoleTempVariables);
-
+
for (int i = 0; i < locals.length; i+= 2) {
addArg(locals[i], locals[i+1]);
}
- sb..write(')=>\n$expression');
+ sb..write(')=>\n$expression');
return [sb.toString(), args.values.toList(growable: false)];
}
@@ -184,10 +195,10 @@
* prepended to disambuguate. This scheme is simplistic but easy to encode and
* decode. The use case for this method is displaying all map keys in a human
* readable way in debugging tools.
- */
+ */
static List<String> getEncodedMapKeyList(dynamic obj) {
if (obj is! Map) return null;
-
+
var ret = new List<String>();
int i = 0;
return obj.keys.map((key) {
@@ -271,40 +282,20 @@
return libName.startsWith('dart:');
}
- static void register(String tag, Type type) {
+ static void register(Document document, String tag, Type type,
+ String extendsTagName) {
// TODO(vsm): Move these checks into native code.
- if (type == null) {
- throw new UnsupportedError("Invalid null type.");
- }
ClassMirror cls = reflectClass(type);
if (_isBuiltinType(cls)) {
throw new UnsupportedError("Invalid custom element from $libName.");
}
- ClassMirror superClass = cls.superclass;
-
- Symbol objectName = reflectClass(Object).qualifiedName;
- bool isRoot(ClassMirror cls) =>
- cls == null || cls.qualifiedName == objectName;
- // TODO(vsm): Support extending SvgElement as well.
- Symbol elementName = reflectClass(HtmlElement).qualifiedName;
- bool isElement(ClassMirror cls) =>
- cls != null && cls.qualifiedName == elementName;
-
- ClassMirror nativeClass = _isBuiltinType(superClass) ? superClass : null;
- while(!isRoot(superClass) && !isElement(superClass)) {
- superClass = superClass.superclass;
- if (nativeClass == null && _isBuiltinType(superClass)) {
- nativeClass = superClass;
- }
- }
-
- if (isRoot(superClass)) {
- throw new UnsupportedError("Invalid custom element doesn't inherit from HtmlElement.");
- }
- _register(tag, type, nativeClass.reflectedType);
+ _register(document, tag, type, extendsTagName);
}
- static void _register(String tag, Type customType, Type nativeType) native "Utils_register";
+ static void _register(Document document, String tag, Type customType,
+ String extendsTagName) native "Utils_register";
+
+ static Element createElement(Document document, String tagName) native "Utils_createElement";
}
class _NPObject extends NativeFieldWrapperClass1 {
diff --git a/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate b/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
index 2ea934d..8cfc7a3 100644
--- a/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
@@ -21,10 +21,10 @@
import 'dart:html_common';
import 'dart:html';
-part "$AUXILIARY_DIR/chrome/utils.dart";
-part "$AUXILIARY_DIR/chrome/chrome.dart";
+part "$AUXILIARY_DIR/_chrome/utils.dart";
+part "$AUXILIARY_DIR/_chrome/_chrome.dart";
// Generated files below this line.
-part "$AUXILIARY_DIR/chrome/app_window.dart";
-part "$AUXILIARY_DIR/chrome/app_runtime.dart";
-part "$AUXILIARY_DIR/chrome/file_system.dart";
\ No newline at end of file
+part "$AUXILIARY_DIR/_chrome/app_window.dart";
+part "$AUXILIARY_DIR/_chrome/app_runtime.dart";
+part "$AUXILIARY_DIR/_chrome/file_system.dart";
diff --git a/tools/dom/templates/html/dartium/chrome_dartium.darttemplate b/tools/dom/templates/html/dartium/chrome_dartium.darttemplate
index 03a6cb4..cc513c7 100644
--- a/tools/dom/templates/html/dartium/chrome_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/chrome_dartium.darttemplate
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
// DO NOT EDIT
-// Auto-generated dart:chrome library.
+// Auto-generated dart:_chrome library.
/// Native wrappers for the Chrome Packaged App APIs.
///
@@ -12,4 +12,4 @@
///
/// For more information on these APIs, see the
/// [Chrome APIs Documentation](http://developer.chrome.com/extensions/api_index.html)
-library chrome;
+library _chrome;
diff --git a/tools/dom/templates/html/dartium/cpp_header.template b/tools/dom/templates/html/dartium/cpp_header.template
index 5a6a8de..8fb291b 100644
--- a/tools/dom/templates/html/dartium/cpp_header.template
+++ b/tools/dom/templates/html/dartium/cpp_header.template
@@ -28,6 +28,14 @@
{
return toDart(value.get());
}
+ static Dart_Handle createWrapper(PassRefPtr< $WEBCORE_CLASS_NAME > value)
+ {
+ return createWrapper(value.get());
+ }
+ static void returnToDart(Dart_NativeArguments args, PassRefPtr< $WEBCORE_CLASS_NAME > value)
+ {
+ return returnToDart(args, value.get());
+ }
static Dart_NativeFunction resolver(Dart_Handle name, int argumentCount);
};
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index 90c3dfa..7cc7f09 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -36,4 +36,18 @@
return true;
$endif
}
+
+ @DomName('Document.createElement')
+ Element createElement(String tagName, [String typeExtension]) {
+$if DART2JS
+ return _createElement(tagName, typeExtension);
+$else
+ if (typeExtension != null) {
+ return _createElement(tagName, typeExtension);
+ } else {
+ // Fast-path for Dartium when typeExtension is not needed.
+ return _Utils.createElement(this, tagName);
+ }
+$endif
+ }
}
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 8f73476..5732c1e 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -680,6 +680,20 @@
@Experimental()
void created() {}
+ /**
+ * Called by the DOM when this element has been inserted into the live
+ * document.
+ */
+ @Experimental()
+ void enteredView() {}
+
+ /**
+ * Called by the DOM when this element has been removed from the live
+ * document.
+ */
+ @Experimental()
+ void leftView() {}
+
// Hooks to support custom WebComponents.
$if DART2JS
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index a29e0c1..08e3709 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -242,13 +242,13 @@
* * VideoElement
*/
$if DART2JS
- void register(String tag, Type customElementClass, {String nativeTagName}) {
+ void register(String tag, Type customElementClass, {String extendsTag}) {
_registerCustomElement(JS('', 'window'), this, tag, customElementClass,
- nativeTagName);
+ extendsTag);
}
$else
- void register(String tag, Type customElementClass, {String nativeTagName}) {
- _Utils.register(tag, customElementClass);
+ void register(String tag, Type customElementClass, {String extendsTag}) {
+ _Utils.register(this, tag, customElementClass, extendsTag);
}
$endif
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 7919df9..646d6c3 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -54,8 +54,9 @@
/**
* Makes a server POST request with the specified data encoded as form data.
*
- * This is similar to sending a FormData object with broader browser
- * support but limited to string values.
+ * This is roughly the POST equivalent of getString. This method is similar
+ * to sending a FormData object with broader browser support but limited to
+ * String values.
*
* See also:
*
@@ -88,11 +89,15 @@
/**
* Creates a URL request for the specified [url].
*
- * By default this will do an HTTP GET request, this can be overridden with
- * [method].
+ * By default `request` will perform an HTTP GET request, but a different
+ * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
+ * [method] parameter.
*
* The Future is completed when the response is available.
*
+ * If specified, `sendData` will send data in the form of a [ByteBuffer],
+ * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
+ *
* The [withCredentials] parameter specified that credentials such as a cookie
* (already) set in the header or
* [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
diff --git a/tools/gyp/find_mac_gcc_version.py b/tools/gyp/find_mac_gcc_version.py
index 1f136dd..0598380 100755
--- a/tools/gyp/find_mac_gcc_version.py
+++ b/tools/gyp/find_mac_gcc_version.py
@@ -25,11 +25,11 @@
return '4.2'
elif major == 4 and minor < 5:
return 'com.apple.compilers.llvmgcc42'
- elif major == 4 and minor >= 5:
+ elif (major == 4 and minor >= 5) or major == 5:
# XCode seems to select the specific clang version automatically
return 'com.apple.compilers.llvm.clang.1_0'
else:
- raise Exception('Unknown XCode Version "%s"' % version_match)
+ raise Exception('Unknown XCode Version "%s"' % stdout)
else:
raise Exception('Could not parse output of xcodebuild "%s"' % stdout)
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index b505799..b69e6ac 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -9,22 +9,91 @@
import "dart:io";
import "status_expression.dart";
-/** Possible outcomes of running a test. */
-const CRASH = "crash";
-const TIMEOUT = "timeout";
-const FAIL = "fail";
-const PASS = "pass";
-/**
- * An indication to skip the test. The caller is responsible for skipping it.
- */
-const SKIP = "skip";
-const SKIP_BY_DESIGN = "skipbydesign";
-const OK = "ok";
-/**
- * An indication that a test is slow and we should allow extra time for
- * completion.
- */
-const SLOW = "slow";
+class Expectation {
+ // Possible outcomes of running a test.
+ static Expectation PASS = byName('Pass');
+ static Expectation CRASH = byName('Crash');
+ static Expectation TIMEOUT = byName('Timeout');
+ static Expectation FAIL = byName('Fail');
+
+ // Special 'FAIL' cases
+ static Expectation RUNTIME_ERROR = byName('RuntimeError');
+ static Expectation COMPILETIME_ERROR = byName('CompileTimeError');
+ static Expectation MISSING_RUNTIME_ERROR = byName('MissingRuntimeError');
+ static Expectation MISSING_COMPILETIME_ERROR =
+ byName('MissingCompileTimeError');
+
+ // "meta expectations"
+ static Expectation OK = byName('Ok');
+ static Expectation SLOW = byName('Slow');
+ static Expectation SKIP = byName('Skip');
+ static Expectation SKIP_BY_DESIGN = byName('SkipByDesign');
+
+ static Expectation byName(String name) {
+ _initialize();
+ name = name.toLowerCase();
+ if (!_AllExpectations.containsKey(name)) {
+ throw new Exception("Expectation.byName(name='$name'): Invalid name.");
+ }
+ return _AllExpectations[name];
+ }
+
+ // Keep a map of all possible Expectation objects, initialized lazily.
+ static Map<String, Expectation> _AllExpectations;
+ static void _initialize() {
+ if (_AllExpectations == null) {
+ _AllExpectations = new Map<String, Expectation>();
+
+ Expectation build(prettyName, {group: null, isMetaExpectation: false}) {
+ var expectation = new Expectation._(prettyName,
+ group: group, isMetaExpectation: isMetaExpectation);
+ assert(!_AllExpectations.containsKey(expectation.name));
+ return _AllExpectations[expectation.name] = expectation;
+ }
+
+ var fail = build("Fail");
+ build("Pass");
+ build("Crash");
+ build("Timeout");
+
+ build("MissingCompileTimeError", group: fail);
+ build("MissingRuntimeError", group: fail);
+ build("CompileTimeError", group: fail);
+ build("RuntimeError", group: fail);
+
+ build("Skip", isMetaExpectation: true);
+ build("SkipByDesign", isMetaExpectation: true);
+ build("Ok", isMetaExpectation: true);
+ build("Slow", isMetaExpectation: true);
+ }
+ }
+
+ final String prettyName;
+ final String name;
+ final Expectation group;
+ // Indicates whether this expectation cannot be a test outcome (i.e. it is a
+ // "meta marker").
+ final bool isMetaExpectation;
+
+ Expectation._(prettyName,
+ {Expectation this.group: null,
+ bool this.isMetaExpectation: false})
+ : prettyName = prettyName, name = prettyName.toLowerCase();
+
+ bool canBeOutcomeOf(Expectation expectation) {
+ Expectation outcome = this;
+ while (outcome != null) {
+ if (outcome == expectation) {
+ return true;
+ }
+ outcome = outcome.group;
+ }
+ return false;
+ }
+
+ String toString() => prettyName;
+}
+
final RegExp SplitComment = new RegExp("^([^#]*)(#.*)?\$");
final RegExp HeaderPattern = new RegExp(r"^\[([^\]]+)\]");
@@ -162,8 +231,9 @@
if (_preprocessed) {
throw "TestExpectations.addRule: cannot add more rules";
}
- var values = testRule.expression.evaluate(environment);
- _map.putIfAbsent(testRule.name, () => new Set()).addAll(values);
+ var names = testRule.expression.evaluate(environment);
+ var expectations = names.map((name) => Expectation.byName(name));
+ _map.putIfAbsent(testRule.name, () => new Set()).addAll(expectations);
}
/**
@@ -177,7 +247,7 @@
* components and checks that the anchored regular expression
* "^$keyComponent\$" matches the corresponding filename component.
*/
- Set<String> expectations(String filename) {
+ Set<Expectation> expectations(String filename) {
var result = new Set();
var splitFilename = filename.split('/');
@@ -198,7 +268,7 @@
// If no expectations were found the expectation is that the test
// passes.
if (result.isEmpty) {
- result.add(PASS);
+ result.add(Expectation.PASS);
}
return result;
}
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index abba2c9..012a7ec 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -178,7 +178,7 @@
class FlakyLogWriter extends EventListener {
void done(TestCase test) {
- if (test.isFlaky && test.result != PASS) {
+ if (test.isFlaky && test.result != Expectation.PASS) {
var buf = new StringBuffer();
for (var l in _buildFailureOutput(test)) {
buf.write("$l\n");
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 658a1c4..2151352 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -379,6 +379,26 @@
}
}
+class VmCommand extends Command {
+ VmCommand._(String executable,
+ List<String> arguments,
+ String configurationDir)
+ : super._("vm", executable, arguments, configurationDir);
+}
+
+class JSCommandlineCommand extends Command {
+ JSCommandlineCommand._(String displayName,
+ String executable,
+ List<String> arguments,
+ String configurationDir,
+ [Map<String, String> environmentOverrides = null])
+ : super._(displayName,
+ executable,
+ arguments,
+ configurationDir,
+ environmentOverrides);
+}
+
class CommandBuilder {
static final instance = new CommandBuilder._();
@@ -440,6 +460,20 @@
return _getUniqueCommand(command);
}
+ VmCommand getVmCommand(String executable,
+ List<String> arguments,
+ String configurationDir) {
+ var command = new VmCommand._(executable, arguments, configurationDir);
+ return _getUniqueCommand(command);
+ }
+
+ Command getJSCommandlineCommand(String displayName, executable, arguments,
+ String configurationDir, [environment = null]) {
+ var command = new JSCommandlineCommand._(displayName, executable, arguments,
+ configurationDir, environment);
+ return _getUniqueCommand(command);
+ }
+
Command getCommand(String displayName, executable, arguments,
String configurationDir, [environment = null]) {
var command = new Command._(displayName, executable, arguments,
@@ -490,7 +524,7 @@
Map configuration;
String displayName;
bool isNegative;
- Set<String> expectedOutcomes;
+ Set<Expectation> expectedOutcomes;
TestInformation info;
TestCase(this.displayName,
@@ -505,10 +539,13 @@
}
bool get unexpectedOutput {
- return !expectedOutcomes.contains(lastCommandOutput.result(this));
+ var outcome = lastCommandOutput.result(this);
+ return !expectedOutcomes.any((expectation) {
+ return outcome.canBeOutcomeOf(expectation);
+ });
}
- String get result => lastCommandOutput.result(this);
+ Expectation get result => lastCommandOutput.result(this);
CommandOutput get lastCommandOutput {
if (commandOutputs.length == 0) {
@@ -520,7 +557,7 @@
}
int get timeout {
- if (expectedOutcomes.contains(SLOW)) {
+ if (expectedOutcomes.contains(Expectation.SLOW)) {
return configuration['timeout'] * SLOW_TIMEOUT_MULTIPLIER;
} else {
return configuration['timeout'];
@@ -541,15 +578,13 @@
bool get usesWebDriver => TestUtils.usesWebDriver(configuration['runtime']);
bool get isFlaky {
- if (expectedOutcomes.contains(SKIP) ||
- expectedOutcomes.contains(SKIP_BY_DESIGN)) {
+ if (expectedOutcomes.contains(Expectation.SKIP) ||
+ expectedOutcomes.contains(Expectation.SKIP_BY_DESIGN)) {
return false;
}
- var flags = new Set.from(expectedOutcomes);
- flags..remove(OK)
- ..remove(SLOW);
- return flags.length > 1;
+ return expectedOutcomes
+ .where((expectation) => !expectation.isMetaExpectation).length > 1;
}
bool get isFinished {
@@ -576,6 +611,30 @@
String get testingUrl => _testingUrl;
}
+class UnittestSuiteMessagesMixin {
+ bool _isAsyncTest(String testOutput) {
+ return testOutput.contains("unittest-suite-wait-for-done");
+ }
+
+ bool _isAsyncTestSuccessfull(String testOutput) {
+ return testOutput.contains("unittest-suite-success");
+ }
+
+ Expectation _negateOutcomeIfIncompleteAsyncTest(Expectation outcome,
+ String testOutput) {
+ // If this is an asynchronous test and the asynchronous operation didn't
+ // complete successfully, it's outcome is Expectation.FAIL.
+ // TODO: maybe we should introduce a AsyncIncomplete marker or so
+ if (outcome == Expectation.PASS) {
+ if (_isAsyncTest(testOutput) &&
+ !_isAsyncTestSuccessfull(testOutput)) {
+ return Expectation.FAIL;
+ }
+ }
+ return outcome;
+ }
+}
+
/**
* CommandOutput records the output of a completed command: the process's exit
* code, the standard output and standard error, whether the process timed out,
@@ -585,7 +644,7 @@
abstract class CommandOutput {
Command get command;
- String result(TestCase testCase);
+ Expectation result(TestCase testCase);
bool get hasCrashed;
@@ -640,8 +699,11 @@
diagnostics = [];
}
- String result(TestCase testCase) => hasCrashed ? CRASH :
- (hasTimedOut ? TIMEOUT : (hasFailed(testCase) ? FAIL : PASS));
+ Expectation result(TestCase testCase) {
+ if (hasCrashed) return Expectation.CRASH;
+ if (hasTimedOut) return Expectation.TIMEOUT;
+ return hasFailed(testCase) ? Expectation.FAIL : Expectation.PASS;
+ }
bool get hasCrashed {
// The Java dartc runner and dart2js exits with code 253 in case
@@ -687,15 +749,18 @@
// Reverse result of a negative test.
bool hasFailed(TestCase testCase) {
- // FIXME(kustermann): this is a hack, remove it
- bool isCompilationCommand = testCase.commands.first == command
- && testCase.commands.length > 1;
- if (isCompilationCommand &&
- testCase.info != null && testCase.info.hasRuntimeError) {
- return exitCode != 0;
- }
return testCase.isNegative ? !didFail(testCase) : didFail(testCase);
}
+
+ Expectation _negateOutcomeIfNegativeTest(Expectation outcome,
+ bool isNegative) {
+ if (!isNegative) return outcome;
+
+ if (outcome.canBeOutcomeOf(Expectation.FAIL)) {
+ return Expectation.PASS;
+ }
+ return Expectation.FAIL;
+ }
}
class BrowserCommandOutputImpl extends CommandOutputImpl {
@@ -724,6 +789,26 @@
}
}
+ Expectation result(TestCase testCase) {
+ // Handle crashes and timeouts first
+ if (hasCrashed) return Expectation.CRASH;
+ if (hasTimedOut) return Expectation.TIMEOUT;
+
+ var outcome = _getOutcome();
+
+ if (testCase.info != null && testCase.info.hasRuntimeError) {
+ if (!outcome.canBeOutcomeOf(Expectation.RUNTIME_ERROR)) {
+ return Expectation.MISSING_RUNTIME_ERROR;
+ }
+ }
+
+ if (testCase.isNegative) {
+ if (outcome.canBeOutcomeOf(Expectation.FAIL)) return Expectation.PASS;
+ return Expectation.FAIL;
+ }
+ return outcome;
+ }
+
bool get successful => canRunDependendCommands;
bool get canRunDependendCommands {
@@ -732,16 +817,21 @@
return super.canRunDependendCommands && !didFail(null);
}
- bool didFail(TestCase _) {
+ Expectation _getOutcome() {
if (_failedBecauseOfMissingXDisplay) {
- return true;
+ return Expectation.FAIL;
}
if (command.expectedOutputFile != null) {
// We are either doing a pixel test or a layout test with content shell
- return _failedBecauseOfUnexpectedDRTOutput;
+ if (_failedBecauseOfUnexpectedDRTOutput) {
+ return Expectation.FAIL;
+ }
}
- return _browserTestFailure;
+ if (_browserTestFailure) {
+ return Expectation.RUNTIME_ERROR;
+ }
+ return Expectation.PASS;
}
bool _didFailBecauseOfMissingXDisplay() {
@@ -1043,6 +1133,130 @@
}
}
+class VmCommandOutputImpl extends CommandOutputImpl
+ with UnittestSuiteMessagesMixin {
+ static const DART_VM_EXITCODE_COMPILE_TIME_ERROR = 254;
+ static const DART_VM_EXITCODE_UNCAUGHT_EXCEPTION = 255;
+
+ VmCommandOutputImpl(Command command, int exitCode, bool timedOut,
+ List<int> stdout, List<int> stderr, Duration time)
+ : super(command, exitCode, timedOut, stdout, stderr, time, false);
+
+ Expectation result(TestCase testCase) {
+ // Handle crashes and timeouts first
+ if (hasCrashed) return Expectation.CRASH;
+ if (hasTimedOut) return Expectation.TIMEOUT;
+
+ // Multitests are handled specially
+ if (testCase.info != null) {
+ if (testCase.info.hasCompileError) {
+ if (exitCode == DART_VM_EXITCODE_COMPILE_TIME_ERROR) {
+ return Expectation.PASS;
+ }
+
+ // We're not as strict, if the exitCode indicated an uncaught exception
+ // we say it passed nonetheless
+ // TODO(kustermann): As soon as the VM team makes sure we get correct
+ // exit codes, we should remove this.
+ if (exitCode == DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) {
+ return Expectation.PASS;
+ }
+
+ return Expectation.MISSING_COMPILETIME_ERROR;
+ }
+ if (testCase.info.hasRuntimeError) {
+ // TODO(kustermann): Do we consider a "runtimeError" only an uncaught
+ // exception or does any nonzero exit code fullfil this requirement?
+ if (exitCode != 0) {
+ return Expectation.PASS;
+ }
+ return Expectation.MISSING_RUNTIME_ERROR;
+ }
+ }
+
+ // The actual outcome depends on the exitCode
+ Expectation outcome;
+ if (exitCode == DART_VM_EXITCODE_COMPILE_TIME_ERROR) {
+ outcome = Expectation.COMPILETIME_ERROR;
+ } else if (exitCode == DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) {
+ outcome = Expectation.RUNTIME_ERROR;
+ } else if (exitCode != 0) {
+ // This is a general fail, in case we get an unknown nonzero exitcode.
+ outcome = Expectation.FAIL;
+ } else {
+ outcome = Expectation.PASS;
+ }
+ outcome = _negateOutcomeIfIncompleteAsyncTest(outcome, decodeUtf8(stdout));
+ return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative);
+ }
+}
+
+class CompilationCommandOutputImpl extends CommandOutputImpl {
+ static const DART2JS_EXITCODE_CRASH = 253;
+
+ CompilationCommandOutputImpl(Command command, int exitCode, bool timedOut,
+ List<int> stdout, List<int> stderr, Duration time)
+ : super(command, exitCode, timedOut, stdout, stderr, time, false);
+
+ Expectation result(TestCase testCase) {
+ // Handle general crash/timeout detection.
+ if (hasCrashed) return Expectation.CRASH;
+ if (hasTimedOut) return Expectation.TIMEOUT;
+
+ // Handle dart2js/dart2dart specific crash detection
+ if (exitCode == DART2JS_EXITCODE_CRASH ||
+ exitCode == VmCommandOutputImpl.DART_VM_EXITCODE_COMPILE_TIME_ERROR ||
+ exitCode == VmCommandOutputImpl.DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) {
+ return Expectation.CRASH;
+ }
+
+ // Multitests are handled specially
+ if (testCase.info != null) {
+ if (testCase.info.hasCompileError) {
+ // Nonzero exit code of the compiler means compilation failed
+ // TODO(kustermann): Do we have a special exit code in that case???
+ if (exitCode != 0) {
+ return Expectation.PASS;
+ }
+ return Expectation.MISSING_COMPILETIME_ERROR;
+ }
+
+ // TODO(kustermann): This is a hack, remove it
+ if (testCase.info.hasRuntimeError && testCase.commands.length > 1) {
+ // We expected to run the test, but we got an compile time error.
+ // If the compilation succeeded, we wouldn't be in here!
+ assert(exitCode != 0);
+ return Expectation.COMPILETIME_ERROR;
+ }
+ }
+
+ Expectation outcome =
+ exitCode == 0 ? Expectation.PASS : Expectation.COMPILETIME_ERROR;
+ return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative);
+ }
+}
+
+class JsCommandlineOutputImpl extends CommandOutputImpl
+ with UnittestSuiteMessagesMixin {
+ JsCommandlineOutputImpl(Command command, int exitCode, bool timedOut,
+ List<int> stdout, List<int> stderr, Duration time)
+ : super(command, exitCode, timedOut, stdout, stderr, time, false);
+
+ Expectation result(TestCase testCase) {
+ // Handle crashes and timeouts first
+ if (hasCrashed) return Expectation.CRASH;
+ if (hasTimedOut) return Expectation.TIMEOUT;
+
+ if (testCase.info != null && testCase.info.hasRuntimeError) {
+ if (exitCode != 0) return Expectation.PASS;
+ return Expectation.MISSING_RUNTIME_ERROR;
+ }
+
+ var outcome = exitCode == 0 ? Expectation.PASS : Expectation.RUNTIME_ERROR;
+ outcome = _negateOutcomeIfIncompleteAsyncTest(outcome, decodeUtf8(stdout));
+ return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative);
+ }
+}
CommandOutput createCommandOutput(Command command,
int exitCode,
@@ -1067,7 +1281,17 @@
return new AnalysisCommandOutputImpl(
command, exitCode, timedOut, stdout, stderr,
time, compilationSkipped);
+ } else if (command is VmCommand) {
+ return new VmCommandOutputImpl(
+ command, exitCode, timedOut, stdout, stderr, time);
+ } else if (command is CompilationCommand) {
+ return new CompilationCommandOutputImpl(
+ command, exitCode, timedOut, stdout, stderr, time);
+ } else if (command is JSCommandlineCommand) {
+ return new JsCommandlineOutputImpl(
+ command, exitCode, timedOut, stdout, stderr, time);
}
+
return new CommandOutputImpl(
command, exitCode, timedOut, stdout, stderr,
time, compilationSkipped);
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 112bc47..e98f6f1 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -298,8 +298,8 @@
}
// Handle skipped tests
- if (expectations.contains(SKIP) ||
- expectations.contains(SKIP_BY_DESIGN)) {
+ if (expectations.contains(Expectation.SKIP) ||
+ expectations.contains(Expectation.SKIP_BY_DESIGN)) {
return;
}
@@ -704,7 +704,7 @@
String testName = buildTestCaseDisplayName(suiteDir, info.originTestPath,
multitestName: optionsFromFile['isMultitest'] ? info.multitestKey : "");
- Set<String> expectations = testExpectations.expectations(testName);
+ Set<Expectation> expectations = testExpectations.expectations(testName);
if (configuration['compiler'] != 'none' && info.hasCompileError) {
// If a compile-time error is expected, and we're testing a
// compiler, we never need to attempt to run the program (in a
@@ -716,7 +716,7 @@
// A browser multi-test has multiple expectations for one test file.
// Find all the different sub-test expecations for one entire test file.
List<String> subtestNames = info.optionsFromFile['subtestNames'];
- Map<String, Set<String>> multiHtmlTestExpectations = {};
+ Map<String, Set<Expectation>> multiHtmlTestExpectations = {};
for (String name in subtestNames) {
String fullTestName = '$testName/$name';
multiHtmlTestExpectations[fullTestName] =
@@ -734,7 +734,7 @@
void enqueueStandardTest(TestInformation info,
String testName,
- Set<String> expectations) {
+ Set<Expectation> expectations) {
var commonArguments = commonArgumentsFromFile(info.filePath,
info.optionsFromFile);
@@ -790,10 +790,10 @@
// Do not attempt to run the compiled result. A compilation
// error should be reported by the compilation command.
} else if (configuration['runtime'] == 'd8') {
- commands.add(CommandBuilder.instance.getCommand(
+ commands.add(CommandBuilder.instance.getJSCommandlineCommand(
"d8", d8FileName, ['$tempDir/out.js'], configurationDir));
} else if (configuration['runtime'] == 'jsshell') {
- commands.add(CommandBuilder.instance.getCommand(
+ commands.add(CommandBuilder.instance.getJSCommandlineCommand(
"jsshell", jsShellFileName, ['$tempDir/out.js'], configurationDir));
}
return commands;
@@ -817,8 +817,8 @@
var vmArguments = new List.from(vmOptions);
vmArguments.addAll([
'--ignore-unrecognized-flags', '$tempDir/out.dart']);
- commands.add(CommandBuilder.instance.getCommand(
- "vm", vmFileName, vmArguments, configurationDir));
+ commands.add(CommandBuilder.instance.getVmCommand(
+ vmFileName, vmArguments, configurationDir));
} else {
throw 'Unsupported runtime ${configuration["runtime"]} for dart2dart';
}
@@ -827,8 +827,8 @@
case 'none':
var arguments = new List.from(vmOptions);
arguments.addAll(args);
- return <Command>[CommandBuilder.instance.getCommand(
- 'vm', dartShellFileName, arguments, configurationDir)];
+ return <Command>[CommandBuilder.instance.getVmCommand(
+ dartShellFileName, arguments, configurationDir)];
case 'dartanalyzer':
case 'dart2analyzer':
@@ -968,6 +968,7 @@
String dartWrapperFilename = '$tempDir/test.dart';
String compiledDartWrapperFilename = '$tempDir/test.js';
+ String precompiledDartWrapperFilename = '$tempDir/test.precompiled.js';
String content = null;
Path dir = filePath.directoryPath;
@@ -990,17 +991,38 @@
// If necessary, run the Polymer deploy steps.
// TODO(jmesserly): this should be generalized for any tests that
// require Pub deploy, not just polymer.
- if (compiler != 'none' &&
- customHtml.readAsStringSync().contains('polymer/boot.js')) {
+ if (customHtml.readAsStringSync().contains('polymer/boot.js')) {
+ if (compiler != 'none') {
+ commands.add(_polymerDeployCommand(
+ customHtmlPath, tempDir, optionsFromFile));
- commands.add(_polymerDeployCommand(
- customHtmlPath, tempDir, optionsFromFile));
-
- htmlPath = '$tempDir/test/$nameNoExt.html';
- dartWrapperFilename = '${htmlPath}_bootstrap.dart';
- compiledDartWrapperFilename = '$dartWrapperFilename.js';
+ htmlPath = '$tempDir/test/$nameNoExt.html';
+ dartWrapperFilename = '${htmlPath}_bootstrap.dart';
+ compiledDartWrapperFilename = '$dartWrapperFilename.js';
+ } else {
+ htmlPath = customHtmlPath;
+ }
} else {
- htmlPath = customHtmlPath;
+ htmlPath = '$tempDir/test.html';
+ dartWrapperFilename = filePath.toNativePath();
+
+ var htmlContents = customHtml.readAsStringSync();
+ if (compiler == 'none') {
+ htmlContents = htmlContents.replaceAll('%TEST_SCRIPTS%',
+ '<script type="application/dart" '
+ 'src="${_createUrlPathFromFile(filePath)}"></script>\n'
+ '<script type="text/javascript" '
+ 'src="/packages/browser/dart.js"></script>');
+ } else {
+ compiledDartWrapperFilename = '$tempDir/$nameNoExt.js';
+ var jsFile = '$nameNoExt.js';
+ if (configuration['csp']) {
+ jsFile = '$nameNoExt.precompiled.js';
+ }
+ htmlContents = htmlContents.replaceAll('%TEST_SCRIPTS%',
+ '<script src="$jsFile"></script>');
+ }
+ new File(htmlPath).writeAsStringSync(htmlContents);
}
} else {
htmlPath = '$tempDir/test.html';
@@ -1015,8 +1037,13 @@
RandomAccessFile htmlTest =
new File(htmlPath).openSync(mode: FileMode.WRITE);
- String scriptPath = (compiler == 'none') ?
- dartWrapperFilename : compiledDartWrapperFilename;
+ String scriptPath = dartWrapperFilename;
+ if (compiler != 'none') {
+ scriptPath = compiledDartWrapperFilename;
+ if (configuration['csp']) {
+ scriptPath = precompiledDartWrapperFilename;
+ }
+ }
scriptPath = _createUrlPathFromFile(new Path(scriptPath));
if (new File(pngPath.toNativePath()).existsSync()) {
@@ -1026,10 +1053,6 @@
expectedOutput = txtPath;
content = getHtmlLayoutContents(scriptType, new Path("$scriptPath"));
} else {
- if (compiler == "dart2js" && configuration["csp"]) {
- scriptPath = scriptPath.replaceFirst('/test.js', '/precompiled.js');
- }
-
content = getHtmlContents(filename, scriptType,
new Path("$scriptPath"));
}
@@ -1047,12 +1070,12 @@
List<String> otherScripts = optionsFromFile['otherScripts'];
for (String name in otherScripts) {
Path namePath = new Path(name);
- String baseName = namePath.filenameWithoutExtension;
+ String fileName = namePath.filename;
Path fromPath = filePath.directoryPath.join(namePath);
if (compiler != 'none') {
assert(namePath.extension == 'dart');
commands.add(_compileCommand(
- fromPath.toNativePath(), '$tempDir/$baseName.js',
+ fromPath.toNativePath(), '$tempDir/$fileName.js',
compiler, tempDir, vmOptions, optionsFromFile));
}
if (compiler == 'none') {
@@ -1060,7 +1083,7 @@
// compiled, move the input scripts over with the script so they can
// be accessed.
String result = new File(fromPath.toNativePath()).readAsStringSync();
- new File('$tempDir/$baseName.dart').writeAsStringSync(result);
+ new File('$tempDir/$fileName').writeAsStringSync(result);
}
}
@@ -1289,6 +1312,7 @@
args.addAll(additionalOptions(filePath));
if (configuration['analyzer']) {
args.add('--machine');
+ args.add('--no-hints');
}
bool isMultitest = optionsFromFile["isMultitest"];
@@ -1968,8 +1992,6 @@
}
return extraVmOptions;
}
-
-
}
class SummaryReport {
@@ -1984,31 +2006,35 @@
static int timeout = 0;
static int compileErrorSkip = 0;
- static void add(Set<String> expectations) {
+ static void add(Set<Expectation> expectations) {
++total;
- if (expectations.contains(SKIP)) {
+ if (expectations.contains(Expectation.SKIP)) {
++skipped;
- } else if (expectations.contains(SKIP_BY_DESIGN)) {
+ } else if (expectations.contains(Expectation.SKIP_BY_DESIGN)) {
++skipped;
++skippedByDesign;
} else {
- if (expectations.contains(PASS) && expectations.contains(FAIL) &&
- !expectations.contains(CRASH) && !expectations.contains(OK)) {
+ if (expectations.contains(Expectation.PASS) &&
+ expectations.contains(Expectation.FAIL) &&
+ !expectations.contains(Expectation.CRASH) &&
+ !expectations.contains(Expectation.OK)) {
++noCrash;
}
- if (expectations.contains(PASS) && expectations.length == 1) {
+ if (expectations.contains(Expectation.PASS) && expectations.length == 1) {
++pass;
}
- if (expectations.containsAll([FAIL, OK]) && expectations.length == 2) {
+ if (expectations.containsAll([Expectation.FAIL, Expectation.OK]) &&
+ expectations.length == 2) {
++failOk;
}
- if (expectations.contains(FAIL) && expectations.length == 1) {
+ if (expectations.contains(Expectation.FAIL) && expectations.length == 1) {
++fail;
}
- if (expectations.contains(CRASH) && expectations.length == 1) {
+ if (expectations.contains(Expectation.CRASH) &&
+ expectations.length == 1) {
++crash;
}
- if (expectations.contains(TIMEOUT)) {
+ if (expectations.contains(Expectation.TIMEOUT)) {
++timeout;
}
}