Version 0.8.0.0
svn merge -r 27984:28200 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@28224 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer_experimental/bin/formatter.dart b/pkg/analyzer_experimental/bin/formatter.dart
index 02dc8f1..a8ea0fe 100755
--- a/pkg/analyzer_experimental/bin/formatter.dart
+++ b/pkg/analyzer_experimental/bin/formatter.dart
@@ -159,7 +159,11 @@
_toJson(formatResult) =>
// Actual JSON format TBD
JSON.encode({'source': formatResult.source,
- 'selection': formatResult.selection.toString()});
+ 'selection': {
+ 'offset': formatResult.selection.offset,
+ 'length': formatResult.selection.length
+ }
+ });
/// Log the given [msg].
_log(String msg) {
diff --git a/pkg/analyzer_experimental/lib/options.dart b/pkg/analyzer_experimental/lib/options.dart
index efa3b5f..9b3ffac 100644
--- a/pkg/analyzer_experimental/lib/options.dart
+++ b/pkg/analyzer_experimental/lib/options.dart
@@ -26,6 +26,9 @@
/** Whether to display version information */
final bool displayVersion;
+ /** Whether to report hints */
+ final bool disableHints;
+
/** Whether to ignore unrecognized flags */
final bool ignoreUnrecognizedFlags;
@@ -57,6 +60,7 @@
: shouldBatch = args['batch'],
machineFormat = args['machine'],
displayVersion = args['version'],
+ disableHints = args['no-hints'],
ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'],
perf = args['perf'],
showPackageWarnings = args['show-package-warnings'],
@@ -102,6 +106,8 @@
defaultsTo: false, negatable: false)
..addFlag('version', help: 'Print the analyzer version',
defaultsTo: false, negatable: false)
+ ..addFlag('no-hints', help: 'Do not show hint results',
+ defaultsTo: false, negatable: false)
..addFlag('ignore-unrecognized-flags',
help: 'Ignore unrecognized command line flags',
defaultsTo: false, negatable: false)
diff --git a/pkg/analyzer_experimental/lib/src/analyzer_impl.dart b/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
index 40b436c..2104617 100644
--- a/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
@@ -86,6 +86,11 @@
sourceFactory = new SourceFactory.con1(contentCache, resolvers);
context = AnalysisEngine.instance.createAnalysisContext();
context.sourceFactory = sourceFactory;
+
+ // set options for context
+ AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
+ contextOptions.hint = !options.disableHints;
+ context.analysisOptions = contextOptions;
}
/// Fills [sources].
@@ -139,6 +144,7 @@
/// Fills [errorInfos].
void prepareErrors() {
for (Source source in sources) {
+ context.computeErrors(source);
var sourceErrors = context.getErrors(source);
errorInfos.add(sourceErrors);
}
diff --git a/pkg/analyzer_experimental/lib/src/error_formatter.dart b/pkg/analyzer_experimental/lib/src/error_formatter.dart
index 47d718d..c26aaa4 100644
--- a/pkg/analyzer_experimental/lib/src/error_formatter.dart
+++ b/pkg/analyzer_experimental/lib/src/error_formatter.dart
@@ -46,41 +46,62 @@
// format errors
int errorCount = 0;
int warnCount = 0;
+ int hintCount = 0;
for (AnalysisError error in errors) {
- if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) {
+ var severity = error.errorCode.errorSeverity;
+ if (severity == ErrorSeverity.ERROR) {
errorCount++;
- } else if (error.errorCode.errorSeverity == ErrorSeverity.WARNING) {
+ } else if (severity == ErrorSeverity.WARNING) {
if (options.warningsAreFatal) {
errorCount++;
} else {
- warnCount++;
+ if (error.errorCode.type == ErrorType.HINT) {
+ hintCount++;
+ } else {
+ warnCount++;
+ }
}
}
formatError(errorToLine, error);
}
// print statistics
if (!options.machineFormat) {
- if (errorCount != 0 && warnCount != 0) {
+ var hasErrors = errorCount != 0;
+ var hasWarns = warnCount != 0;
+ var hasHints = hintCount != 0;
+ bool hasContent = false;
+ if (hasErrors) {
out.write(errorCount);
out.write(' ');
out.write(pluralize("error", errorCount));
- out.write(' and ');
+ hasContent = true;
+ }
+ if (hasWarns) {
+ if (hasContent) {
+ if (!hasHints) {
+ out.write(' and ');
+ } else {
+ out.write(", ");
+ }
+ }
out.write(warnCount);
out.write(' ');
out.write(pluralize("warning", warnCount));
- out.writeln(' found.');
- } else if (errorCount != 0) {
- out.write(errorCount);
+ hasContent = true;
+ }
+ if (hasHints) {
+ if (hasContent) {
+ out.write(" and ");
+ }
+ out.write(hintCount);
out.write(' ');
- out.write(pluralize("error", errorCount));
- out.writeln(' found.');
- } else if (warnCount != 0) {
- out.write(warnCount);
- out.write(' ');
- out.write(pluralize("warning", warnCount));
- out.writeln(' found.');
+ out.write(pluralize("hint", hintCount));
+ hasContent = true;
+ }
+ if (hasContent) {
+ out.writeln(" found.");
} else {
- out.writeln("No issues found.");
+ out.writeln("No issues found");
}
}
}
@@ -110,8 +131,12 @@
out.write('|');
out.write(escapePipe(error.message));
} else {
+ String errorType = error.errorCode.errorSeverity.displayName;
+ if (error.errorCode.type == ErrorType.HINT) {
+ errorType = error.errorCode.type.displayName;
+ }
// [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2)
- out.write('[${severity.displayName}] ${error.message} ');
+ out.write('[$errorType] ${error.message} ');
out.write('(${source.fullName}');
out.write(', line ${location.lineNumber}, col ${location.columnNumber})');
}
diff --git a/pkg/analyzer_experimental/lib/src/generated/ast.dart b/pkg/analyzer_experimental/lib/src/generated/ast.dart
index dea447d..3acc231 100644
--- a/pkg/analyzer_experimental/lib/src/generated/ast.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/ast.dart
@@ -116,7 +116,7 @@
if (beginToken == null) {
return -1;
}
- return beginToken.offset;
+ return this.beginToken.offset;
}
/**
@@ -484,8 +484,8 @@
*
* @param comment the documentation comment to be associated with this node
*/
- void set documentationComment(Comment comment2) {
- this._comment = becomeParentOf(comment2);
+ void set documentationComment(Comment comment) {
+ this._comment = becomeParentOf(comment);
}
/**
@@ -493,9 +493,9 @@
*
* @param metadata the metadata to be associated with this node
*/
- void set metadata(List<Annotation> metadata2) {
+ void set metadata(List<Annotation> metadata) {
this._metadata.clear();
- this._metadata.addAll(metadata2);
+ this._metadata.addAll(metadata);
}
void visitChildren(ASTVisitor visitor) {
if (commentIsBeforeAnnotations()) {
@@ -686,8 +686,8 @@
*
* @param arguments the arguments to the constructor being invoked
*/
- void set arguments(ArgumentList arguments2) {
- this._arguments = becomeParentOf(arguments2);
+ void set arguments(ArgumentList arguments) {
+ this._arguments = becomeParentOf(arguments);
}
/**
@@ -695,8 +695,8 @@
*
* @param constructorName the name of the constructor being invoked
*/
- void set constructorName(SimpleIdentifier constructorName2) {
- this._constructorName = becomeParentOf(constructorName2);
+ void set constructorName(SimpleIdentifier constructorName) {
+ this._constructorName = becomeParentOf(constructorName);
}
/**
@@ -704,8 +704,8 @@
*
* @param element the element to be associated with this identifier
*/
- void set element(Element element2) {
- this._element = element2;
+ void set element(Element element) {
+ this._element = element;
}
/**
@@ -714,8 +714,8 @@
*
* @param name the name of the constructor being invoked or the name of the field being referenced
*/
- void set name(Identifier name2) {
- this._name = becomeParentOf(name2);
+ void set name(Identifier name) {
+ this._name = becomeParentOf(name);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_name, visitor);
@@ -779,8 +779,8 @@
*
* @param identifier the identifier representing the argument being tested
*/
- void set identifier(SimpleIdentifier identifier2) {
- this._identifier = becomeParentOf(identifier2);
+ void set identifier(SimpleIdentifier identifier) {
+ this._identifier = becomeParentOf(identifier);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_identifier, visitor);
@@ -1046,8 +1046,8 @@
*
* @param expression the expression used to compute the value being cast
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
/**
@@ -1143,8 +1143,8 @@
*
* @param the condition that is being asserted to be `true`
*/
- void set condition(Expression condition2) {
- this._condition = becomeParentOf(condition2);
+ void set condition(Expression condition) {
+ this._condition = becomeParentOf(condition);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_condition, visitor);
@@ -1655,8 +1655,8 @@
*
* @param block the block representing the body of the function
*/
- void set block(Block block2) {
- this._block = becomeParentOf(block2);
+ void set block(Block block) {
+ this._block = becomeParentOf(block);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_block, visitor);
@@ -1847,8 +1847,8 @@
*
* @param target the target of the cascade sections
*/
- void set target(Expression target2) {
- this._target = becomeParentOf(target2);
+ void set target(Expression target) {
+ this._target = becomeParentOf(target);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_target, visitor);
@@ -2214,8 +2214,8 @@
*
* @param extendsClause the extends clause for this class
*/
- void set extendsClause(ExtendsClause extendsClause2) {
- this._extendsClause = becomeParentOf(extendsClause2);
+ void set extendsClause(ExtendsClause extendsClause) {
+ this._extendsClause = becomeParentOf(extendsClause);
}
/**
@@ -2223,8 +2223,8 @@
*
* @param implementsClause the implements clause for the class
*/
- void set implementsClause(ImplementsClause implementsClause2) {
- this._implementsClause = becomeParentOf(implementsClause2);
+ void set implementsClause(ImplementsClause implementsClause) {
+ this._implementsClause = becomeParentOf(implementsClause);
}
/**
@@ -2241,8 +2241,8 @@
*
* @param withClause the with clause for the class
*/
- void set withClause(WithClause withClause2) {
- this._withClause = becomeParentOf(withClause2);
+ void set withClause(WithClause withClause) {
+ this._withClause = becomeParentOf(withClause);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -2422,8 +2422,8 @@
*
* @param implementsClause the implements clause for this class
*/
- void set implementsClause(ImplementsClause implementsClause2) {
- this._implementsClause = becomeParentOf(implementsClause2);
+ void set implementsClause(ImplementsClause implementsClause) {
+ this._implementsClause = becomeParentOf(implementsClause);
}
/**
@@ -2431,8 +2431,8 @@
*
* @param name the name of the class being declared
*/
- void set name(SimpleIdentifier name2) {
- this._name = becomeParentOf(name2);
+ void set name(SimpleIdentifier name) {
+ this._name = becomeParentOf(name);
}
/**
@@ -2440,8 +2440,8 @@
*
* @param superclass the name of the superclass of the class being declared
*/
- void set superclass(TypeName superclass2) {
- this._superclass = becomeParentOf(superclass2);
+ void set superclass(TypeName superclass) {
+ this._superclass = becomeParentOf(superclass);
}
/**
@@ -2449,8 +2449,8 @@
*
* @param typeParameters the type parameters for the class
*/
- void set typeParameters(TypeParameterList typeParameters2) {
- this._typeParameters = becomeParentOf(typeParameters2);
+ void set typeParameters(TypeParameterList typeParameters) {
+ this._typeParameters = becomeParentOf(typeParameters);
}
/**
@@ -2458,8 +2458,8 @@
*
* @param withClause the with clause for this class
*/
- void set withClause(WithClause withClause2) {
- this._withClause = becomeParentOf(withClause2);
+ void set withClause(WithClause withClause) {
+ this._withClause = becomeParentOf(withClause);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -2711,8 +2711,8 @@
*
* @param identifier the identifier being referenced
*/
- void set identifier(Identifier identifier2) {
- identifier2 = becomeParentOf(identifier2);
+ void set identifier(Identifier identifier) {
+ identifier = becomeParentOf(identifier);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_identifier, visitor);
@@ -2928,8 +2928,8 @@
*
* @param scriptTag the script tag at the beginning of the compilation unit
*/
- void set scriptTag(ScriptTag scriptTag2) {
- this._scriptTag = becomeParentOf(scriptTag2);
+ void set scriptTag(ScriptTag scriptTag) {
+ this._scriptTag = becomeParentOf(scriptTag);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_scriptTag, visitor);
@@ -3345,8 +3345,8 @@
*
* @param element the element associated with this constructor
*/
- void set element(ConstructorElement element2) {
- this._element = element2;
+ void set element(ConstructorElement element) {
+ this._element = element;
}
/**
@@ -3363,8 +3363,8 @@
*
* @param parameters the parameters associated with the constructor
*/
- void set parameters(FormalParameterList parameters2) {
- this._parameters = becomeParentOf(parameters2);
+ void set parameters(FormalParameterList parameters) {
+ this._parameters = becomeParentOf(parameters);
}
/**
@@ -3374,8 +3374,8 @@
* @param redirectedConstructor the name of the constructor to which this constructor will be
* redirected
*/
- void set redirectedConstructor(ConstructorName redirectedConstructor2) {
- this._redirectedConstructor = becomeParentOf(redirectedConstructor2);
+ void set redirectedConstructor(ConstructorName redirectedConstructor) {
+ this._redirectedConstructor = becomeParentOf(redirectedConstructor);
}
/**
@@ -3396,9 +3396,9 @@
safelyVisitChild(_body, visitor);
}
Token get firstTokenAfterCommentAndMetadata {
- Token leftMost2 = leftMost([externalKeyword, constKeyword, factoryKeyword]);
- if (leftMost2 != null) {
- return leftMost2;
+ Token leftMost = this.leftMost([externalKeyword, constKeyword, factoryKeyword]);
+ if (leftMost != null) {
+ return leftMost;
}
return _returnType.beginToken;
}
@@ -3518,8 +3518,8 @@
*
* @param expression the expression computing the value to which the field will be initialized
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
/**
@@ -3644,8 +3644,8 @@
*
* @param name the name of the constructor
*/
- void set name(SimpleIdentifier name2) {
- this._name = becomeParentOf(name2);
+ void set name(SimpleIdentifier name) {
+ this._name = becomeParentOf(name);
}
/**
@@ -3663,8 +3663,8 @@
*
* @param type the name of the type defining the constructor
*/
- void set type(TypeName type2) {
- this._type = becomeParentOf(type2);
+ void set type(TypeName type) {
+ this._type = becomeParentOf(type);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_type, visitor);
@@ -3831,11 +3831,11 @@
DeclaredIdentifier({Comment comment, List<Annotation> metadata, Token keyword, TypeName type, SimpleIdentifier identifier}) : this.full(comment, metadata, keyword, type, identifier);
accept(ASTVisitor visitor) => visitor.visitDeclaredIdentifier(this);
LocalVariableElement get element {
- SimpleIdentifier identifier2 = identifier;
- if (identifier2 == null) {
+ SimpleIdentifier identifier = this.identifier;
+ if (identifier == null) {
return null;
}
- return identifier2.staticElement as LocalVariableElement;
+ return identifier.staticElement as LocalVariableElement;
}
Token get endToken => identifier.endToken;
@@ -3990,8 +3990,8 @@
*
* @param kind the kind of this parameter
*/
- void set kind(ParameterKind kind2) {
- this._kind = kind2;
+ void set kind(ParameterKind kind) {
+ this._kind = kind;
}
/**
@@ -4381,9 +4381,9 @@
ExportDirective({Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, List<Combinator> combinators, Token semicolon}) : this.full(comment, metadata, keyword, libraryUri, combinators, semicolon);
accept(ASTVisitor visitor) => visitor.visitExportDirective(this);
LibraryElement get uriElement {
- Element element2 = element;
- if (element2 is ExportElement) {
- return ((element2 as ExportElement)).exportedLibrary;
+ Element element = this.element;
+ if (element is ExportElement) {
+ return ((element as ExportElement)).exportedLibrary;
}
return null;
}
@@ -4605,8 +4605,8 @@
*
* @param expression the expression representing the body of the function
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_expression, visitor);
@@ -4675,8 +4675,8 @@
*
* @param expression the expression that comprises the statement
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_expression, visitor);
@@ -4946,8 +4946,8 @@
*
* @param parameters the parameters of the function-typed parameter
*/
- void set parameters(FormalParameterList parameters2) {
- this._parameters = becomeParentOf(parameters2);
+ void set parameters(FormalParameterList parameters) {
+ this._parameters = becomeParentOf(parameters);
}
/**
@@ -5120,8 +5120,8 @@
*
* @param body the body of the loop
*/
- void set body(Statement body2) {
- this._body = becomeParentOf(body2);
+ void set body(Statement body) {
+ this._body = becomeParentOf(body);
}
/**
@@ -5129,8 +5129,8 @@
*
* @param identifier the loop variable
*/
- void set identifier(SimpleIdentifier identifier2) {
- this._identifier = becomeParentOf(identifier2);
+ void set identifier(SimpleIdentifier identifier) {
+ this._identifier = becomeParentOf(identifier);
}
/**
@@ -5312,8 +5312,8 @@
*
* @param body the body of the loop
*/
- void set body(Statement body2) {
- this._body = becomeParentOf(body2);
+ void set body(Statement body) {
+ this._body = becomeParentOf(body);
}
/**
@@ -5330,8 +5330,8 @@
*
* @param initialization the initialization expression
*/
- void set initialization(Expression initialization2) {
- this._initialization = becomeParentOf(initialization2);
+ void set initialization(Expression initialization) {
+ this._initialization = becomeParentOf(initialization);
}
/**
@@ -5722,8 +5722,8 @@
*
* @param functionExpression the function expression being wrapped
*/
- void set functionExpression(FunctionExpression functionExpression2) {
- functionExpression2 = becomeParentOf(functionExpression2);
+ void set functionExpression(FunctionExpression functionExpression) {
+ functionExpression = becomeParentOf(functionExpression);
}
/**
@@ -5800,8 +5800,8 @@
*
* @param functionDeclaration the function declaration being wrapped
*/
- void set functionExpression(FunctionDeclaration functionDeclaration2) {
- this.functionDeclaration = becomeParentOf(functionDeclaration2);
+ void set functionExpression(FunctionDeclaration functionDeclaration) {
+ this.functionDeclaration = becomeParentOf(functionDeclaration);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(functionDeclaration, visitor);
@@ -5899,8 +5899,8 @@
*
* @param parameters the parameters associated with the function
*/
- void set parameters(FormalParameterList parameters2) {
- this._parameters = becomeParentOf(parameters2);
+ void set parameters(FormalParameterList parameters) {
+ this._parameters = becomeParentOf(parameters);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_parameters, visitor);
@@ -6012,8 +6012,8 @@
*
* @param argumentList the list of arguments to the method
*/
- void set argumentList(ArgumentList argumentList2) {
- this._argumentList = becomeParentOf(argumentList2);
+ void set argumentList(ArgumentList argumentList) {
+ this._argumentList = becomeParentOf(argumentList);
}
/**
@@ -6021,8 +6021,8 @@
*
* @param function the expression producing the function being invoked
*/
- void set function(Expression function2) {
- function2 = becomeParentOf(function2);
+ void set function(Expression function) {
+ function = becomeParentOf(function);
}
/**
@@ -6146,8 +6146,8 @@
*
* @param name the name of the function type being declared
*/
- void set name(SimpleIdentifier name2) {
- this._name = becomeParentOf(name2);
+ void set name(SimpleIdentifier name) {
+ this._name = becomeParentOf(name);
}
/**
@@ -6155,8 +6155,8 @@
*
* @param parameters the parameters associated with the function type
*/
- void set parameters(FormalParameterList parameters2) {
- this._parameters = becomeParentOf(parameters2);
+ void set parameters(FormalParameterList parameters) {
+ this._parameters = becomeParentOf(parameters);
}
/**
@@ -6173,8 +6173,8 @@
*
* @param typeParameters the type parameters for the function type
*/
- void set typeParameters(TypeParameterList typeParameters2) {
- this._typeParameters = becomeParentOf(typeParameters2);
+ void set typeParameters(TypeParameterList typeParameters) {
+ this._typeParameters = becomeParentOf(typeParameters);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -6264,8 +6264,8 @@
*
* @param parameters the parameters of the function-typed parameter
*/
- void set parameters(FormalParameterList parameters2) {
- this._parameters = becomeParentOf(parameters2);
+ void set parameters(FormalParameterList parameters) {
+ this._parameters = becomeParentOf(parameters);
}
/**
@@ -6273,8 +6273,8 @@
*
* @param returnType the return type of the function
*/
- void set returnType(TypeName returnType2) {
- this._returnType = becomeParentOf(returnType2);
+ void set returnType(TypeName returnType) {
+ this._returnType = becomeParentOf(returnType);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -6724,9 +6724,9 @@
*/
SimpleIdentifier get prefix => _prefix;
LibraryElement get uriElement {
- Element element2 = element;
- if (element2 is ImportElement) {
- return ((element2 as ImportElement)).importedLibrary;
+ Element element = this.element;
+ if (element is ImportElement) {
+ return ((element as ImportElement)).importedLibrary;
}
return null;
}
@@ -6736,8 +6736,8 @@
*
* @param prefix the prefix to be used with the imported names
*/
- void set prefix(SimpleIdentifier prefix2) {
- this._prefix = becomeParentOf(prefix2);
+ void set prefix(SimpleIdentifier prefix) {
+ this._prefix = becomeParentOf(prefix);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -7184,8 +7184,8 @@
*
* @param argumentList the list of arguments to the constructor
*/
- void set argumentList(ArgumentList argumentList2) {
- this._argumentList = becomeParentOf(argumentList2);
+ void set argumentList(ArgumentList argumentList) {
+ this._argumentList = becomeParentOf(argumentList);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(constructorName, visitor);
@@ -7333,8 +7333,8 @@
*
* @param expression the expression to be evaluated for the value to be converted into a string
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_expression, visitor);
@@ -7499,8 +7499,8 @@
*
* @param expression the expression used to compute the value whose type is being tested
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
/**
@@ -7572,8 +7572,8 @@
*
* @param label the label being associated with the statement
*/
- void set label(SimpleIdentifier label2) {
- this._label = becomeParentOf(label2);
+ void set label(SimpleIdentifier label) {
+ this._label = becomeParentOf(label);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_label, visitor);
@@ -7642,8 +7642,8 @@
*
* @param statement the statement with which the labels are being associated
*/
- void set statement(Statement statement2) {
- this._statement = becomeParentOf(statement2);
+ void set statement(Statement statement) {
+ this._statement = becomeParentOf(statement);
}
void visitChildren(ASTVisitor visitor) {
labels.accept(visitor);
@@ -7718,8 +7718,8 @@
*
* @param name the name of the library being defined
*/
- void set name(LibraryIdentifier name2) {
- this._name = becomeParentOf(name2);
+ void set name(LibraryIdentifier name) {
+ this._name = becomeParentOf(name);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -7844,9 +7844,9 @@
if (token != null) {
return token;
}
- TypeArgumentList typeArguments2 = typeArguments;
- if (typeArguments2 != null) {
- return typeArguments2.beginToken;
+ TypeArgumentList typeArguments = this.typeArguments;
+ if (typeArguments != null) {
+ return typeArguments.beginToken;
}
return _leftBracket;
}
@@ -7968,9 +7968,9 @@
if (token != null) {
return token;
}
- TypeArgumentList typeArguments2 = typeArguments;
- if (typeArguments2 != null) {
- return typeArguments2.beginToken;
+ TypeArgumentList typeArguments = this.typeArguments;
+ if (typeArguments != null) {
+ return typeArguments.beginToken;
}
return _leftBracket;
}
@@ -8308,8 +8308,8 @@
*
* @param parameters the parameters associated with the method
*/
- void set parameters(FormalParameterList parameters2) {
- this._parameters = becomeParentOf(parameters2);
+ void set parameters(FormalParameterList parameters) {
+ this._parameters = becomeParentOf(parameters);
}
/**
@@ -8474,8 +8474,8 @@
*
* @param argumentList the list of arguments to the method
*/
- void set argumentList(ArgumentList argumentList2) {
- this._argumentList = becomeParentOf(argumentList2);
+ void set argumentList(ArgumentList argumentList) {
+ this._argumentList = becomeParentOf(argumentList);
}
/**
@@ -8580,8 +8580,8 @@
*
* @param expression the expression with which the name is associated
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
/**
@@ -8849,8 +8849,8 @@
*
* @param comment the documentation comment to be associated with this parameter
*/
- void set documentationComment(Comment comment2) {
- this._comment = becomeParentOf(comment2);
+ void set documentationComment(Comment comment) {
+ this._comment = becomeParentOf(comment);
}
/**
@@ -8858,8 +8858,8 @@
*
* @param identifier the name of the parameter being declared
*/
- void set identifier(SimpleIdentifier identifier2) {
- this._identifier = becomeParentOf(identifier2);
+ void set identifier(SimpleIdentifier identifier) {
+ this._identifier = becomeParentOf(identifier);
}
void visitChildren(ASTVisitor visitor) {
if (commentIsBeforeAnnotations()) {
@@ -9017,8 +9017,8 @@
*
* @param expression the expression within the parentheses
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
/**
@@ -9170,8 +9170,8 @@
*
* @param libraryName the name of the library that the containing compilation unit is part of
*/
- void set libraryName(LibraryIdentifier libraryName2) {
- this._libraryName = becomeParentOf(libraryName2);
+ void set libraryName(LibraryIdentifier libraryName) {
+ this._libraryName = becomeParentOf(libraryName);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -9621,8 +9621,8 @@
*
* @param identifier the identifier being prefixed
*/
- void set identifier(SimpleIdentifier identifier2) {
- this._identifier = becomeParentOf(identifier2);
+ void set identifier(SimpleIdentifier identifier) {
+ this._identifier = becomeParentOf(identifier);
}
/**
@@ -9863,8 +9863,8 @@
*
* @param argumentList the list of arguments to the constructor
*/
- void set argumentList(ArgumentList argumentList2) {
- this._argumentList = becomeParentOf(argumentList2);
+ void set argumentList(ArgumentList argumentList) {
+ this._argumentList = becomeParentOf(argumentList);
}
/**
@@ -9984,8 +9984,8 @@
*
* @param expression the expression computing the value to be returned
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_expression, visitor);
@@ -10710,8 +10710,8 @@
*
* @param argumentList the list of arguments to the constructor
*/
- void set argumentList(ArgumentList argumentList2) {
- this._argumentList = becomeParentOf(argumentList2);
+ void set argumentList(ArgumentList argumentList) {
+ this._argumentList = becomeParentOf(argumentList);
}
/**
@@ -10819,8 +10819,8 @@
*
* @param expression the expression controlling whether the statements will be executed
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
void visitChildren(ASTVisitor visitor) {
labels.accept(visitor);
@@ -11036,8 +11036,8 @@
*
* @param expression the expression used to determine which of the switch members will be selected
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_expression, visitor);
@@ -11189,8 +11189,8 @@
*
* @param expression the expression computing the exception to be thrown
*/
- void set expression(Expression expression2) {
- this._expression = becomeParentOf(expression2);
+ void set expression(Expression expression) {
+ this._expression = becomeParentOf(expression);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_expression, visitor);
@@ -11582,8 +11582,8 @@
*
* @param typeArguments the type arguments associated with the type
*/
- void set typeArguments(TypeArgumentList typeArguments2) {
- this._typeArguments = becomeParentOf(typeArguments2);
+ void set typeArguments(TypeArgumentList typeArguments) {
+ this._typeArguments = becomeParentOf(typeArguments);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_name, visitor);
@@ -11858,8 +11858,8 @@
*
* @param uri the URI referenced by this directive
*/
- void set uri(StringLiteral uri2) {
- this._uri = becomeParentOf(uri2);
+ void set uri(StringLiteral uri) {
+ this._uri = becomeParentOf(uri);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -11990,8 +11990,8 @@
*
* @param initializer the expression used to compute the initial value for the variable
*/
- void set initializer(Expression initializer2) {
- this._initializer = becomeParentOf(initializer2);
+ void set initializer(Expression initializer) {
+ this._initializer = becomeParentOf(initializer);
}
/**
@@ -11999,8 +11999,8 @@
*
* @param name the name of the variable being declared
*/
- void set name(SimpleIdentifier name2) {
- this._name = becomeParentOf(name2);
+ void set name(SimpleIdentifier name) {
+ this._name = becomeParentOf(name);
}
void visitChildren(ASTVisitor visitor) {
super.visitChildren(visitor);
@@ -12174,8 +12174,8 @@
*
* @param variableList the variables being declared
*/
- void set variables(VariableDeclarationList variableList2) {
- this._variableList = becomeParentOf(variableList2);
+ void set variables(VariableDeclarationList variableList) {
+ this._variableList = becomeParentOf(variableList);
}
void visitChildren(ASTVisitor visitor) {
safelyVisitChild(_variableList, visitor);
@@ -12336,8 +12336,8 @@
*
* @param withKeyword the token representing the 'with' keyword
*/
- void set mixinKeyword(Token withKeyword2) {
- this.withKeyword = withKeyword2;
+ void set mixinKeyword(Token withKeyword) {
+ this.withKeyword = withKeyword;
}
void visitChildren(ASTVisitor visitor) {
mixinTypes.accept(visitor);
diff --git a/pkg/analyzer_experimental/lib/src/generated/constant.dart b/pkg/analyzer_experimental/lib/src/generated/constant.dart
index ac6bf34..2403231 100644
--- a/pkg/analyzer_experimental/lib/src/generated/constant.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/constant.dart
@@ -1103,16 +1103,16 @@
return value.toString();
}
EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
- } else if (isSomeNum || leftOperand2.isSomeNum) {
+ } else if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_NUM;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1137,14 +1137,14 @@
return error(node);
}
EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyInt || !leftOperand2.isAnyInt) {
+ EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyInt || !leftOperand.isAnyInt) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1161,14 +1161,14 @@
return union(error(node.leftOperand), error(node.rightOperand));
}
EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyInt || !leftOperand2.isAnyInt) {
+ EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyInt || !leftOperand.isAnyInt) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1185,14 +1185,14 @@
return union(error(node.leftOperand), error(node.rightOperand));
}
EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyInt || !leftOperand2.isAnyInt) {
+ EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyInt || !leftOperand.isAnyInt) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1217,14 +1217,14 @@
return error(node);
}
EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeNum || leftOperand2.isSomeNum) {
+ if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_NUM;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1286,14 +1286,14 @@
}
EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeNum || leftOperand2.isSomeNum) {
+ if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_BOOL;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1313,14 +1313,14 @@
}
return error(node);
}
- EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeNum || leftOperand2.isSomeNum) {
+ if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_BOOL;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1341,14 +1341,14 @@
return error(node);
}
EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeNum || leftOperand2.isSomeNum) {
+ if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_INT;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1376,14 +1376,14 @@
}
EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeNum || leftOperand2.isSomeNum) {
+ if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_BOOL;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1403,14 +1403,14 @@
}
return error(node);
}
- EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeNum || leftOperand2.isSomeNum) {
+ if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_BOOL;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1462,16 +1462,16 @@
return booleanConversion(node.rightOperand, value);
}
EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
- } else if (isSomeNum || leftOperand2.isSomeNum) {
+ } else if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_NUM;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1527,16 +1527,16 @@
return RESULT_TRUE;
}
EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
- } else if (isSomeNum || leftOperand2.isSomeNum) {
+ } else if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_NUM;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1560,14 +1560,14 @@
return error(node);
}
EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyInt || !leftOperand2.isAnyInt) {
+ EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyInt || !leftOperand.isAnyInt) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1584,14 +1584,14 @@
return union(error(node.leftOperand), error(node.rightOperand));
}
EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyInt || !leftOperand2.isAnyInt) {
+ EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyInt || !leftOperand.isAnyInt) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
@@ -1608,16 +1608,16 @@
return union(error(node.leftOperand), error(node.rightOperand));
}
EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
- EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand2) {
- if (!isAnyNum || !leftOperand2.isAnyNum) {
+ EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand) {
+ if (!isAnyNum || !leftOperand.isAnyNum) {
return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
}
- if (isSomeInt || leftOperand2.isSomeInt) {
+ if (isSomeInt || leftOperand.isSomeInt) {
return RESULT_INT;
- } else if (isSomeNum || leftOperand2.isSomeNum) {
+ } else if (isSomeNum || leftOperand.isSomeNum) {
return RESULT_NUM;
}
- Object leftValue = leftOperand2.value;
+ Object leftValue = leftOperand.value;
if (leftValue == null) {
return error(node.leftOperand);
} else if (value == null) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/element.dart b/pkg/analyzer_experimental/lib/src/generated/element.dart
index fa3c4be..776fbf2 100644
--- a/pkg/analyzer_experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/element.dart
@@ -1812,29 +1812,29 @@
collectAllSupertypes(list);
return new List.from(list);
}
- ElementImpl getChild(String identifier2) {
+ ElementImpl getChild(String identifier) {
for (PropertyAccessorElement accessor in _accessors) {
- if (((accessor as PropertyAccessorElementImpl)).identifier == identifier2) {
+ if (((accessor as PropertyAccessorElementImpl)).identifier == identifier) {
return accessor as PropertyAccessorElementImpl;
}
}
for (ConstructorElement constructor in _constructors) {
- if (((constructor as ConstructorElementImpl)).identifier == identifier2) {
+ if (((constructor as ConstructorElementImpl)).identifier == identifier) {
return constructor as ConstructorElementImpl;
}
}
for (FieldElement field in _fields) {
- if (((field as FieldElementImpl)).identifier == identifier2) {
+ if (((field as FieldElementImpl)).identifier == identifier) {
return field as FieldElementImpl;
}
}
for (MethodElement method in _methods) {
- if (((method as MethodElementImpl)).identifier == identifier2) {
+ if (((method as MethodElementImpl)).identifier == identifier) {
return method as MethodElementImpl;
}
}
for (TypeParameterElement typeParameter in _typeParameters) {
- if (((typeParameter as TypeParameterElementImpl)).identifier == identifier2) {
+ if (((typeParameter as TypeParameterElementImpl)).identifier == identifier) {
return typeParameter as TypeParameterElementImpl;
}
}
@@ -1849,9 +1849,9 @@
* @param name some name to lookup a field element with
* @return the matching field element, or `null` if no such element was found
*/
- FieldElement getField(String name2) {
+ FieldElement getField(String name) {
for (FieldElement fieldElement in _fields) {
- if (name2 == fieldElement.name) {
+ if (name == fieldElement.name) {
return fieldElement;
}
}
@@ -1878,10 +1878,10 @@
}
List<MethodElement> get methods => _methods;
List<InterfaceType> get mixins => _mixins;
- ConstructorElement getNamedConstructor(String name2) {
+ ConstructorElement getNamedConstructor(String name) {
for (ConstructorElement element in constructors) {
String elementName = element.name;
- if (elementName != null && elementName == name2) {
+ if (elementName != null && elementName == name) {
return element;
}
}
@@ -2034,11 +2034,11 @@
*
* @param accessors the accessors contained in this class
*/
- void set accessors(List<PropertyAccessorElement> accessors2) {
- for (PropertyAccessorElement accessor in accessors2) {
+ void set accessors(List<PropertyAccessorElement> accessors) {
+ for (PropertyAccessorElement accessor in accessors) {
((accessor as PropertyAccessorElementImpl)).enclosingElement = this;
}
- this._accessors = accessors2;
+ this._accessors = accessors;
}
/**
@@ -2046,11 +2046,11 @@
*
* @param constructors the constructors contained in this class
*/
- void set constructors(List<ConstructorElement> constructors2) {
- for (ConstructorElement constructor in constructors2) {
+ void set constructors(List<ConstructorElement> constructors) {
+ for (ConstructorElement constructor in constructors) {
((constructor as ConstructorElementImpl)).enclosingElement = this;
}
- this._constructors = constructors2;
+ this._constructors = constructors;
}
/**
@@ -2058,11 +2058,11 @@
*
* @param fields the fields contained in this class
*/
- void set fields(List<FieldElement> fields2) {
- for (FieldElement field in fields2) {
+ void set fields(List<FieldElement> fields) {
+ for (FieldElement field in fields) {
((field as FieldElementImpl)).enclosingElement = this;
}
- this._fields = fields2;
+ this._fields = fields;
}
/**
@@ -2079,8 +2079,8 @@
*
* @param the interfaces that are implemented by this class
*/
- void set interfaces(List<InterfaceType> interfaces2) {
- this._interfaces = interfaces2;
+ void set interfaces(List<InterfaceType> interfaces) {
+ this._interfaces = interfaces;
}
/**
@@ -2088,11 +2088,11 @@
*
* @param methods the methods contained in this class
*/
- void set methods(List<MethodElement> methods2) {
- for (MethodElement method in methods2) {
+ void set methods(List<MethodElement> methods) {
+ for (MethodElement method in methods) {
((method as MethodElementImpl)).enclosingElement = this;
}
- this._methods = methods2;
+ this._methods = methods;
}
/**
@@ -2101,8 +2101,8 @@
*
* @param mixins the mixins that are applied to derive the superclass of this class
*/
- void set mixins(List<InterfaceType> mixins2) {
- this._mixins = mixins2;
+ void set mixins(List<InterfaceType> mixins) {
+ this._mixins = mixins;
}
/**
@@ -2110,8 +2110,8 @@
*
* @param supertype the superclass of the class
*/
- void set supertype(InterfaceType supertype2) {
- this._supertype = supertype2;
+ void set supertype(InterfaceType supertype) {
+ this._supertype = supertype;
}
/**
@@ -2119,8 +2119,8 @@
*
* @param type the type defined by the class
*/
- void set type(InterfaceType type2) {
- this._type = type2;
+ void set type(InterfaceType type) {
+ this._type = type;
}
/**
@@ -2137,11 +2137,11 @@
*
* @param typeParameters the type parameters defined for this class
*/
- void set typeParameters(List<TypeParameterElement> typeParameters2) {
- for (TypeParameterElement typeParameter in typeParameters2) {
+ void set typeParameters(List<TypeParameterElement> typeParameters) {
+ for (TypeParameterElement typeParameter in typeParameters) {
((typeParameter as TypeParameterElementImpl)).enclosingElement = this;
}
- this._typeParameters = typeParameters2;
+ this._typeParameters = typeParameters;
}
/**
@@ -2267,29 +2267,29 @@
accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
bool operator ==(Object object) => object != null && runtimeType == object.runtimeType && _source == ((object as CompilationUnitElementImpl)).source;
List<PropertyAccessorElement> get accessors => _accessors;
- ElementImpl getChild(String identifier2) {
+ ElementImpl getChild(String identifier) {
for (PropertyAccessorElement accessor in _accessors) {
- if (((accessor as PropertyAccessorElementImpl)).identifier == identifier2) {
+ if (((accessor as PropertyAccessorElementImpl)).identifier == identifier) {
return accessor as PropertyAccessorElementImpl;
}
}
for (VariableElement variable in _variables) {
- if (((variable as VariableElementImpl)).identifier == identifier2) {
+ if (((variable as VariableElementImpl)).identifier == identifier) {
return variable as VariableElementImpl;
}
}
for (ExecutableElement function in _functions) {
- if (((function as ExecutableElementImpl)).identifier == identifier2) {
+ if (((function as ExecutableElementImpl)).identifier == identifier) {
return function as ExecutableElementImpl;
}
}
for (FunctionTypeAliasElement typeAlias in _typeAliases) {
- if (((typeAlias as FunctionTypeAliasElementImpl)).identifier == identifier2) {
+ if (((typeAlias as FunctionTypeAliasElementImpl)).identifier == identifier) {
return typeAlias as FunctionTypeAliasElementImpl;
}
}
for (ClassElement type in _types) {
- if (((type as ClassElementImpl)).identifier == identifier2) {
+ if (((type as ClassElementImpl)).identifier == identifier) {
return type as ClassElementImpl;
}
}
@@ -2320,11 +2320,11 @@
*
* @param the top-level accessors (getters and setters) contained in this compilation unit
*/
- void set accessors(List<PropertyAccessorElement> accessors2) {
- for (PropertyAccessorElement accessor in accessors2) {
+ void set accessors(List<PropertyAccessorElement> accessors) {
+ for (PropertyAccessorElement accessor in accessors) {
((accessor as PropertyAccessorElementImpl)).enclosingElement = this;
}
- this._accessors = accessors2;
+ this._accessors = accessors;
}
/**
@@ -2332,11 +2332,11 @@
*
* @param functions the top-level functions contained in this compilation unit
*/
- void set functions(List<FunctionElement> functions2) {
- for (FunctionElement function in functions2) {
+ void set functions(List<FunctionElement> functions) {
+ for (FunctionElement function in functions) {
((function as FunctionElementImpl)).enclosingElement = this;
}
- this._functions = functions2;
+ this._functions = functions;
}
/**
@@ -2344,8 +2344,8 @@
*
* @param source the source that corresponds to this compilation unit
*/
- void set source(Source source2) {
- this._source = source2;
+ void set source(Source source) {
+ this._source = source;
}
/**
@@ -2353,11 +2353,11 @@
*
* @param variables the top-level variables contained in this compilation unit
*/
- void set topLevelVariables(List<TopLevelVariableElement> variables2) {
- for (TopLevelVariableElement field in variables2) {
+ void set topLevelVariables(List<TopLevelVariableElement> variables) {
+ for (TopLevelVariableElement field in variables) {
((field as TopLevelVariableElementImpl)).enclosingElement = this;
}
- this._variables = variables2;
+ this._variables = variables;
}
/**
@@ -2365,11 +2365,11 @@
*
* @param typeAliases the function type aliases contained in this compilation unit
*/
- void set typeAliases(List<FunctionTypeAliasElement> typeAliases2) {
- for (FunctionTypeAliasElement typeAlias in typeAliases2) {
+ void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
+ for (FunctionTypeAliasElement typeAlias in typeAliases) {
((typeAlias as FunctionTypeAliasElementImpl)).enclosingElement = this;
}
- this._typeAliases = typeAliases2;
+ this._typeAliases = typeAliases;
}
/**
@@ -2377,11 +2377,11 @@
*
* @param types types contained in this compilation unit
*/
- void set types(List<ClassElement> types2) {
- for (ClassElement type in types2) {
+ void set types(List<ClassElement> types) {
+ for (ClassElement type in types) {
((type as ClassElementImpl)).enclosingElement = this;
}
- this._types = types2;
+ this._types = types;
}
/**
@@ -2389,8 +2389,8 @@
*
* @param uri the URI that is specified by the "part" directive in the enclosing library.
*/
- void set uri(String uri2) {
- this._uri = uri2;
+ void set uri(String uri) {
+ this._uri = uri;
}
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
@@ -2426,8 +2426,8 @@
*/
ConstFieldElementImpl(Identifier name) : super.con1(name);
EvaluationResultImpl get evaluationResult => _result;
- void set evaluationResult(EvaluationResultImpl result2) {
- this._result = result2;
+ void set evaluationResult(EvaluationResultImpl result) {
+ this._result = result;
}
}
/**
@@ -2450,8 +2450,8 @@
*/
ConstLocalVariableElementImpl(Identifier name) : super(name);
EvaluationResultImpl get evaluationResult => _result;
- void set evaluationResult(EvaluationResultImpl result2) {
- this._result = result2;
+ void set evaluationResult(EvaluationResultImpl result) {
+ this._result = result;
}
}
/**
@@ -2472,8 +2472,8 @@
*/
ConstTopLevelVariableElementImpl(Identifier name) : super.con1(name);
EvaluationResultImpl get evaluationResult => _result;
- void set evaluationResult(EvaluationResultImpl result2) {
- this._result = result2;
+ void set evaluationResult(EvaluationResultImpl result) {
+ this._result = result;
}
}
/**
@@ -2542,8 +2542,8 @@
*
* @param redirectedConstructor the constructor to which this constructor is redirecting
*/
- void set redirectedConstructor(ConstructorElement redirectedConstructor2) {
- this._redirectedConstructor = redirectedConstructor2;
+ void set redirectedConstructor(ConstructorElement redirectedConstructor) {
+ this._redirectedConstructor = redirectedConstructor;
}
void appendTo(JavaStringBuilder builder) {
builder.append(enclosingElement.displayName);
@@ -2575,8 +2575,8 @@
*/
DefaultFieldFormalParameterElementImpl(Identifier name) : super(name);
EvaluationResultImpl get evaluationResult => _result;
- void set evaluationResult(EvaluationResultImpl result2) {
- this._result = result2;
+ void set evaluationResult(EvaluationResultImpl result) {
+ this._result = result;
}
}
/**
@@ -2599,8 +2599,8 @@
*/
DefaultParameterElementImpl(Identifier name) : super.con1(name);
EvaluationResultImpl get evaluationResult => _result;
- void set evaluationResult(EvaluationResultImpl result2) {
- this._result = result2;
+ void set evaluationResult(EvaluationResultImpl result) {
+ this._result = result;
}
}
/**
@@ -2770,9 +2770,9 @@
}
return _cachedHashCode;
}
- bool isAccessibleIn(LibraryElement library2) {
+ bool isAccessibleIn(LibraryElement library) {
if (Identifier.isPrivateName(_name)) {
- return library2 == library;
+ return library == this.library;
}
return true;
}
@@ -2783,8 +2783,8 @@
*
* @param metadata the metadata to be associated with this element
*/
- void set metadata(List<ElementAnnotation> metadata2) {
- this._metadata = metadata2;
+ void set metadata(List<ElementAnnotation> metadata) {
+ this._metadata = metadata;
}
/**
@@ -2794,8 +2794,8 @@
*
* @param nameOffset the offset to the beginning of the name
*/
- void set nameOffset(int nameOffset2) {
- this._nameOffset = nameOffset2;
+ void set nameOffset(int nameOffset) {
+ this._nameOffset = nameOffset;
}
/**
@@ -3092,9 +3092,9 @@
*
* @param scriptLibrary the library or `null` if none
*/
- void set scriptLibrary(LibraryElementImpl scriptLibrary2) {
- scriptLibrary2.enclosingElement = this;
- this._scriptLibrary = scriptLibrary2;
+ void set scriptLibrary(LibraryElementImpl scriptLibrary) {
+ scriptLibrary.enclosingElement = this;
+ this._scriptLibrary = scriptLibrary;
}
void visitChildren(ElementVisitor visitor) {
safelyVisitChild(_scriptLibrary, visitor);
@@ -3158,24 +3158,24 @@
* declaration of this element
*/
ExecutableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset);
- ElementImpl getChild(String identifier2) {
+ ElementImpl getChild(String identifier) {
for (ExecutableElement function in _functions) {
- if (((function as ExecutableElementImpl)).identifier == identifier2) {
+ if (((function as ExecutableElementImpl)).identifier == identifier) {
return function as ExecutableElementImpl;
}
}
for (LabelElement label in _labels) {
- if (((label as LabelElementImpl)).identifier == identifier2) {
+ if (((label as LabelElementImpl)).identifier == identifier) {
return label as LabelElementImpl;
}
}
for (VariableElement variable in _localVariables) {
- if (((variable as VariableElementImpl)).identifier == identifier2) {
+ if (((variable as VariableElementImpl)).identifier == identifier) {
return variable as VariableElementImpl;
}
}
for (ParameterElement parameter in _parameters) {
- if (((parameter as ParameterElementImpl)).identifier == identifier2) {
+ if (((parameter as ParameterElementImpl)).identifier == identifier) {
return parameter as ParameterElementImpl;
}
}
@@ -3194,11 +3194,11 @@
*
* @param functions the functions defined within this executable element
*/
- void set functions(List<FunctionElement> functions2) {
- for (FunctionElement function in functions2) {
+ void set functions(List<FunctionElement> functions) {
+ for (FunctionElement function in functions) {
((function as FunctionElementImpl)).enclosingElement = this;
}
- this._functions = functions2;
+ this._functions = functions;
}
/**
@@ -3206,11 +3206,11 @@
*
* @param labels the labels defined within this executable element
*/
- void set labels(List<LabelElement> labels2) {
- for (LabelElement label in labels2) {
+ void set labels(List<LabelElement> labels) {
+ for (LabelElement label in labels) {
((label as LabelElementImpl)).enclosingElement = this;
}
- this._labels = labels2;
+ this._labels = labels;
}
/**
@@ -3218,11 +3218,11 @@
*
* @param localVariables the local variables defined within this executable element
*/
- void set localVariables(List<LocalVariableElement> localVariables2) {
- for (LocalVariableElement variable in localVariables2) {
+ void set localVariables(List<LocalVariableElement> localVariables) {
+ for (LocalVariableElement variable in localVariables) {
((variable as LocalVariableElementImpl)).enclosingElement = this;
}
- this._localVariables = localVariables2;
+ this._localVariables = localVariables;
}
/**
@@ -3230,11 +3230,11 @@
*
* @param parameters the parameters defined by this executable element
*/
- void set parameters(List<ParameterElement> parameters2) {
- for (ParameterElement parameter in parameters2) {
+ void set parameters(List<ParameterElement> parameters) {
+ for (ParameterElement parameter in parameters) {
((parameter as ParameterElementImpl)).enclosingElement = this;
}
- this._parameters = parameters2;
+ this._parameters = parameters;
}
/**
@@ -3242,8 +3242,8 @@
*
* @param returnType the return type defined by this executable element
*/
- void set returnType(Type2 returnType2) {
- this._returnType = returnType2;
+ void set returnType(Type2 returnType) {
+ this._returnType = returnType;
}
/**
@@ -3251,8 +3251,8 @@
*
* @param type the type of function defined by this executable element
*/
- void set type(FunctionType type2) {
- this._type = type2;
+ void set type(FunctionType type) {
+ this._type = type;
}
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
@@ -3316,8 +3316,8 @@
*
* @param combinators the combinators that were specified as part of the export directive
*/
- void set combinators(List<NamespaceCombinator> combinators2) {
- this._combinators = combinators2;
+ void set combinators(List<NamespaceCombinator> combinators) {
+ this._combinators = combinators;
}
/**
@@ -3326,8 +3326,8 @@
*
* @param exportedLibrary the library that is exported from this library
*/
- void set exportedLibrary(LibraryElement exportedLibrary2) {
- this._exportedLibrary = exportedLibrary2;
+ void set exportedLibrary(LibraryElement exportedLibrary) {
+ this._exportedLibrary = exportedLibrary;
}
/**
@@ -3335,8 +3335,8 @@
*
* @param uri the URI that is specified by this directive.
*/
- void set uri(String uri2) {
- this._uri = uri2;
+ void set uri(String uri) {
+ this._uri = uri;
}
void appendTo(JavaStringBuilder builder) {
builder.append("export ");
@@ -3372,8 +3372,8 @@
*
* @param scriptSource the script source or `null` if unspecified
*/
- void set scriptSource(Source scriptSource2) {
- this._scriptSource = scriptSource2;
+ void set scriptSource(Source scriptSource) {
+ this._scriptSource = scriptSource;
}
}
/**
@@ -3444,8 +3444,8 @@
*
* @param field the new field element
*/
- void set field(FieldElement field2) {
- this._field = field2;
+ void set field(FieldElement field) {
+ this._field = field;
}
}
/**
@@ -3564,14 +3564,14 @@
*/
FunctionTypeAliasElementImpl(Identifier name) : super.con1(name);
accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
- ElementImpl getChild(String identifier2) {
+ ElementImpl getChild(String identifier) {
for (VariableElement parameter in _parameters) {
- if (((parameter as VariableElementImpl)).identifier == identifier2) {
+ if (((parameter as VariableElementImpl)).identifier == identifier) {
return parameter as VariableElementImpl;
}
}
for (TypeParameterElement typeParameter in _typeParameters) {
- if (((typeParameter as TypeParameterElementImpl)).identifier == identifier2) {
+ if (((typeParameter as TypeParameterElementImpl)).identifier == identifier) {
return typeParameter as TypeParameterElementImpl;
}
}
@@ -3589,13 +3589,13 @@
*
* @param parameters the parameters defined by this type alias
*/
- void set parameters(List<ParameterElement> parameters2) {
- if (parameters2 != null) {
- for (ParameterElement parameter in parameters2) {
+ void set parameters(List<ParameterElement> parameters) {
+ if (parameters != null) {
+ for (ParameterElement parameter in parameters) {
((parameter as ParameterElementImpl)).enclosingElement = this;
}
}
- this._parameters = parameters2;
+ this._parameters = parameters;
}
/**
@@ -3603,8 +3603,8 @@
*
* @param returnType the return type defined by this type alias
*/
- void set returnType(Type2 returnType2) {
- this._returnType = returnType2;
+ void set returnType(Type2 returnType) {
+ this._returnType = returnType;
}
/**
@@ -3612,8 +3612,8 @@
*
* @param type the type of function defined by this type alias
*/
- void set type(FunctionType type2) {
- this._type = type2;
+ void set type(FunctionType type) {
+ this._type = type;
}
/**
@@ -3621,11 +3621,11 @@
*
* @param typeParameters the type parameters defined for this type
*/
- void set typeParameters(List<TypeParameterElement> typeParameters2) {
- for (TypeParameterElement typeParameter in typeParameters2) {
+ void set typeParameters(List<TypeParameterElement> typeParameters) {
+ for (TypeParameterElement typeParameter in typeParameters) {
((typeParameter as TypeParameterElementImpl)).enclosingElement = this;
}
- this._typeParameters = typeParameters2;
+ this._typeParameters = typeParameters;
}
/**
@@ -3635,8 +3635,8 @@
*
* @param parameters the parameters defined by this type alias
*/
- void shareParameters(List<ParameterElement> parameters2) {
- this._parameters = parameters2;
+ void shareParameters(List<ParameterElement> parameters) {
+ this._parameters = parameters;
}
/**
@@ -3646,8 +3646,8 @@
*
* @param typeParameters the type parameters defined for this type
*/
- void shareTypeParameters(List<TypeParameterElement> typeParameters2) {
- this._typeParameters = typeParameters2;
+ void shareTypeParameters(List<TypeParameterElement> typeParameters) {
+ this._typeParameters = typeParameters;
}
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
@@ -3704,8 +3704,8 @@
*
* @param hiddenNames the names that are not to be made visible in the importing library
*/
- void set hiddenNames(List<String> hiddenNames2) {
- this._hiddenNames = hiddenNames2;
+ void set hiddenNames(List<String> hiddenNames) {
+ this._hiddenNames = hiddenNames;
}
String toString() {
JavaStringBuilder builder = new JavaStringBuilder();
@@ -3769,14 +3769,14 @@
*
* @param scripts the scripts
*/
- void set scripts(List<HtmlScriptElement> scripts2) {
- if (scripts2.length == 0) {
- scripts2 = HtmlScriptElementImpl.EMPTY_ARRAY;
+ void set scripts(List<HtmlScriptElement> scripts) {
+ if (scripts.length == 0) {
+ scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
}
- for (HtmlScriptElement script in scripts2) {
+ for (HtmlScriptElement script in scripts) {
((script as HtmlScriptElementImpl)).enclosingElement = this;
}
- this._scripts = scripts2;
+ this._scripts = scripts;
}
/**
@@ -3784,8 +3784,8 @@
*
* @param source the source that corresponds to this HTML file
*/
- void set source(Source source2) {
- this._source = source2;
+ void set source(Source source) {
+ this._source = source;
}
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
@@ -3864,8 +3864,8 @@
*
* @param combinators the combinators that were specified as part of the import directive
*/
- void set combinators(List<NamespaceCombinator> combinators2) {
- this._combinators = combinators2;
+ void set combinators(List<NamespaceCombinator> combinators) {
+ this._combinators = combinators;
}
/**
@@ -3874,8 +3874,8 @@
*
* @param importedLibrary the library that is imported into this library
*/
- void set importedLibrary(LibraryElement importedLibrary2) {
- this._importedLibrary = importedLibrary2;
+ void set importedLibrary(LibraryElement importedLibrary) {
+ this._importedLibrary = importedLibrary;
}
/**
@@ -3883,8 +3883,8 @@
*
* @param prefix the prefix that was specified as part of the import directive
*/
- void set prefix(PrefixElement prefix2) {
- this._prefix = prefix2;
+ void set prefix(PrefixElement prefix) {
+ this._prefix = prefix;
}
/**
@@ -3892,8 +3892,8 @@
*
* @param uri the URI that is specified by this directive.
*/
- void set uri(String uri2) {
- this._uri = uri2;
+ void set uri(String uri) {
+ this._uri = uri;
}
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
@@ -4030,22 +4030,22 @@
}
accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
bool operator ==(Object object) => object != null && runtimeType == object.runtimeType && _definingCompilationUnit == ((object as LibraryElementImpl)).definingCompilationUnit;
- ElementImpl getChild(String identifier2) {
- if (((_definingCompilationUnit as CompilationUnitElementImpl)).identifier == identifier2) {
+ ElementImpl getChild(String identifier) {
+ if (((_definingCompilationUnit as CompilationUnitElementImpl)).identifier == identifier) {
return _definingCompilationUnit as CompilationUnitElementImpl;
}
for (CompilationUnitElement part in _parts) {
- if (((part as CompilationUnitElementImpl)).identifier == identifier2) {
+ if (((part as CompilationUnitElementImpl)).identifier == identifier) {
return part as CompilationUnitElementImpl;
}
}
for (ImportElement importElement in _imports) {
- if (((importElement as ImportElementImpl)).identifier == identifier2) {
+ if (((importElement as ImportElementImpl)).identifier == identifier) {
return importElement as ImportElementImpl;
}
}
for (ExportElement exportElement in _exports) {
- if (((exportElement as ExportElementImpl)).identifier == identifier2) {
+ if (((exportElement as ExportElementImpl)).identifier == identifier) {
return exportElement as ExportElementImpl;
}
}
@@ -4123,9 +4123,9 @@
*
* @param definingCompilationUnit the compilation unit that defines this library
*/
- void set definingCompilationUnit(CompilationUnitElement definingCompilationUnit2) {
- ((definingCompilationUnit2 as CompilationUnitElementImpl)).enclosingElement = this;
- this._definingCompilationUnit = definingCompilationUnit2;
+ void set definingCompilationUnit(CompilationUnitElement definingCompilationUnit) {
+ ((definingCompilationUnit as CompilationUnitElementImpl)).enclosingElement = this;
+ this._definingCompilationUnit = definingCompilationUnit;
}
/**
@@ -4133,8 +4133,8 @@
*
* @param entryPoint the entry point for this library
*/
- void set entryPoint(FunctionElement entryPoint2) {
- this._entryPoint = entryPoint2;
+ void set entryPoint(FunctionElement entryPoint) {
+ this._entryPoint = entryPoint;
}
/**
@@ -4142,11 +4142,11 @@
*
* @param exports the specifications of all of the exports defined in this library
*/
- void set exports(List<ExportElement> exports2) {
- for (ExportElement exportElement in exports2) {
+ void set exports(List<ExportElement> exports) {
+ for (ExportElement exportElement in exports) {
((exportElement as ExportElementImpl)).enclosingElement = this;
}
- this._exports = exports2;
+ this._exports = exports;
}
/**
@@ -4154,15 +4154,15 @@
*
* @param imports the specifications of all of the imports defined in this library
*/
- void set imports(List<ImportElement> imports2) {
- for (ImportElement importElement in imports2) {
+ void set imports(List<ImportElement> imports) {
+ for (ImportElement importElement in imports) {
((importElement as ImportElementImpl)).enclosingElement = this;
PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
if (prefix != null) {
prefix.enclosingElement = this;
}
}
- this._imports = imports2;
+ this._imports = imports;
}
/**
@@ -4171,11 +4171,11 @@
* @param parts the compilation units that are included in this library using a `part`
* directive
*/
- void set parts(List<CompilationUnitElement> parts2) {
- for (CompilationUnitElement compilationUnit in parts2) {
+ void set parts(List<CompilationUnitElement> parts) {
+ for (CompilationUnitElement compilationUnit in parts) {
((compilationUnit as CompilationUnitElementImpl)).enclosingElement = this;
}
- this._parts = parts2;
+ this._parts = parts;
}
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
@@ -4593,8 +4593,8 @@
*
* @param parameterKind the new kind of this parameter
*/
- void set parameterKind(ParameterKind parameterKind2) {
- this._parameterKind = parameterKind2;
+ void set parameterKind(ParameterKind parameterKind) {
+ this._parameterKind = parameterKind;
}
/**
@@ -4602,11 +4602,11 @@
*
* @param parameters the parameters defined by this executable element
*/
- void set parameters(List<ParameterElement> parameters2) {
- for (ParameterElement parameter in parameters2) {
+ void set parameters(List<ParameterElement> parameters) {
+ for (ParameterElement parameter in parameters) {
((parameter as ParameterElementImpl)).enclosingElement = this;
}
- this._parameters = parameters2;
+ this._parameters = parameters;
}
/**
@@ -4678,16 +4678,17 @@
*
* @param importedLibraries the libraries that are imported using this prefix
*/
- void set importedLibraries(List<LibraryElement> importedLibraries2) {
- for (LibraryElement library in importedLibraries2) {
+ void set importedLibraries(List<LibraryElement> importedLibraries) {
+ for (LibraryElement library in importedLibraries) {
((library as LibraryElementImpl)).enclosingElement = this;
}
- this._importedLibraries = importedLibraries2;
+ this._importedLibraries = importedLibraries;
}
void appendTo(JavaStringBuilder builder) {
builder.append("as ");
super.appendTo(builder);
}
+ String get identifier => "_${super.identifier}";
}
/**
* Instances of the class `PropertyAccessorElementImpl` implement a
@@ -4797,8 +4798,8 @@
*
* @param variable the variable associated with this accessor
*/
- void set variable(PropertyInducingElement variable2) {
- this._variable = variable2;
+ void set variable(PropertyInducingElement variable) {
+ this._variable = variable;
}
void appendTo(JavaStringBuilder builder) {
builder.append(isGetter ? "get " : "set ");
@@ -4853,8 +4854,8 @@
*
* @param getter the getter associated with this element
*/
- void set getter(PropertyAccessorElement getter2) {
- this._getter = getter2;
+ void set getter(PropertyAccessorElement getter) {
+ this._getter = getter;
}
/**
@@ -4862,8 +4863,8 @@
*
* @param setter the setter associated with this element
*/
- void set setter(PropertyAccessorElement setter2) {
- this._setter = setter2;
+ void set setter(PropertyAccessorElement setter) {
+ this._setter = setter;
}
}
/**
@@ -4887,8 +4888,8 @@
*
* @param shownNames the names that are to be made visible in the importing library
*/
- void set shownNames(List<String> shownNames2) {
- this._shownNames = shownNames2;
+ void set shownNames(List<String> shownNames) {
+ this._shownNames = shownNames;
}
String toString() {
JavaStringBuilder builder = new JavaStringBuilder();
@@ -4972,8 +4973,8 @@
*
* @param bound the type representing the bound associated with this parameter
*/
- void set bound(Type2 bound2) {
- this._bound = bound2;
+ void set bound(Type2 bound) {
+ this._bound = bound;
}
/**
@@ -4981,8 +4982,8 @@
*
* @param type the type defined by this type parameter
*/
- void set type(TypeParameterType type2) {
- this._type = type2;
+ void set type(TypeParameterType type) {
+ this._type = type;
}
void appendTo(JavaStringBuilder builder) {
builder.append(displayName);
@@ -5077,11 +5078,11 @@
*
* @param initializer the function representing this variable's initializer
*/
- void set initializer(FunctionElement initializer2) {
- if (initializer2 != null) {
- ((initializer2 as FunctionElementImpl)).enclosingElement = this;
+ void set initializer(FunctionElement initializer) {
+ if (initializer != null) {
+ ((initializer as FunctionElementImpl)).enclosingElement = this;
}
- this._initializer = initializer2;
+ this._initializer = initializer;
}
/**
@@ -5089,8 +5090,8 @@
*
* @param type the declared type of this variable
*/
- void set type(Type2 type2) {
- this._type = type2;
+ void set type(Type2 type) {
+ this._type = type;
}
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
@@ -6013,8 +6014,8 @@
*
* @param typeArguments the actual types of the type arguments
*/
- void set typeArguments(List<Type2> typeArguments2) {
- this._typeArguments = typeArguments2;
+ void set typeArguments(List<Type2> typeArguments) {
+ this._typeArguments = typeArguments;
}
FunctionTypeImpl substitute3(List<Type2> argumentTypes) => substitute2(argumentTypes, typeArguments);
FunctionTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
@@ -6480,24 +6481,24 @@
return isMoreSpecificThan2(type as InterfaceType, new Set<ClassElement>());
}
bool get isObject => element.supertype == null;
- bool isSubtypeOf(Type2 type2) {
- if (identical(type2, DynamicTypeImpl.instance)) {
+ bool isSubtypeOf(Type2 type) {
+ if (identical(type, DynamicTypeImpl.instance)) {
return true;
- } else if (type2 is TypeParameterType) {
+ } else if (type is TypeParameterType) {
return true;
- } else if (type2 is FunctionType) {
+ } else if (type is FunctionType) {
ClassElement element = this.element;
MethodElement callMethod = element.lookUpMethod("call", element.library);
if (callMethod != null) {
- return callMethod.type.isSubtypeOf(type2);
+ return callMethod.type.isSubtypeOf(type);
}
return false;
- } else if (type2 is! InterfaceType) {
+ } else if (type is! InterfaceType) {
return false;
- } else if (this == type2) {
+ } else if (this == type) {
return true;
}
- return isSubtypeOf2(type2 as InterfaceType, new Set<ClassElement>());
+ return isSubtypeOf2(type as InterfaceType, new Set<ClassElement>());
}
ConstructorElement lookUpConstructor(String constructorName, LibraryElement library) {
ConstructorElement constructorElement;
@@ -6619,8 +6620,8 @@
*
* @param typeArguments the actual types of the type arguments
*/
- void set typeArguments(List<Type2> typeArguments2) {
- this._typeArguments = typeArguments2;
+ void set typeArguments(List<Type2> typeArguments) {
+ this._typeArguments = typeArguments;
}
InterfaceTypeImpl substitute4(List<Type2> argumentTypes) => substitute2(argumentTypes, typeArguments);
InterfaceTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
@@ -6659,7 +6660,7 @@
if (s.isDirectSupertypeOf(this)) {
return true;
}
- ClassElement tElement = element;
+ ClassElement tElement = this.element;
ClassElement sElement = s.element;
if (tElement == sElement) {
List<Type2> tArguments = typeArguments;
@@ -6695,9 +6696,9 @@
}
return false;
}
- bool isSubtypeOf2(InterfaceType type2, Set<ClassElement> visitedClasses) {
+ bool isSubtypeOf2(InterfaceType type, Set<ClassElement> visitedClasses) {
InterfaceType typeT = this;
- InterfaceType typeS = type2;
+ InterfaceType typeS = type;
ClassElement elementT = element;
if (elementT == null || visitedClasses.contains(elementT)) {
return false;
diff --git a/pkg/analyzer_experimental/lib/src/generated/engine.dart b/pkg/analyzer_experimental/lib/src/generated/engine.dart
index 1d8b5f8..84f6f56 100644
--- a/pkg/analyzer_experimental/lib/src/generated/engine.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/engine.dart
@@ -101,8 +101,8 @@
* @param logger the logger that should receive information about errors within the analysis
* engine
*/
- void set logger(Logger logger2) {
- this._logger = logger2 == null ? Logger.NULL : logger2;
+ void set logger(Logger logger) {
+ this._logger = logger == null ? Logger.NULL : logger;
}
}
/**
@@ -1440,10 +1440,10 @@
return super.getState(descriptor);
}
}
- CacheState getState2(DataDescriptor descriptor, Source librarySource2) {
+ CacheState getState2(DataDescriptor descriptor, Source librarySource) {
DartEntryImpl_ResolutionState state = _resolutionState;
while (state != null) {
- if (librarySource2 == state._librarySource) {
+ if (librarySource == state._librarySource) {
if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
return state._resolutionErrorsState;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
@@ -1488,10 +1488,10 @@
}
return super.getValue(descriptor);
}
- Object getValue2(DataDescriptor descriptor, Source librarySource2) {
+ Object getValue2(DataDescriptor descriptor, Source librarySource) {
DartEntryImpl_ResolutionState state = _resolutionState;
while (state != null) {
- if (librarySource2 == state._librarySource) {
+ if (librarySource == state._librarySource) {
if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
return state._resolutionErrors as Object;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
@@ -1676,9 +1676,9 @@
* @param librarySource the source of the defining compilation unit of the library that used to
* contain this part but no longer does
*/
- void removeResolution(Source librarySource2) {
- if (librarySource2 != null) {
- if (librarySource2 == _resolutionState._librarySource) {
+ void removeResolution(Source librarySource) {
+ if (librarySource != null) {
+ if (librarySource == _resolutionState._librarySource) {
if (_resolutionState._nextState == null) {
_resolutionState.invalidateAllResolutionInformation();
} else {
@@ -1688,7 +1688,7 @@
DartEntryImpl_ResolutionState priorState = _resolutionState;
DartEntryImpl_ResolutionState state = _resolutionState._nextState;
while (state != null) {
- if (librarySource2 == state._librarySource) {
+ if (librarySource == state._librarySource) {
priorState._nextState = state._nextState;
break;
}
@@ -1904,16 +1904,16 @@
* @param librarySource the library source (not `null`)
* @return the resolution state (not `null`)
*/
- DartEntryImpl_ResolutionState getOrCreateResolutionState(Source librarySource2) {
+ DartEntryImpl_ResolutionState getOrCreateResolutionState(Source librarySource) {
DartEntryImpl_ResolutionState state = _resolutionState;
if (state._librarySource == null) {
- state._librarySource = librarySource2;
+ state._librarySource = librarySource;
return state;
}
- while (state._librarySource != librarySource2) {
+ while (state._librarySource != librarySource) {
if (state._nextState == null) {
DartEntryImpl_ResolutionState newState = new DartEntryImpl_ResolutionState();
- newState._librarySource = librarySource2;
+ newState._librarySource = librarySource;
state._nextState = newState;
return newState;
}
@@ -2484,8 +2484,8 @@
*
* @param exception the exception that caused one or more values to be uncomputable
*/
- void set exception(AnalysisException exception2) {
- this._exception = exception2;
+ void set exception(AnalysisException exception) {
+ this._exception = exception;
}
/**
@@ -2779,6 +2779,7 @@
return null;
}
List<AnalysisError> computeErrors(Source source) {
+ bool enableHints = analysisOptions.hint;
SourceEntry sourceEntry = getReadableSourceEntry(source);
if (sourceEntry is DartEntry) {
List<AnalysisError> errors = new List<AnalysisError>();
@@ -2787,12 +2788,16 @@
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));
+ if (enableHints) {
+ 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 (enableHints) {
+ ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS));
+ }
}
}
if (errors.isEmpty) {
@@ -3305,9 +3310,9 @@
}
CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) => getDartResolutionData2(unitSource, librarySource, DartEntry.RESOLVED_UNIT, null);
HtmlUnit resolveHtmlUnit(Source htmlSource) => parseHtmlUnit(htmlSource);
- void set analysisOptions(AnalysisOptions options2) {
+ void set analysisOptions(AnalysisOptions options) {
{
- this._options = options2;
+ this._options = options;
invalidateAllResolutionInformation();
}
}
@@ -3983,11 +3988,11 @@
* @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> getSources(SourceKind kind) {
List<Source> sources = new List<Source>();
{
for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
- if (identical(entry.getValue().kind, kind2)) {
+ if (identical(entry.getValue().kind, kind)) {
sources.add(entry.getKey());
}
}
@@ -4102,7 +4107,7 @@
*/
DartEntry recordGenerateDartHintsTask(GenerateDartHintsTask task) {
Source librarySource = task.libraryElement.source;
- AnalysisException thrownException = task.thrownException;
+ AnalysisException thrownException = task.exception;
DartEntry libraryEntry = null;
Map<Source, TimestampedData<List<AnalysisError>>> hintMap = task.hintMap;
if (hintMap == null) {
@@ -4186,7 +4191,7 @@
*/
DartEntry recordParseDartTaskResults(ParseDartTask task) {
Source source = task.source;
- AnalysisException thrownException = task.thrownException;
+ AnalysisException thrownException = task.exception;
DartEntry dartEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
@@ -4253,7 +4258,7 @@
*/
HtmlEntry recordParseHtmlTaskResults(ParseHtmlTask task) {
Source source = task.source;
- AnalysisException thrownException = task.thrownException;
+ AnalysisException thrownException = task.exception;
HtmlEntry htmlEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
@@ -4327,7 +4332,7 @@
*/
DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
LibraryResolver resolver = task.libraryResolver;
- AnalysisException thrownException = task.thrownException;
+ AnalysisException thrownException = task.exception;
DartEntry unitEntry = null;
Source unitSource = task.unitSource;
if (resolver != null) {
@@ -4419,7 +4424,7 @@
SourceEntry recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
Source unitSource = task.source;
Source librarySource = task.librarySource;
- AnalysisException thrownException = task.thrownException;
+ AnalysisException thrownException = task.exception;
DartEntry dartEntry = null;
{
SourceEntry sourceEntry = _cache.get(unitSource);
@@ -4477,7 +4482,7 @@
*/
SourceEntry recordResolveHtmlTaskResults(ResolveHtmlTask task) {
Source source = task.source;
- AnalysisException thrownException = task.thrownException;
+ AnalysisException thrownException = task.exception;
HtmlEntry htmlEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
@@ -4700,8 +4705,8 @@
*
* @param hint `true` if analysis is to generate hint results
*/
- void set hint(bool hint2) {
- this._hint = hint2;
+ void set hint(bool hint) {
+ this._hint = hint;
}
/**
@@ -4794,8 +4799,8 @@
*
* @param compilationUnit the fully resolved AST that changed as a result of the analysis
*/
- void set compilationUnit(CompilationUnit compilationUnit2) {
- this._compilationUnit = compilationUnit2;
+ void set compilationUnit(CompilationUnit compilationUnit) {
+ this._compilationUnit = compilationUnit;
}
/**
@@ -4805,9 +4810,9 @@
* @param errors the errors that changed as a result of the analysis
* @param lineInfo the line information associated with the source
*/
- void setErrors(List<AnalysisError> errors2, LineInfo lineInfo2) {
- this._errors = errors2;
- this._lineInfo = lineInfo2;
+ void setErrors(List<AnalysisError> errors, LineInfo lineInfo) {
+ this._errors = errors;
+ this._lineInfo = lineInfo;
}
}
/**
@@ -5927,7 +5932,7 @@
* The exception that was thrown while performing this task, or `null` if the task completed
* successfully.
*/
- AnalysisException thrownException;
+ AnalysisException exception;
/**
* Initialize a newly created task to perform analysis within the given context.
@@ -5958,7 +5963,7 @@
try {
safelyPerform();
} on AnalysisException catch (exception) {
- thrownException = exception;
+ this.exception = exception;
AnalysisEngine.instance.logger.logInformation2("Task failed: ${taskDescription}", exception);
}
return accept(visitor);
@@ -6325,14 +6330,14 @@
RecordingErrorListener errorListener;
List<Token> token;
Source_ContentReceiver_9(this.ParseDartTask_this, this.errorListener, this.token);
- void accept(CharBuffer contents, int modificationTime2) {
- ParseDartTask_this.modificationTime = modificationTime2;
+ void accept(CharBuffer contents, int modificationTime) {
+ ParseDartTask_this.modificationTime = modificationTime;
CharBufferScanner scanner = new CharBufferScanner(ParseDartTask_this.source, contents, errorListener);
token[0] = scanner.tokenize();
ParseDartTask_this.lineInfo = new LineInfo(scanner.lineStarts);
}
- void accept2(String contents, int modificationTime2) {
- ParseDartTask_this.modificationTime = modificationTime2;
+ void accept2(String contents, int modificationTime) {
+ ParseDartTask_this.modificationTime = modificationTime;
StringScanner scanner = new StringScanner(ParseDartTask_this.source, contents, errorListener);
token[0] = scanner.tokenize();
ParseDartTask_this.lineInfo = new LineInfo(scanner.lineStarts);
diff --git a/pkg/analyzer_experimental/lib/src/generated/error.dart b/pkg/analyzer_experimental/lib/src/generated/error.dart
index b57ab78..7c5d24d 100644
--- a/pkg/analyzer_experimental/lib/src/generated/error.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/error.dart
@@ -206,8 +206,8 @@
*
* @param source the source to be used when reporting errors
*/
- void set source(Source source2) {
- this._source = source2 == null ? _defaultSource : source2;
+ void set source(Source source) {
+ this._source = source == null ? _defaultSource : source;
}
}
/**
@@ -478,24 +478,68 @@
static final HintCode TYPE_CHECK_IS_NULL = new HintCode.con1('TYPE_CHECK_IS_NULL', 12, "Tests for null should be done with '== null'");
/**
+ * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_GETTER] or
+ * [StaticWarningCode#UNDEFINED_GETTER] would have been generated, if we used propagated
+ * information for the warnings.
+ *
+ * @param getterName the name of the getter
+ * @param enclosingType the name of the enclosing type where the getter is being looked for
+ * @see StaticTypeWarningCode#UNDEFINED_GETTER
+ * @see StaticWarningCode#UNDEFINED_GETTER
+ */
+ static final HintCode UNDEFINED_GETTER = new HintCode.con1('UNDEFINED_GETTER', 13, StaticTypeWarningCode.UNDEFINED_GETTER.message);
+
+ /**
+ * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_METHOD] would
+ * have been generated, if we used propagated information for the warnings.
+ *
+ * @param methodName the name of the method that is undefined
+ * @param typeName the resolved type name that the method lookup is happening on
+ * @see StaticTypeWarningCode#UNDEFINED_METHOD
+ */
+ static final HintCode UNDEFINED_METHOD = new HintCode.con1('UNDEFINED_METHOD', 14, StaticTypeWarningCode.UNDEFINED_METHOD.message);
+
+ /**
+ * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_OPERATOR]
+ * would have been generated, if we used propagated information for the warnings.
+ *
+ * @param operator the name of the operator
+ * @param enclosingType the name of the enclosing type where the operator is being looked for
+ * @see StaticTypeWarningCode#UNDEFINED_OPERATOR
+ */
+ static final HintCode UNDEFINED_OPERATOR = new HintCode.con1('UNDEFINED_OPERATOR', 15, StaticTypeWarningCode.UNDEFINED_OPERATOR.message);
+
+ /**
+ * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_SETTER] or
+ * [StaticWarningCode#UNDEFINED_SETTER] would have been generated, if we used propagated
+ * information for the warnings.
+ *
+ * @param setterName the name of the setter
+ * @param enclosingType the name of the enclosing type where the setter is being looked for
+ * @see StaticTypeWarningCode#UNDEFINED_SETTER
+ * @see StaticWarningCode#UNDEFINED_SETTER
+ */
+ static final HintCode UNDEFINED_SETTER = new HintCode.con1('UNDEFINED_SETTER', 16, StaticTypeWarningCode.UNDEFINED_SETTER.message);
+
+ /**
* Unnecessary cast.
*/
- static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 13, "Unnecessary cast");
+ static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 17, "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");
+ static final HintCode UNNECESSARY_TYPE_CHECK_FALSE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_FALSE', 18, "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");
+ static final HintCode UNNECESSARY_TYPE_CHECK_TRUE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_TRUE', 19, "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', 16, "Unused import");
+ static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 20, "Unused import");
static final List<HintCode> values = [
DEAD_CODE,
DEAD_CODE_CATCH_FOLLOWING_CATCH,
@@ -510,6 +554,10 @@
OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
TYPE_CHECK_IS_NOT_NULL,
TYPE_CHECK_IS_NULL,
+ UNDEFINED_GETTER,
+ UNDEFINED_METHOD,
+ UNDEFINED_OPERATOR,
+ UNDEFINED_SETTER,
UNNECESSARY_CAST,
UNNECESSARY_TYPE_CHECK_FALSE,
UNNECESSARY_TYPE_CHECK_TRUE,
@@ -2793,6 +2841,8 @@
* <i>id</i> occurs inside a top level or static function (be it function, method, getter, or
* setter) or variable initializer and there is no declaration <i>d</i> with name <i>id</i> in the
* lexical scope enclosing the expression.
+ *
+ * @param name the name of the identifier
*/
static final StaticWarningCode UNDEFINED_IDENTIFIER = new StaticWarningCode.con1('UNDEFINED_IDENTIFIER', 72, "Undefined name '%s'");
diff --git a/pkg/analyzer_experimental/lib/src/generated/html.dart b/pkg/analyzer_experimental/lib/src/generated/html.dart
index a6c4a4e..f5286bc 100644
--- a/pkg/analyzer_experimental/lib/src/generated/html.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/html.dart
@@ -210,7 +210,7 @@
if (beginToken == null) {
return -1;
}
- return beginToken.offset;
+ return this.beginToken.offset;
}
/**
@@ -397,8 +397,8 @@
/**
* Set array of element tags for which the content between tags should be consider a single token.
*/
- void set passThroughElements(List<String> passThroughElements2) {
- this._passThroughElements = passThroughElements2 != null ? passThroughElements2 : _NO_PASS_THROUGH_ELEMENTS;
+ void set passThroughElements(List<String> passThroughElements) {
+ this._passThroughElements = passThroughElements != null ? passThroughElements : _NO_PASS_THROUGH_ELEMENTS;
}
/**
@@ -694,8 +694,8 @@
this._charOffset = -1;
}
int get offset => _charOffset;
- void set offset(int offset2) {
- _charOffset = offset2;
+ void set offset(int offset) {
+ _charOffset = offset;
}
int advance() {
if (++_charOffset < _stringLength) {
@@ -999,14 +999,14 @@
HtmlScanner(Source source) {
this._source = source;
}
- void accept(CharBuffer contents, int modificationTime2) {
- this._modificationTime = modificationTime2;
+ void accept(CharBuffer contents, int modificationTime) {
+ this._modificationTime = modificationTime;
_scanner = new CharBufferScanner(_source, contents);
_scanner.passThroughElements = _SCRIPT_TAG;
_token = _scanner.tokenize();
}
- void accept2(String contents, int modificationTime2) {
- this._modificationTime = modificationTime2;
+ void accept2(String contents, int modificationTime) {
+ this._modificationTime = modificationTime;
_scanner = new StringScanner(_source, contents);
_scanner.passThroughElements = _SCRIPT_TAG;
_token = _scanner.tokenize();
@@ -1354,9 +1354,9 @@
* @param name the attribute name
* @return the attribute or `null` if no matching attribute is found
*/
- XmlAttributeNode getAttribute(String name2) {
+ XmlAttributeNode getAttribute(String name) {
for (XmlAttributeNode attribute in attributes) {
- if (attribute.name.lexeme == name2) {
+ if (attribute.name.lexeme == name) {
return attribute;
}
}
diff --git a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
index 8af2198..32f7498 100644
--- a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
@@ -85,8 +85,8 @@
*
* @param logger the logger that should receive instrumentation information
*/
- static void set logger(InstrumentationLogger logger2) {
- _CURRENT_LOGGER = logger2 == null ? _NULL_LOGGER : logger2;
+ static void set logger(InstrumentationLogger logger) {
+ _CURRENT_LOGGER = logger == null ? _NULL_LOGGER : logger;
}
}
class InstrumentationBuilder_15 implements InstrumentationBuilder {
diff --git a/pkg/analyzer_experimental/lib/src/generated/parser.dart b/pkg/analyzer_experimental/lib/src/generated/parser.dart
index 2264972..a7cb7de 100644
--- a/pkg/analyzer_experimental/lib/src/generated/parser.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/parser.dart
@@ -259,8 +259,8 @@
instrumentation.log();
}
}
- void set currentToken(Token currentToken2) {
- this._currentToken = currentToken2;
+ void set currentToken(Token currentToken) {
+ this._currentToken = currentToken;
}
/**
@@ -818,7 +818,7 @@
* @param keyword the keyword that is being tested for
* @return `true` if the given token matches the given keyword
*/
- bool matches3(Token token, Keyword keyword2) => identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword2);
+ bool matches3(Token token, Keyword keyword) => identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword);
/**
* Return `true` if the given token has the given type.
@@ -827,7 +827,7 @@
* @param type the type of token that is being tested for
* @return `true` if the given token has the given type
*/
- bool matches4(Token token, TokenType type2) => identical(token.type, type2);
+ bool matches4(Token token, TokenType type) => identical(token.type, type);
/**
* Return `true` if the current token has the given type. Note that this method, unlike
@@ -838,10 +838,10 @@
* @param type the type of token that can optionally appear in the current location
* @return `true` if the current token has the given type
*/
- bool matches5(TokenType type2) {
+ bool matches5(TokenType type) {
TokenType currentType = _currentToken.type;
- if (currentType != type2) {
- if (identical(type2, TokenType.GT)) {
+ if (currentType != type) {
+ if (identical(type, TokenType.GT)) {
if (identical(currentType, TokenType.GT_GT)) {
int offset = _currentToken.offset;
Token first = new Token(TokenType.GT, offset);
@@ -4861,8 +4861,7 @@
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)]));
+ // _errorListener.onError(new AnalysisError.con2(_source, offset, length, TodoCode.TODO, [matcher.group(2)]));
}
}
diff --git a/pkg/analyzer_experimental/lib/src/generated/resolver.dart b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
index 3860b21..535ce2e 100644
--- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
@@ -33,7 +33,7 @@
* @return the compilation unit element that was built
* @throws AnalysisException if the analysis could not be performed
*/
- CompilationUnitElementImpl buildCompilationUnit(Source source2, CompilationUnit unit) {
+ CompilationUnitElementImpl buildCompilationUnit(Source source, CompilationUnit unit) {
TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
if (unit == null) {
return null;
@@ -41,10 +41,10 @@
ElementHolder holder = new ElementHolder();
ElementBuilder builder = new ElementBuilder(holder);
unit.accept(builder);
- CompilationUnitElementImpl element = new CompilationUnitElementImpl(source2.shortName);
+ CompilationUnitElementImpl element = new CompilationUnitElementImpl(source.shortName);
element.accessors = holder.accessors;
element.functions = holder.functions;
- element.source = source2;
+ element.source = source;
element.typeAliases = holder.typeAliases;
element.types = holder.types;
element.topLevelVariables = holder.topLevelVariables;
@@ -693,7 +693,7 @@
* @param keyword the keyword being tested for
* @return `true` if the given token is a token for the given keyword
*/
- bool matches(sc.Token token, sc.Keyword keyword2) => token != null && identical(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).keyword, keyword2);
+ bool matches(sc.Token token, sc.Keyword keyword) => token != null && identical(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).keyword, keyword);
/**
* Sets the visible source range for formal parameter.
@@ -1117,11 +1117,11 @@
* @param unit the AST structure representing the HTML
* @throws AnalysisException if the analysis could not be performed
*/
- HtmlElementImpl buildHtmlElement2(Source source2, int modificationStamp2, ht.HtmlUnit unit) {
- this._modificationStamp = modificationStamp2;
- _lineInfo = _context.computeLineInfo(source2);
- HtmlElementImpl result = new HtmlElementImpl(_context, source2.shortName);
- result.source = source2;
+ HtmlElementImpl buildHtmlElement2(Source source, int modificationStamp, ht.HtmlUnit unit) {
+ this._modificationStamp = modificationStamp;
+ _lineInfo = _context.computeLineInfo(source);
+ HtmlElementImpl result = new HtmlElementImpl(_context, source.shortName);
+ result.source = source;
_htmlElement = result;
unit.accept(this);
_htmlElement = null;
@@ -1296,7 +1296,6 @@
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";
@@ -1394,7 +1393,7 @@
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 (rhsType.isObject || (expression is NullLiteral && rhsNameStr == _NULL_TYPE_NAME)) {
if (node.notOperator == null) {
_errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
} else {
@@ -2055,9 +2054,18 @@
}
return super.visitCompilationUnit(node);
}
- Object visitExportDirective(ExportDirective node) => null;
- Object visitImportDirective(ImportDirective node) => null;
- Object visitLibraryDirective(LibraryDirective node) => null;
+ Object visitExportDirective(ExportDirective node) {
+ visitMetadata(node.metadata);
+ return null;
+ }
+ Object visitImportDirective(ImportDirective node) {
+ visitMetadata(node.metadata);
+ return null;
+ }
+ Object visitLibraryDirective(LibraryDirective node) {
+ visitMetadata(node.metadata);
+ return null;
+ }
Object visitPrefixedIdentifier(PrefixedIdentifier node) {
SimpleIdentifier prefixIdentifier = node.prefix;
Element element = prefixIdentifier.staticElement;
@@ -2068,8 +2076,8 @@
return visitIdentifier(element, prefixIdentifier.name);
}
Object visitSimpleIdentifier(SimpleIdentifier node) => visitIdentifier(node.staticElement, node.name);
- void set inDefiningCompilationUnit(bool inDefiningCompilationUnit2) {
- this._inDefiningCompilationUnit = inDefiningCompilationUnit2;
+ void set inDefiningCompilationUnit(bool inDefiningCompilationUnit) {
+ this._inDefiningCompilationUnit = inDefiningCompilationUnit;
}
/**
@@ -2159,6 +2167,20 @@
}
return null;
}
+
+ /**
+ * Given some [NodeList] of [Annotation]s, ensure that the identifiers are visited by
+ * this visitor. Specifically, this covers the cases where AST nodes don't have their identifiers
+ * visited by this visitor, but still need their annotations visited.
+ *
+ * @param annotations the list of annotations to visit
+ */
+ void visitMetadata(NodeList<Annotation> annotations) {
+ for (Annotation annotation in annotations) {
+ Identifier name = annotation.name;
+ visitIdentifier(name.staticElement, name.name);
+ }
+ }
}
/**
* Instances of the class `PubVerifier` traverse an AST structure looking for deviations from
@@ -2354,9 +2376,9 @@
* @param unit the compilation unit to be resolved
* @param element the root of the element model used to resolve the AST nodes
*/
- void resolve(CompilationUnit unit, CompilationUnitElement element2) {
- _enclosingUnit = element2;
- unit.element = element2;
+ void resolve(CompilationUnit unit, CompilationUnitElement element) {
+ _enclosingUnit = element;
+ unit.element = element;
unit.accept(this);
}
Object visitCatchClause(CatchClause node) {
@@ -2714,9 +2736,9 @@
* for
* @return the export element whose library has the given source
*/
- ExportElement find5(List<ExportElement> exports, Source source2) {
+ ExportElement find5(List<ExportElement> exports, Source source) {
for (ExportElement export in exports) {
- if (export.exportedLibrary.source == source2) {
+ if (export.exportedLibrary.source == source) {
return export;
}
}
@@ -2733,16 +2755,16 @@
* @param prefix the prefix with which the library was imported
* @return the import element whose library has the given source and prefix
*/
- ImportElement find6(List<ImportElement> imports, Source source2, SimpleIdentifier prefix2) {
+ ImportElement find6(List<ImportElement> imports, Source source, SimpleIdentifier prefix) {
for (ImportElement element in imports) {
- if (element.importedLibrary.source == source2) {
+ if (element.importedLibrary.source == source) {
PrefixElement prefixElement = element.prefix;
- if (prefix2 == null) {
+ if (prefix == null) {
if (prefixElement == null) {
return element;
}
} else {
- if (prefixElement != null && prefix2.name == prefixElement.displayName) {
+ if (prefixElement != null && prefix.name == prefixElement.displayName) {
return element;
}
}
@@ -2919,6 +2941,11 @@
bool _strictMode = false;
/**
+ * A flag indicating whether we should generate hints.
+ */
+ bool _enableHints = false;
+
+ /**
* The type representing the type 'dynamic'.
*/
Type2 _dynamicType;
@@ -2947,7 +2974,9 @@
*/
ElementResolver(ResolverVisitor resolver) {
this._resolver = resolver;
- _strictMode = resolver.definingLibrary.context.analysisOptions.strictMode;
+ AnalysisOptions options = resolver.definingLibrary.context.analysisOptions;
+ _strictMode = options.strictMode;
+ _enableHints = options.hint;
_dynamicType = resolver.typeProvider.dynamicType;
_typeType = resolver.typeProvider.typeType;
}
@@ -2965,8 +2994,13 @@
Type2 propagatedType = getPropagatedType(leftHandSide);
MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedType, methodName);
node.propagatedElement = propagatedMethod;
- if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
- _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.displayName]);
+ bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+ bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+ if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_METHOD : HintCode.UNDEFINED_METHOD) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+ methodName,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
}
}
}
@@ -2984,8 +3018,13 @@
Type2 propagatedType = getPropagatedType(leftOperand);
MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedType, methodName);
node.propagatedElement = propagatedMethod;
- if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
- _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
+ bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+ bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+ if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+ methodName,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
}
}
}
@@ -3311,7 +3350,15 @@
argumentList.correspondingPropagatedParameters = parameters;
}
}
- ErrorCode errorCode = checkForInvocationError(target, staticElement);
+ ErrorCode errorCode = checkForInvocationError(target, true, staticElement);
+ bool generatedWithTypePropagation = false;
+ if (_enableHints && errorCode == null && staticElement == null) {
+ errorCode = checkForInvocationError(target, false, propagatedElement);
+ generatedWithTypePropagation = true;
+ }
+ if (errorCode == null) {
+ return null;
+ }
if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
_resolver.reportError5(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
} else if (identical(errorCode, CompileTimeErrorCode.UNDEFINED_FUNCTION)) {
@@ -3321,20 +3368,27 @@
if (target == null) {
ClassElement enclosingClass = _resolver.enclosingClass;
targetTypeName = enclosingClass.displayName;
- _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingClass, StaticTypeWarningCode.UNDEFINED_METHOD, methodName, [methodName.name, targetTypeName]);
+ ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingClass, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
} else {
- Type2 targetType = getStaticType(target);
+ Type2 targetType = null;
+ if (!generatedWithTypePropagation) {
+ targetType = getStaticType(target);
+ } else {
+ targetType = getPropagatedType(target);
+ if (targetType == null) {
+ targetType = getStaticType(target);
+ }
+ }
if (targetType != null && targetType.isDartCoreFunction && methodName.name == CALL_METHOD_NAME) {
return null;
}
targetTypeName = targetType == null ? null : targetType.displayName;
- _resolver.reportErrorProxyConditionalAnalysisError(targetType.element, StaticTypeWarningCode.UNDEFINED_METHOD, methodName, [methodName.name, targetTypeName]);
+ ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError(targetType.element, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
}
} else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) {
- Type2 targetType = getPropagatedType(target);
- if (targetType == null) {
- targetType = getStaticType(target);
- }
+ Type2 targetType = getStaticType(target);
String targetTypeName = targetType == null ? null : targetType.name;
_resolver.reportError5(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName, [methodName.name, targetTypeName]);
}
@@ -3357,8 +3411,13 @@
Type2 propagatedType = getPropagatedType(operand);
MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, methodName);
node.propagatedElement = propagatedMethod;
- if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
- _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.displayName]);
+ bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+ bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+ if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, node.operator, [
+ methodName,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
}
return null;
}
@@ -3415,8 +3474,13 @@
Type2 propagatedType = getPropagatedType(operand);
MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, methodName);
node.propagatedElement = propagatedMethod;
- if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
- _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
+ bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+ bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+ if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+ methodName,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
}
}
return null;
@@ -3573,10 +3637,11 @@
* reported, or `null` if no error should be reported.
*
* @param target the target of the invocation, or `null` if there was no target
+ * @param useStaticContext
* @param element the element to be invoked
* @return the error code that should be reported
*/
- ErrorCode checkForInvocationError(Expression target, Element element) {
+ ErrorCode checkForInvocationError(Expression target, bool useStaticContext, Element element) {
if (element is PrefixElement) {
element = null;
}
@@ -3618,7 +3683,15 @@
return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
}
} else {
- Type2 targetType = getStaticType(target);
+ Type2 targetType;
+ if (useStaticContext) {
+ targetType = getStaticType(target);
+ } else {
+ targetType = getPropagatedType(target);
+ if (targetType == null) {
+ targetType = getStaticType(target);
+ }
+ }
if (targetType == null) {
return CompileTimeErrorCode.UNDEFINED_FUNCTION;
} else if (!targetType.isDynamic) {
@@ -3641,15 +3714,22 @@
* @return `true` if and only if an error code is generated on the passed node
*/
bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, String methodName, MethodElement staticMethod, MethodElement propagatedMethod, Type2 staticType, Type2 propagatedType) {
- if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
+ bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+ bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+ if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
sc.Token leftBracket = node.leftBracket;
sc.Token rightBracket = node.rightBracket;
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
if (leftBracket == null || rightBracket == null) {
- _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, node, [methodName, staticType.displayName]);
+ _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, node, [
+ methodName,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
} else {
int offset = leftBracket.offset;
int length = rightBracket.offset - offset + 1;
- _resolver.reportErrorProxyConditionalAnalysisError2(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, offset, length, [methodName, staticType.displayName]);
+ _resolver.reportErrorProxyConditionalAnalysisError2(staticType.element, errorCode, offset, length, [
+ methodName,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
}
return true;
}
@@ -3665,9 +3745,9 @@
* @param executableElement the element that will be invoked with the arguments
* @return the parameters that correspond to the arguments
*/
- List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentList, Element element2) {
- if (element2 is PropertyAccessorElement) {
- FunctionType getterType = ((element2 as PropertyAccessorElement)).type;
+ List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentList, Element element) {
+ if (element is PropertyAccessorElement) {
+ FunctionType getterType = ((element as PropertyAccessorElement)).type;
if (getterType != null) {
Type2 getterReturnType = getterType.returnType;
if (getterReturnType is InterfaceType) {
@@ -3682,10 +3762,10 @@
}
}
}
- } else if (element2 is ExecutableElement) {
- return resolveArgumentsToParameters(false, argumentList, element2 as ExecutableElement);
- } else if (element2 is VariableElement) {
- VariableElement variable = element2 as VariableElement;
+ } else if (element is ExecutableElement) {
+ return resolveArgumentsToParameters(false, argumentList, element as ExecutableElement);
+ } else if (element is VariableElement) {
+ VariableElement variable = element as VariableElement;
Type2 type = variable.type;
if (type is FunctionType) {
FunctionType functionType = type as FunctionType;
@@ -4262,9 +4342,9 @@
* @param nameNode the name of the invoked constructor, may be `null` if unnamed constructor
* or not a constructor invocation
*/
- void resolveAnnotationElement(Annotation annotation, Element element2, SimpleIdentifier nameNode) {
- if (element2 is PropertyAccessorElement) {
- PropertyAccessorElement accessorElement = element2 as PropertyAccessorElement;
+ void resolveAnnotationElement(Annotation annotation, Element element, SimpleIdentifier nameNode) {
+ if (element is PropertyAccessorElement) {
+ PropertyAccessorElement accessorElement = element as PropertyAccessorElement;
if (!accessorElement.isSynthetic) {
_resolver.reportError5(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
return;
@@ -4275,14 +4355,14 @@
}
return;
}
- if (element2 is ClassElement) {
+ if (element is ClassElement) {
if (nameNode == null) {
nameNode = annotation.constructorName;
}
String name = nameNode != null ? nameNode.name : null;
ConstructorElement constructor;
{
- InterfaceType interfaceType = new InterfaceTypeImpl.con1(element2 as ClassElement);
+ InterfaceType interfaceType = new InterfaceTypeImpl.con1(element as ClassElement);
LibraryElement definingLibrary = _resolver.definingLibrary;
constructor = interfaceType.lookUpConstructor(name, definingLibrary);
}
@@ -4297,7 +4377,7 @@
resolveAnnotationConstructorInvocationArguments(annotation, constructor);
return;
}
- if (element2 != null) {
+ if (element != null) {
_resolver.reportError5(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
}
}
@@ -4507,20 +4587,34 @@
Type2 propagatedType = getPropagatedType(target);
ExecutableElement propagatedElement = resolveProperty(target, propagatedType, propertyName);
propertyName.propagatedElement = propagatedElement;
- if (shouldReportMissingMember(staticType, staticElement) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedElement))) {
+ bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticElement) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedElement));
+ bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedElement) : false;
+ if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
Element selectedElement = select(staticElement, propagatedElement);
bool isStaticProperty = isStatic(selectedElement);
if (propertyName.inSetterContext()) {
if (isStaticProperty) {
- _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticWarningCode.UNDEFINED_SETTER, propertyName, [propertyName.name, staticType.displayName]);
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+ propertyName.name,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
} else {
- _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticTypeWarningCode.UNDEFINED_SETTER, propertyName, [propertyName.name, staticType.displayName]);
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+ propertyName.name,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
}
} else if (propertyName.inGetterContext()) {
if (isStaticProperty) {
- _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticWarningCode.UNDEFINED_GETTER, propertyName, [propertyName.name, staticType.displayName]);
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+ propertyName.name,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
} else {
- _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticTypeWarningCode.UNDEFINED_GETTER, propertyName, [propertyName.name, staticType.displayName]);
+ ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
+ _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+ propertyName.name,
+ shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
}
} else {
_resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.name]);
@@ -4811,8 +4905,8 @@
*
* @param library the new library element
*/
- void set libraryElement(LibraryElement library2) {
- this._library = library2;
+ void set libraryElement(LibraryElement library) {
+ this._library = library;
}
/**
@@ -5353,7 +5447,7 @@
try {
_libraryElement = _analysisContext.computeLibraryElement(librarySource) as LibraryElementImpl;
} on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not compute ilbrary element for ${librarySource.fullName}", exception);
+ AnalysisEngine.instance.logger.logError2("Could not compute library element for ${librarySource.fullName}", exception);
}
}
return _libraryElement;
@@ -5439,8 +5533,8 @@
*
* @param exportedLibraries the libraries that are exported by this library
*/
- void set exportedLibraries(List<Library> exportedLibraries2) {
- this.exports = exportedLibraries2;
+ void set exportedLibraries(List<Library> exportedLibraries) {
+ this.exports = exportedLibraries;
}
/**
@@ -5448,8 +5542,8 @@
*
* @param importedLibraries the libraries that are imported into this library
*/
- void set importedLibraries(List<Library> importedLibraries2) {
- this.imports = importedLibraries2;
+ void set importedLibraries(List<Library> importedLibraries) {
+ this.imports = importedLibraries;
}
/**
@@ -5457,10 +5551,10 @@
*
* @param libraryElement the library element representing this library
*/
- void set libraryElement(LibraryElementImpl libraryElement2) {
- this._libraryElement = libraryElement2;
+ void set libraryElement(LibraryElementImpl libraryElement) {
+ this._libraryElement = libraryElement;
if (_inheritanceManager != null) {
- _inheritanceManager.libraryElement = libraryElement2;
+ _inheritanceManager.libraryElement = libraryElement;
}
}
String toString() => librarySource.shortName;
@@ -6349,9 +6443,9 @@
* @param element the class being tested
* @return `true` if the given element represents a class that has the proxy annotation
*/
- static bool classHasProxyAnnotation(Element element2) {
- if (element2 is ClassElement) {
- ClassElement classElement = element2 as ClassElement;
+ static bool classHasProxyAnnotation(Element element) {
+ if (element is ClassElement) {
+ ClassElement classElement = element as ClassElement;
List<ElementAnnotation> annotations = classElement.metadata;
for (ElementAnnotation annotation in annotations) {
Element elementAnnotation = annotation.element;
@@ -7112,11 +7206,11 @@
* @param expression the expression being tested
* @return `true` if the given expression terminates abruptly
*/
- bool isAbruptTermination(Expression expression2) {
- while (expression2 is ParenthesizedExpression) {
- expression2 = ((expression2 as ParenthesizedExpression)).expression;
+ bool isAbruptTermination(Expression expression) {
+ while (expression is ParenthesizedExpression) {
+ expression = ((expression as ParenthesizedExpression)).expression;
}
- return expression2 is ThrowExpression || expression2 is RethrowExpression;
+ return expression is ThrowExpression || expression is RethrowExpression;
}
/**
@@ -7404,6 +7498,16 @@
}
return null;
}
+ Object visitFormalParameterList(FormalParameterList node) {
+ super.visitFormalParameterList(node);
+ if (nameScope is FunctionScope) {
+ ((nameScope as FunctionScope)).defineParameters();
+ }
+ if (nameScope is FunctionTypeScope) {
+ ((nameScope as FunctionTypeScope)).defineParameters();
+ }
+ return null;
+ }
Object visitForStatement(ForStatement node) {
Scope outerNameScope = nameScope;
LabelScope outerLabelScope = labelScope;
@@ -7813,8 +7917,8 @@
*
* @param thisType the type representing the class containing the nodes being analyzed
*/
- void set thisType(InterfaceType thisType2) {
- this._thisType = thisType2;
+ void set thisType(InterfaceType thisType) {
+ this._thisType = thisType;
}
/**
@@ -9943,12 +10047,12 @@
TypeArgumentList argumentList = node.typeArguments;
Element element = nameScope.lookup(typeName, definingLibrary);
if (element == null) {
- if (typeName.name == _dynamicType.name) {
- setElement(typeName, _dynamicType.element);
+ if (typeName.name == this._dynamicType.name) {
+ setElement(typeName, this._dynamicType.element);
if (argumentList != null) {
}
- typeName.staticType = _dynamicType;
- node.type = _dynamicType;
+ typeName.staticType = this._dynamicType;
+ node.type = this._dynamicType;
return null;
}
VoidTypeImpl voidType = VoidTypeImpl.instance;
@@ -10024,10 +10128,10 @@
if (element is MultiplyDefinedElement) {
setElement(typeName, element);
} else {
- setElement(typeName, _dynamicType.element);
+ setElement(typeName, this._dynamicType.element);
}
- typeName.staticType = _dynamicType;
- node.type = _dynamicType;
+ typeName.staticType = this._dynamicType;
+ node.type = this._dynamicType;
return null;
}
Type2 type = null;
@@ -10069,9 +10173,9 @@
reportError5(StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
}
}
- setElement(typeName, _dynamicType.element);
- typeName.staticType = _dynamicType;
- node.type = _dynamicType;
+ setElement(typeName, this._dynamicType.element);
+ typeName.staticType = this._dynamicType;
+ node.type = this._dynamicType;
return null;
}
if (argumentList != null) {
@@ -10093,7 +10197,7 @@
argumentCount = typeArguments.length;
if (argumentCount < parameterCount) {
for (int i = argumentCount; i < parameterCount; i++) {
- typeArguments.add(_dynamicType);
+ typeArguments.add(this._dynamicType);
}
}
if (type is InterfaceTypeImpl) {
@@ -10513,12 +10617,12 @@
* @param returnType the (possibly `null`) return type of the function
* @param parameterList the list of parameters to the function
*/
- void setFunctionTypedParameterType(ParameterElementImpl element, TypeName returnType2, FormalParameterList parameterList) {
+ void setFunctionTypedParameterType(ParameterElementImpl element, TypeName returnType, FormalParameterList parameterList) {
List<ParameterElement> parameters = getElements(parameterList);
FunctionTypeAliasElementImpl aliasElement = new FunctionTypeAliasElementImpl(null);
aliasElement.synthetic = true;
aliasElement.shareParameters(parameters);
- aliasElement.returnType = computeReturnType(returnType2);
+ aliasElement.returnType = computeReturnType(returnType);
FunctionTypeImpl type = new FunctionTypeImpl.con2(aliasElement);
ClassElement definingClass = element.getAncestor(ClassElement);
if (definingClass != null) {
@@ -10655,6 +10759,8 @@
* @coverage dart.engine.resolver
*/
class FunctionScope extends EnclosedScope {
+ ExecutableElement _functionElement;
+ bool _parametersDefined = false;
/**
* Initialize a newly created scope enclosed within another scope.
@@ -10663,23 +10769,25 @@
* @param functionElement the element representing the type represented by this scope
*/
FunctionScope(Scope enclosingScope, ExecutableElement functionElement) : super(new EnclosedScope(enclosingScope)) {
- defineParameters(functionElement);
+ this._functionElement = functionElement;
}
/**
* Define the parameters for the given function in the scope that encloses this function.
- *
- * @param functionElement the element representing the function represented by this scope
*/
- void defineParameters(ExecutableElement functionElement) {
+ void defineParameters() {
+ if (_parametersDefined) {
+ return;
+ }
+ _parametersDefined = true;
Scope parameterScope = enclosingScope;
- if (functionElement.enclosingElement is ExecutableElement) {
- String name = functionElement.name;
+ if (_functionElement.enclosingElement is ExecutableElement) {
+ String name = _functionElement.name;
if (name != null && !name.isEmpty) {
- parameterScope.define(functionElement);
+ parameterScope.define(_functionElement);
}
}
- for (ParameterElement parameter in functionElement.parameters) {
+ for (ParameterElement parameter in _functionElement.parameters) {
if (!parameter.isInitializingFormal) {
parameterScope.define(parameter);
}
@@ -10693,6 +10801,8 @@
* @coverage dart.engine.resolver
*/
class FunctionTypeScope extends EnclosedScope {
+ FunctionTypeAliasElement _typeElement;
+ bool _parametersDefined = false;
/**
* Initialize a newly created scope enclosed within another scope.
@@ -10701,8 +10811,8 @@
* @param typeElement the element representing the type alias represented by this scope
*/
FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) {
- defineTypeParameters(typeElement);
- defineParameters(typeElement);
+ this._typeElement = typeElement;
+ defineTypeParameters();
}
/**
@@ -10710,8 +10820,12 @@
*
* @param typeElement the element representing the type represented by this scope
*/
- void defineParameters(FunctionTypeAliasElement typeElement) {
- for (ParameterElement parameter in typeElement.parameters) {
+ void defineParameters() {
+ if (_parametersDefined) {
+ return;
+ }
+ _parametersDefined = true;
+ for (ParameterElement parameter in _typeElement.parameters) {
define(parameter);
}
}
@@ -10721,9 +10835,9 @@
*
* @param typeElement the element representing the type represented by this scope
*/
- void defineTypeParameters(FunctionTypeAliasElement typeElement) {
+ void defineTypeParameters() {
Scope typeParameterScope = enclosingScope;
- for (TypeParameterElement typeParameter in typeElement.typeParameters) {
+ for (TypeParameterElement typeParameter in _typeElement.typeParameters) {
typeParameterScope.define(typeParameter);
}
}
@@ -10884,7 +10998,7 @@
if (enclosingLibrary != null) {
libName2 = enclosingLibrary.definingCompilationUnit.displayName;
}
- _errorListener.onError(new AnalysisError.con2(source2, identifier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltName, libName1, libName2]));
+ _errorListener.onError(new AnalysisError.con2(source, identifier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltName, libName1, libName2]));
return foundElement;
}
if (foundElement != null) {
@@ -10927,6 +11041,9 @@
return foundElement;
} else if (to == 1) {
return conflictingMembers[0];
+ } else if (to == 0) {
+ AnalysisEngine.instance.logger.logInformation("Multiply defined SDK element: ${foundElement}");
+ return foundElement;
}
List<Element> remaining = new List<Element>(to);
JavaSystem.arraycopy(conflictingMembers, 0, remaining, 0, to);
@@ -10959,7 +11076,7 @@
offset = accessor.variable.nameOffset;
}
}
- return new AnalysisError.con2(source2, offset, duplicate.displayName.length, CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existing.displayName]);
+ return new AnalysisError.con2(source, offset, duplicate.displayName.length, CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existing.displayName]);
}
return super.getErrorForDuplicate(existing, duplicate);
}
@@ -11129,9 +11246,9 @@
* @param definedNames the mapping table to which the names in the given namespace are to be added
* @param namespace the namespace containing the names to be added to this namespace
*/
- void addAll2(Map<String, Element> definedNames2, Namespace namespace) {
+ void addAll2(Map<String, Element> definedNames, Namespace namespace) {
if (namespace != null) {
- addAll(definedNames2, namespace.definedNames);
+ addAll(definedNames, namespace.definedNames);
}
}
@@ -11379,7 +11496,7 @@
AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
Source source = duplicate.source;
if (source == null) {
- source = source2;
+ source = this.source;
}
return new AnalysisError.con2(source, duplicate.nameOffset, duplicate.displayName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName]);
}
@@ -11397,7 +11514,7 @@
*
* @return the source object with which errors should be associated
*/
- Source get source2 => definingLibrary.definingCompilationUnit.source;
+ Source get source => definingLibrary.definingCompilationUnit.source;
/**
* Return the element with which the given name is associated, or `null` if the name is not
@@ -11602,14 +11719,14 @@
* @param result the result containing any errors that need to be reported
* @param errorCode the error code to be used if the result represents an error
*/
- void reportErrors(EvaluationResultImpl result, ErrorCode errorCode2) {
+ void reportErrors(EvaluationResultImpl result, ErrorCode errorCode) {
if (result is ErrorResult) {
for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
ErrorCode dataErrorCode = data.errorCode;
if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) {
_errorReporter.reportError2(dataErrorCode, data.node, []);
} else {
- _errorReporter.reportError2(errorCode2, data.node, []);
+ _errorReporter.reportError2(errorCode, data.node, []);
}
}
}
@@ -11666,11 +11783,11 @@
*
* @param parameters the list of parameters to be validated
*/
- void validateDefaultValues(FormalParameterList parameters2) {
- if (parameters2 == null) {
+ void validateDefaultValues(FormalParameterList parameters) {
+ if (parameters == null) {
return;
}
- for (FormalParameter parameter in parameters2.parameters) {
+ for (FormalParameter parameter in parameters.parameters) {
if (parameter is DefaultFormalParameter) {
DefaultFormalParameter defaultParameter = parameter as DefaultFormalParameter;
Expression defaultValue = defaultParameter.defaultValue;
@@ -12555,7 +12672,7 @@
* @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE
* @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
*/
- bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, List<ParameterElement> parameters2, List<ASTNode> parameterLocations, SimpleIdentifier errorNameTarget) {
+ bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, List<ParameterElement> parameters, List<ASTNode> parameterLocations, SimpleIdentifier errorNameTarget) {
String executableElementName = executableElement.name;
ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritance(_enclosingClass, executableElementName);
bool isGetter = false;
@@ -12675,8 +12792,8 @@
if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) {
ParameterElement parameterToSelect = null;
ASTNode parameterLocationToSelect = null;
- for (int i = 0; i < parameters2.length; i++) {
- ParameterElement parameter = parameters2[i];
+ for (int i = 0; i < parameters.length; i++) {
+ ParameterElement parameter = parameters[i];
if (identical(parameter.parameterKind, ParameterKind.NAMED) && overriddenNamedPTEntry.getKey() == parameter.name) {
parameterToSelect = parameter;
parameterLocationToSelect = parameterLocations[i];
@@ -12697,8 +12814,8 @@
List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>();
List<ParameterElementImpl> overriddenParameterElts = new List<ParameterElementImpl>();
List<ParameterElement> overriddenPEs = overriddenExecutable.parameters;
- for (int i = 0; i < parameters2.length; i++) {
- ParameterElement parameter = parameters2[i];
+ for (int i = 0; i < parameters.length; i++) {
+ ParameterElement parameter = parameters[i];
if (parameter.parameterKind.isOptional) {
formalParameters.add(parameterLocations[i]);
parameterElts.add(parameter as ParameterElementImpl);
@@ -13250,11 +13367,11 @@
* @return `true` if and only if an error code is generated on the passed node
* @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
*/
- bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node, Type2 type2) {
- if (type2 == null || type2 == _typeProvider.intType || type2 == _typeProvider.stringType) {
+ bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node, Type2 type) {
+ if (type == null || type == _typeProvider.intType || type == _typeProvider.stringType) {
return false;
}
- Element element = type2.element;
+ Element element = type.element;
if (element is! ClassElement) {
return false;
}
@@ -14258,14 +14375,14 @@
* @return `true` if and only if an error code is generated on the passed node
* @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER
*/
- bool checkForInstanceAccessToStaticMember(Expression target, SimpleIdentifier name2) {
+ bool checkForInstanceAccessToStaticMember(Expression target, SimpleIdentifier name) {
if (target == null) {
return false;
}
if (_isInComment) {
return false;
}
- Element element = name2.staticElement;
+ Element element = name.staticElement;
if (element is! ExecutableElement) {
return false;
}
@@ -14279,7 +14396,7 @@
if (isTypeReference(target)) {
return false;
}
- _errorReporter.reportError2(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name2, [name2.name]);
+ _errorReporter.reportError2(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [name.name]);
return true;
}
@@ -15274,8 +15391,8 @@
* @return `true` if and only if an error code is generated on the passed node
* @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER
*/
- bool checkForStaticAccessToInstanceMember(Expression target, SimpleIdentifier name2) {
- Element element = name2.staticElement;
+ bool checkForStaticAccessToInstanceMember(Expression target, SimpleIdentifier name) {
+ Element element = name.staticElement;
if (element is! ExecutableElement) {
return false;
}
@@ -15286,7 +15403,7 @@
if (!isTypeReference(target)) {
return false;
}
- _errorReporter.reportError2(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name2, [name2.name]);
+ _errorReporter.reportError2(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]);
return true;
}
@@ -15475,8 +15592,8 @@
* @return `true` if and only if an error code is generated on the passed node
* @see StaticTypeWarningCode#UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
*/
- bool checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name2) {
- Element element = name2.staticElement;
+ bool checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name) {
+ Element element = name.staticElement;
if (element == null || element is TypeParameterElement) {
return false;
}
@@ -15490,7 +15607,7 @@
if (identical(enclosingElement, _enclosingClass)) {
return false;
}
- _errorReporter.reportError2(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, name2, [name2.name]);
+ _errorReporter.reportError2(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, name, [name.name]);
return true;
}
diff --git a/pkg/analyzer_experimental/lib/src/generated/scanner.dart b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
index 67ffec0..7ee43be 100644
--- a/pkg/analyzer_experimental/lib/src/generated/scanner.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
@@ -38,13 +38,13 @@
* @param length the number of strings in the array that pass through the state being built
* @return the state that was created
*/
- static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length2) {
+ static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length) {
List<KeywordState> result = new List<KeywordState>(26);
- assert(length2 != 0);
+ assert(length != 0);
int chunk = 0x0;
int chunkStart = -1;
bool isLeaf = false;
- for (int i = offset; i < offset + length2; i++) {
+ for (int i = offset; i < offset + length; i++) {
if (strings[i].length == start) {
isLeaf = true;
}
@@ -61,9 +61,9 @@
}
if (chunkStart != -1) {
assert(result[chunk - 0x61] == null);
- result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length2 - chunkStart);
+ result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length - chunkStart);
} else {
- assert(length2 == 1);
+ assert(length == 1);
return new KeywordState(_EMPTY_TABLE, strings[offset]);
}
if (isLeaf) {
@@ -544,12 +544,12 @@
_lastComment = _lastComment.setNext(new StringToken(type, value, _tokenStart));
}
}
- void appendEndToken(TokenType type2, TokenType beginType) {
+ void appendEndToken(TokenType type, TokenType beginType) {
Token token;
if (_firstComment == null) {
- token = new Token(type2, _tokenStart);
+ token = new Token(type, _tokenStart);
} else {
- token = new TokenWithComment(type2, _tokenStart, _firstComment);
+ token = new TokenWithComment(type, _tokenStart, _firstComment);
_firstComment = null;
_lastComment = null;
}
@@ -643,8 +643,8 @@
return advance();
}
if (next == 0x72) {
- int peek2 = peek();
- if (peek2 == 0x22 || peek2 == 0x27) {
+ int peek = this.peek();
+ if (peek == 0x22 || peek == 0x27) {
int start = offset;
return tokenizeString(advance(), start, true);
}
@@ -1017,23 +1017,23 @@
beginToken();
return next;
}
- int tokenizeKeywordOrIdentifier(int next2, bool allowDollar) {
+ int tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
KeywordState state = KeywordState.KEYWORD_STATE;
int start = offset;
- while (state != null && 0x61 <= next2 && next2 <= 0x7A) {
- state = state.next(next2 as int);
- next2 = advance();
+ while (state != null && 0x61 <= next && next <= 0x7A) {
+ state = state.next(next as int);
+ next = advance();
}
if (state == null || state.keyword() == null) {
- return tokenizeIdentifier(next2, start, allowDollar);
+ return tokenizeIdentifier(next, start, allowDollar);
}
- if ((0x41 <= next2 && next2 <= 0x5A) || (0x30 <= next2 && next2 <= 0x39) || next2 == 0x5F || next2 == 0x24) {
- return tokenizeIdentifier(next2, start, allowDollar);
- } else if (next2 < 128) {
+ if ((0x41 <= next && next <= 0x5A) || (0x30 <= next && next <= 0x39) || next == 0x5F || next == 0x24) {
+ return tokenizeIdentifier(next, start, allowDollar);
+ } else if (next < 128) {
appendKeywordToken(state.keyword());
- return next2;
+ return next;
} else {
- return tokenizeIdentifier(next2, start, allowDollar);
+ return tokenizeIdentifier(next, start, allowDollar);
}
}
int tokenizeLessThan(int next) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/sdk.dart b/pkg/analyzer_experimental/lib/src/generated/sdk.dart
index 2accc54..234742f 100644
--- a/pkg/analyzer_experimental/lib/src/generated/sdk.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/sdk.dart
@@ -157,8 +157,8 @@
*
* @param category the name of the category containing the library
*/
- void set category(String category2) {
- this._category = category2;
+ void set category(String category) {
+ this._category = category;
}
/**
@@ -173,8 +173,8 @@
*
* @param documented `true` if the library is documented
*/
- void set documented(bool documented2) {
- this._documented = documented2;
+ void set documented(bool documented) {
+ this._documented = documented;
}
/**
@@ -182,8 +182,8 @@
*
* @param implementation `true` if the library is an implementation library
*/
- void set implementation(bool implementation2) {
- this._implementation = implementation2;
+ void set implementation(bool implementation) {
+ this._implementation = implementation;
}
/**
@@ -192,8 +192,8 @@
*
* @param path the path to the file defining the library
*/
- void set path(String path2) {
- this._path = path2;
+ void set path(String path) {
+ this._path = path;
}
/**
diff --git a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
index 032d5e7..6d3d7e9 100644
--- a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
@@ -195,7 +195,9 @@
advance();
}
- if (!isEOF(token2)) {
+ // TODO(pquitslund): consider a better way to notice trailing synthetics
+ if (!isEOF(token2) &&
+ !(isCLOSE_CURLY_BRACKET(token2) && isEOF(token2.next))) {
throw new FormatterException(
'Expected "EOF" but got "${token2}".');
}
@@ -261,6 +263,11 @@
return true;
}
}
+ // Advance past synthetic { } tokens
+ if (isOPEN_CURLY_BRACKET(token2) || isCLOSE_CURLY_BRACKET(token2)) {
+ token2 = token2.next;
+ return checkTokens();
+ }
return false;
}
@@ -286,6 +293,14 @@
/// Test if this token is an INDEX token.
bool isINDEX(Token token) => tokenIs(token, TokenType.INDEX);
+/// Test if this token is a OPEN_CURLY_BRACKET token.
+bool isOPEN_CURLY_BRACKET(Token token) =>
+ tokenIs(token, TokenType.OPEN_CURLY_BRACKET);
+
+/// Test if this token is a CLOSE_CURLY_BRACKET token.
+bool isCLOSE_CURLY_BRACKET(Token token) =>
+ tokenIs(token, TokenType.CLOSE_CURLY_BRACKET);
+
/// Test if this token is a OPEN_SQUARE_BRACKET token.
bool isOPEN_SQ_BRACKET(Token token) =>
tokenIs(token, TokenType.OPEN_SQUARE_BRACKET);
@@ -294,8 +309,19 @@
bool isCLOSE_SQUARE_BRACKET(Token token) =>
tokenIs(token, TokenType.CLOSE_SQUARE_BRACKET);
+
/// An AST visitor that drives formatting heuristics.
class SourceVisitor implements ASTVisitor {
+
+ static final OPEN_CURLY = syntheticToken(TokenType.OPEN_CURLY_BRACKET, '{');
+ static final CLOSE_CURLY = syntheticToken(TokenType.CLOSE_CURLY_BRACKET, '}');
+
+ static const SYNTH_OFFSET = -13;
+
+ static StringToken syntheticToken(TokenType type, String value) =>
+ new StringToken(type, value, SYNTH_OFFSET);
+
+ static bool isSynthetic(Token token) => token.offset == SYNTH_OFFSET;
/// The writer to which the source is to be written.
final SourceWriter writer;
@@ -308,6 +334,9 @@
/// A flag to indicate that a newline should be emitted before the next token.
bool needsNewline = false;
+
+ /// A counter for spaces that should be emitted preceding the next token.
+ int leadingSpaces = 0;
/// Used for matching EOL comments
final twoSlashes = new RegExp(r'//[^/]');
@@ -514,13 +543,41 @@
token(node.period);
visit(node.name);
visit(node.parameters);
- token(node.separator /* = or : */, precededBy: space, followedBy: space);
- visitNodes(node.initializers, separatedBy: commaSeperator);
- visit(node.redirectedConstructor);
+
+ // Check for redirects or initializer lists
+ if (node.separator != null) {
+ if (node.redirectedConstructor != null) {
+ visitConstructorRedirects(node);
+ } else {
+ visitConstructorInitializers(node);
+ }
+ }
visitPrefixedBody(space, node.body);
}
+ visitConstructorInitializers(ConstructorDeclaration node) {
+ newlines();
+ indent(2);
+ token(node.separator /* : */);
+ space();
+ for (var i = 0; i < node.initializers.length; i++) {
+ if (i > 0) {
+ comma();
+ newlines();
+ space(2);
+ }
+ node.initializers[i].accept(this);
+ }
+ unindent(2);
+ }
+
+ visitConstructorRedirects(ConstructorDeclaration node) {
+ token(node.separator /* = */, precededBy: space, followedBy: space);
+ visitNodes(node.initializers, separatedBy: commaSeperator);
+ visit(node.redirectedConstructor);
+ }
+
visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
token(node.keyword);
token(node.period);
@@ -730,24 +787,26 @@
space();
visitNodes(node.hiddenNames, separatedBy: commaSeperator);
}
-
+
visitIfStatement(IfStatement node) {
+ var hasElse = node.elseStatement != null;
token(node.ifKeyword);
space();
token(node.leftParenthesis);
visit(node.condition);
token(node.rightParenthesis);
space();
- visit(node.thenStatement);
- //visitPrefixed(' else ', node.elseStatement);
- if (node.elseStatement != null) {
+ if (hasElse) {
+ printAsBlock(node.thenStatement);
space();
token(node.elseKeyword);
space();
- visit(node.elseStatement);
+ printAsBlock(node.elseStatement);
+ } else {
+ visit(node.thenStatement);
}
}
-
+
visitImplementsClause(ImplementsClause node) {
token(node.keyword);
space();
@@ -1226,6 +1285,13 @@
}
}
+ emitSpaces() {
+ while (leadingSpaces > 0) {
+ writer.print(' ');
+ leadingSpaces--;
+ }
+ }
+
checkForSelectionUpdate(Token token) {
// Cache the first token on or AFTER the selection offset
if (preSelection != null && selection == null) {
@@ -1233,7 +1299,8 @@
var overshot = token.offset - preSelection.offset;
if (overshot >= 0) {
//TODO(pquitslund): update length (may need truncating)
- selection = new Selection(writer.toString().length - overshot,
+ selection = new Selection(
+ writer.toString().length + leadingSpaces - overshot,
preSelection.length);
}
}
@@ -1245,15 +1312,16 @@
}
comma() {
- append(',');
+ writer.print(',');
}
+
/// Emit a non-breakable space.
- space() {
+ space([n = 1]) {
//TODO(pquitslund): replace with a proper space token
- append(' ');
+ leadingSpaces+=n;
}
-
+
/// Emit a breakable space
breakableSpace() {
//Implement
@@ -1262,21 +1330,40 @@
/// Append the given [string] to the source writer if it's non-null.
append(String string) {
if (string != null && !string.isEmpty) {
+ emitSpaces();
writer.print(string);
}
}
/// Indent.
- indent() {
- writer.indent();
+ indent([n = 1]) {
+ while (n-- > 0) {
+ writer.indent();
+ }
}
-
+
/// Unindent
- unindent() {
- writer.unindent();
+ unindent([n = 1]) {
+ while (n-- > 0) {
+ writer.unindent();
+ }
}
-
-
+
+ /// Print this statement as if it were a block (e.g., surrounded by braces).
+ printAsBlock(Statement statement) {
+ if (statement is! Block) {
+ token(OPEN_CURLY);
+ indent();
+ newlines();
+ visit(statement);
+ newlines();
+ unindent();
+ token(CLOSE_CURLY);
+ } else {
+ visit(statement);
+ }
+ }
+
/// Emit any detected comments and newlines or a minimum as specified
/// by [min].
int emitPrecedingCommentsAndNewlines(Token token, {min: 0}) {
@@ -1294,7 +1381,7 @@
var lines = max(min, countNewlinesBetween(previousToken, currentToken));
writer.newlines(lines);
- var previousToken = currentToken.previous;
+ previousToken = currentToken.previous;
while (comment != null) {
@@ -1306,7 +1393,7 @@
writer.newlines(newlines);
lines += newlines;
} else if (!isEOF(token)) {
- space();
+ append(' ');
}
previousToken = comment;
@@ -1336,7 +1423,7 @@
var ws = countSpacesBetween(previousToken, comment);
// Preserve one space but no more
if (ws > 0) {
- space();
+ append(' ');
}
}
@@ -1361,7 +1448,7 @@
/// Count the blanks between these two tokens.
int countNewlinesBetween(Token last, Token current) {
- if (last == null || current == null) {
+ if (last == null || current == null || isSynthetic(last)) {
return 0;
}
diff --git a/pkg/analyzer_experimental/test/generated/ast_test.dart b/pkg/analyzer_experimental/test/generated/ast_test.dart
index 36380ec..0c07d4c 100644
--- a/pkg/analyzer_experimental/test/generated/ast_test.dart
+++ b/pkg/analyzer_experimental/test/generated/ast_test.dart
@@ -262,7 +262,7 @@
static CompilationUnit compilationUnit5(String scriptTag) => compilationUnit8(scriptTag, null, null);
static CompilationUnit compilationUnit6(String scriptTag, List<CompilationUnitMember> declarations) => compilationUnit8(scriptTag, null, list(declarations));
static CompilationUnit compilationUnit7(String scriptTag, List<Directive> directives) => compilationUnit8(scriptTag, list(directives), null);
- static CompilationUnit compilationUnit8(String scriptTag2, List<Directive> directives, List<CompilationUnitMember> declarations) => new CompilationUnit.full(TokenFactory.token3(TokenType.EOF), scriptTag2 == null ? null : scriptTag(scriptTag2), directives == null ? new List<Directive>() : directives, declarations == null ? new List<CompilationUnitMember>() : declarations, TokenFactory.token3(TokenType.EOF));
+ static CompilationUnit compilationUnit8(String scriptTag, List<Directive> directives, List<CompilationUnitMember> declarations) => new CompilationUnit.full(TokenFactory.token3(TokenType.EOF), scriptTag == null ? null : ASTFactory.scriptTag(scriptTag), directives == null ? new List<Directive>() : directives, declarations == null ? new List<CompilationUnitMember>() : declarations, TokenFactory.token3(TokenType.EOF));
static ConditionalExpression conditionalExpression(Expression condition, Expression thenExpression, Expression elseExpression) => new ConditionalExpression.full(condition, TokenFactory.token3(TokenType.QUESTION), thenExpression, TokenFactory.token3(TokenType.COLON), elseExpression);
static ConstructorDeclaration constructorDeclaration(Identifier returnType, String name, FormalParameterList parameters, List<ConstructorInitializer> initializers) => new ConstructorDeclaration.full(null, null, TokenFactory.token(Keyword.EXTERNAL), null, null, returnType, name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier3(name), parameters, initializers == null || initializers.isEmpty ? null : TokenFactory.token3(TokenType.PERIOD), initializers == null ? new List<ConstructorInitializer>() : initializers, null, emptyFunctionBody());
static ConstructorDeclaration constructorDeclaration2(Keyword constKeyword, Keyword factoryKeyword, Identifier returnType, String name, FormalParameterList parameters, List<ConstructorInitializer> initializers, FunctionBody body) => new ConstructorDeclaration.full(null, null, null, constKeyword == null ? null : TokenFactory.token(constKeyword), factoryKeyword == null ? null : TokenFactory.token(factoryKeyword), returnType, name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier3(name), parameters, initializers == null || initializers.isEmpty ? null : TokenFactory.token3(TokenType.PERIOD), initializers == null ? new List<ConstructorInitializer>() : initializers, null, body);
@@ -306,7 +306,7 @@
}
return new HideCombinator.full(TokenFactory.token2("hide"), identifierList);
}
- static PrefixedIdentifier identifier(SimpleIdentifier prefix, SimpleIdentifier identifier2) => new PrefixedIdentifier.full(prefix, TokenFactory.token3(TokenType.PERIOD), identifier2);
+ static PrefixedIdentifier identifier(SimpleIdentifier prefix, SimpleIdentifier identifier) => new PrefixedIdentifier.full(prefix, TokenFactory.token3(TokenType.PERIOD), identifier);
static SimpleIdentifier identifier3(String lexeme) => new SimpleIdentifier.full(TokenFactory.token4(TokenType.IDENTIFIER, lexeme));
static PrefixedIdentifier identifier4(String prefix, SimpleIdentifier identifier) => new PrefixedIdentifier.full(identifier3(prefix), TokenFactory.token3(TokenType.PERIOD), identifier);
static PrefixedIdentifier identifier5(String prefix, String identifier) => new PrefixedIdentifier.full(identifier3(prefix), TokenFactory.token3(TokenType.PERIOD), identifier3(identifier));
@@ -324,8 +324,8 @@
static InterpolationExpression interpolationExpression2(String identifier) => new InterpolationExpression.full(TokenFactory.token3(TokenType.STRING_INTERPOLATION_IDENTIFIER), identifier3(identifier), null);
static InterpolationString interpolationString(String contents, String value) => new InterpolationString.full(TokenFactory.token2(contents), value);
static IsExpression isExpression(Expression expression, bool negated, TypeName type) => new IsExpression.full(expression, TokenFactory.token(Keyword.IS), negated ? TokenFactory.token3(TokenType.BANG) : null, type);
- static Label label(SimpleIdentifier label2) => new Label.full(label2, TokenFactory.token3(TokenType.COLON));
- static Label label2(String label22) => label(identifier3(label22));
+ static Label label(SimpleIdentifier label) => new Label.full(label, TokenFactory.token3(TokenType.COLON));
+ static Label label2(String label) => ASTFactory.label(identifier3(label));
static LabeledStatement labeledStatement(List<Label> labels, Statement statement) => new LabeledStatement.full(labels, statement);
static LibraryDirective libraryDirective(List<Annotation> metadata, LibraryIdentifier libraryName) => new LibraryDirective.full(null, metadata, TokenFactory.token(Keyword.LIBRARY), libraryName, TokenFactory.token3(TokenType.SEMICOLON));
static LibraryDirective libraryDirective2(String libraryName) => libraryDirective(new List<Annotation>(), libraryIdentifier2([libraryName]));
@@ -374,7 +374,7 @@
static RethrowExpression rethrowExpression() => new RethrowExpression.full(TokenFactory.token(Keyword.RETHROW));
static ReturnStatement returnStatement() => returnStatement2(null);
static ReturnStatement returnStatement2(Expression expression) => new ReturnStatement.full(TokenFactory.token(Keyword.RETURN), expression, TokenFactory.token3(TokenType.SEMICOLON));
- static ScriptTag scriptTag(String scriptTag2) => new ScriptTag.full(TokenFactory.token2(scriptTag2));
+ static ScriptTag scriptTag(String scriptTag) => new ScriptTag.full(TokenFactory.token2(scriptTag));
static ShowCombinator showCombinator(List<SimpleIdentifier> identifiers) => new ShowCombinator.full(TokenFactory.token2("show"), list(identifiers));
static ShowCombinator showCombinator2(List<String> identifiers) {
List<SimpleIdentifier> identifierList = new List<SimpleIdentifier>();
@@ -1420,7 +1420,7 @@
assertSource("library l;", ASTFactory.compilationUnit3([ASTFactory.libraryDirective2("l")]));
}
void test_visitCompilationUnit_directive_declaration() {
- assertSource("library l; var a;", ASTFactory.compilationUnit4(ASTFactory.list([(ASTFactory.libraryDirective2("l") as Directive)]), ASTFactory.list([(ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember)])));
+ assertSource("library l; var a;", ASTFactory.compilationUnit4(ASTFactory.list([ASTFactory.libraryDirective2("l") as Directive]), ASTFactory.list([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember])));
}
void test_visitCompilationUnit_empty() {
assertSource("", ASTFactory.compilationUnit());
@@ -1435,7 +1435,7 @@
assertSource("!#/bin/dartvm library l;", ASTFactory.compilationUnit7("!#/bin/dartvm", [ASTFactory.libraryDirective2("l")]));
}
void test_visitCompilationUnit_script_directives_declarations() {
- assertSource("!#/bin/dartvm library l; var a;", ASTFactory.compilationUnit8("!#/bin/dartvm", ASTFactory.list([(ASTFactory.libraryDirective2("l") as Directive)]), ASTFactory.list([(ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember)])));
+ assertSource("!#/bin/dartvm library l; var a;", ASTFactory.compilationUnit8("!#/bin/dartvm", ASTFactory.list([ASTFactory.libraryDirective2("l") as Directive]), ASTFactory.list([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember])));
}
void test_visitConditionalExpression() {
assertSource("a ? b : c", ASTFactory.conditionalExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"), ASTFactory.identifier3("c")));
@@ -1451,7 +1451,7 @@
}
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, "a", ASTFactory.identifier3("b")) as ConstructorInitializer,
ASTFactory.constructorFieldInitializer(false, "c", ASTFactory.identifier3("d"))]), ASTFactory.blockFunctionBody2([])));
}
void test_visitConstructorDeclaration_multipleParameters() {
@@ -1463,7 +1463,7 @@
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.blockFunctionBody2([])));
+ 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")));
@@ -1511,7 +1511,7 @@
assertSource(";", ASTFactory.emptyStatement());
}
void test_visitExportDirective_combinator() {
- assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [(ASTFactory.showCombinator([ASTFactory.identifier3("A")]) as Combinator)]));
+ assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [ASTFactory.showCombinator([ASTFactory.identifier3("A")]) as Combinator]));
}
void test_visitExportDirective_combinators() {
assertSource("export 'a.dart' show A hide B;", ASTFactory.exportDirective2("a.dart", [
@@ -1630,7 +1630,7 @@
assertSource("for (; c;) {}", ASTFactory.forStatement(null as Expression, ASTFactory.identifier3("c"), null, ASTFactory.block([])));
}
void test_visitForStatement_cu() {
- assertSource("for (; c; u) {}", ASTFactory.forStatement(null as Expression, ASTFactory.identifier3("c"), ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+ assertSource("for (; c; u) {}", ASTFactory.forStatement(null as Expression, ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
}
void test_visitForStatement_e() {
assertSource("for (e;;) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), null, null, ASTFactory.block([])));
@@ -1639,10 +1639,10 @@
assertSource("for (e; c;) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), ASTFactory.identifier3("c"), null, ASTFactory.block([])));
}
void test_visitForStatement_ecu() {
- assertSource("for (e; c; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), ASTFactory.identifier3("c"), ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+ assertSource("for (e; c; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
}
void test_visitForStatement_eu() {
- assertSource("for (e;; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), null, ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+ assertSource("for (e;; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
}
void test_visitForStatement_i() {
assertSource("for (var i;;) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, null, ASTFactory.block([])));
@@ -1651,13 +1651,13 @@
assertSource("for (var i; c;) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier3("c"), null, ASTFactory.block([])));
}
void test_visitForStatement_icu() {
- assertSource("for (var i; c; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier3("c"), ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+ assertSource("for (var i; c; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
}
void test_visitForStatement_iu() {
- assertSource("for (var i;; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+ assertSource("for (var i;; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
}
void test_visitForStatement_u() {
- assertSource("for (;; u) {}", ASTFactory.forStatement(null as Expression, null, ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+ assertSource("for (;; u) {}", ASTFactory.forStatement(null as Expression, null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
}
void test_visitFunctionDeclaration_getter() {
assertSource("get f() {}", ASTFactory.functionDeclaration(null, Keyword.GET, "f", ASTFactory.functionExpression()));
diff --git a/pkg/analyzer_experimental/test/generated/element_test.dart b/pkg/analyzer_experimental/test/generated/element_test.dart
index d2571ca..954592e 100644
--- a/pkg/analyzer_experimental/test/generated/element_test.dart
+++ b/pkg/analyzer_experimental/test/generated/element_test.dart
@@ -1716,24 +1716,24 @@
constructor.type = constructorType;
return constructor;
}
- static ExportElementImpl exportFor(LibraryElement exportedLibrary2, List<NamespaceCombinator> combinators2) {
+ static ExportElementImpl exportFor(LibraryElement exportedLibrary, List<NamespaceCombinator> combinators) {
ExportElementImpl spec = new ExportElementImpl();
- spec.exportedLibrary = exportedLibrary2;
- spec.combinators = combinators2;
+ spec.exportedLibrary = exportedLibrary;
+ spec.combinators = combinators;
return spec;
}
- static FieldElementImpl fieldElement(String name, bool isStatic, bool isFinal, bool isConst, Type2 type2) {
+ static FieldElementImpl fieldElement(String name, bool isStatic, bool isFinal, bool isConst, Type2 type) {
FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier3(name));
field.const3 = isConst;
field.final2 = isFinal;
field.static = isStatic;
- field.type = type2;
+ field.type = type;
PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
getter.getter = true;
getter.static = isStatic;
getter.synthetic = true;
getter.variable = field;
- getter.returnType = type2;
+ getter.returnType = type;
field.getter = getter;
FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
getter.type = getterType;
@@ -1743,7 +1743,7 @@
setter.static = isStatic;
setter.synthetic = true;
setter.variable = field;
- setter.parameters = <ParameterElement> [requiredParameter2("_${name}", type2)];
+ setter.parameters = <ParameterElement> [requiredParameter2("_${name}", type)];
setter.returnType = VoidTypeImpl.instance;
setter.type = new FunctionTypeImpl.con1(setter);
field.setter = setter;
@@ -1822,26 +1822,26 @@
}
return _objectElement;
}
- static PropertyAccessorElementImpl getterElement(String name, bool isStatic, Type2 type2) {
+ static PropertyAccessorElementImpl getterElement(String name, bool isStatic, Type2 type) {
FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier3(name));
field.static = isStatic;
field.synthetic = true;
- field.type = type2;
+ field.type = type;
PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
getter.getter = true;
getter.static = isStatic;
getter.variable = field;
- getter.returnType = type2;
+ getter.returnType = type;
field.getter = getter;
FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
getter.type = getterType;
return getter;
}
- static ImportElementImpl importFor(LibraryElement importedLibrary2, PrefixElement prefix2, List<NamespaceCombinator> combinators2) {
+ static ImportElementImpl importFor(LibraryElement importedLibrary, PrefixElement prefix, List<NamespaceCombinator> combinators) {
ImportElementImpl spec = new ImportElementImpl();
- spec.importedLibrary = importedLibrary2;
- spec.prefix = prefix2;
- spec.combinators = combinators2;
+ spec.importedLibrary = importedLibrary;
+ spec.prefix = prefix;
+ spec.combinators = combinators;
return spec;
}
static LibraryElementImpl library(AnalysisContext context, String libraryName) {
@@ -1855,7 +1855,7 @@
}
static LocalVariableElementImpl localVariableElement(Identifier name) => new LocalVariableElementImpl(name);
static LocalVariableElementImpl localVariableElement2(String name) => new LocalVariableElementImpl(ASTFactory.identifier3(name));
- static MethodElementImpl methodElement(String methodName, Type2 returnType2, List<Type2> argumentTypes) {
+ static MethodElementImpl methodElement(String methodName, Type2 returnType, List<Type2> argumentTypes) {
MethodElementImpl method = new MethodElementImpl.con1(ASTFactory.identifier3(methodName));
int count = argumentTypes.length;
List<ParameterElement> parameters = new List<ParameterElement>(count);
@@ -1866,7 +1866,7 @@
parameters[i] = parameter;
}
method.parameters = parameters;
- method.returnType = returnType2;
+ method.returnType = returnType;
FunctionTypeImpl methodType = new FunctionTypeImpl.con1(method);
method.type = methodType;
return method;
@@ -1876,10 +1876,10 @@
parameter.parameterKind = ParameterKind.NAMED;
return parameter;
}
- static ParameterElementImpl namedParameter2(String name, Type2 type2) {
+ static ParameterElementImpl namedParameter2(String name, Type2 type) {
ParameterElementImpl parameter = new ParameterElementImpl.con1(ASTFactory.identifier3(name));
parameter.parameterKind = ParameterKind.NAMED;
- parameter.type = type2;
+ parameter.type = type;
return parameter;
}
static ParameterElementImpl positionalParameter(String name) {
@@ -1887,10 +1887,10 @@
parameter.parameterKind = ParameterKind.POSITIONAL;
return parameter;
}
- static ParameterElementImpl positionalParameter2(String name, Type2 type2) {
+ static ParameterElementImpl positionalParameter2(String name, Type2 type) {
ParameterElementImpl parameter = new ParameterElementImpl.con1(ASTFactory.identifier3(name));
parameter.parameterKind = ParameterKind.POSITIONAL;
- parameter.type = type2;
+ parameter.type = type;
return parameter;
}
static PrefixElementImpl prefix(String name) => new PrefixElementImpl(ASTFactory.identifier3(name));
@@ -1899,26 +1899,26 @@
parameter.parameterKind = ParameterKind.REQUIRED;
return parameter;
}
- static ParameterElementImpl requiredParameter2(String name, Type2 type2) {
+ static ParameterElementImpl requiredParameter2(String name, Type2 type) {
ParameterElementImpl parameter = new ParameterElementImpl.con1(ASTFactory.identifier3(name));
parameter.parameterKind = ParameterKind.REQUIRED;
- parameter.type = type2;
+ parameter.type = type;
return parameter;
}
- static PropertyAccessorElementImpl setterElement(String name, bool isStatic, Type2 type2) {
+ static PropertyAccessorElementImpl setterElement(String name, bool isStatic, Type2 type) {
FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier3(name));
field.static = isStatic;
field.synthetic = true;
- field.type = type2;
+ field.type = type;
PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
getter.getter = true;
getter.static = isStatic;
getter.variable = field;
- getter.returnType = type2;
+ getter.returnType = type;
field.getter = getter;
FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
getter.type = getterType;
- ParameterElementImpl parameter = requiredParameter2("a", type2);
+ ParameterElementImpl parameter = requiredParameter2("a", type);
PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(field);
setter.setter = true;
setter.static = isStatic;
@@ -1932,7 +1932,7 @@
}
static TopLevelVariableElementImpl topLevelVariableElement(Identifier name) => new TopLevelVariableElementImpl.con1(name);
static TopLevelVariableElementImpl topLevelVariableElement2(String name) => new TopLevelVariableElementImpl.con2(name);
- static TopLevelVariableElementImpl topLevelVariableElement3(String name, bool isFinal, Type2 type2) {
+ static TopLevelVariableElementImpl topLevelVariableElement3(String name, bool isFinal, Type2 type) {
TopLevelVariableElementImpl variable = new TopLevelVariableElementImpl.con2(name);
variable.final2 = isFinal;
PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(variable);
@@ -1940,7 +1940,7 @@
getter.static = true;
getter.synthetic = true;
getter.variable = variable;
- getter.returnType = type2;
+ getter.returnType = type;
variable.getter = getter;
FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
getter.type = getterType;
@@ -1950,7 +1950,7 @@
setter.static = true;
setter.synthetic = true;
setter.variable = variable;
- setter.parameters = <ParameterElement> [requiredParameter2("_${name}", type2)];
+ setter.parameters = <ParameterElement> [requiredParameter2("_${name}", type)];
setter.returnType = VoidTypeImpl.instance;
setter.type = new FunctionTypeImpl.con1(setter);
variable.setter = setter;
diff --git a/pkg/analyzer_experimental/test/generated/resolver_test.dart b/pkg/analyzer_experimental/test/generated/resolver_test.dart
index 0e21d4b..6229a06 100644
--- a/pkg/analyzer_experimental/test/generated/resolver_test.dart
+++ b/pkg/analyzer_experimental/test/generated/resolver_test.dart
@@ -1290,6 +1290,16 @@
assertNoErrors(source);
verify([source]);
}
+ void test_constructorDeclaration_scope_signature() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const app = 0;",
+ "class A {",
+ " A(@app int app) {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
void test_constWithNonConstantArgument_literals() {
Source source = addSource(EngineTestCase.createSource([
"class A {",
@@ -1533,6 +1543,30 @@
assertNoErrors(source);
verify([source]);
}
+ void test_functionDeclaration_scope_returnType() {
+ Source source = addSource(EngineTestCase.createSource(["int f(int) {}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_functionDeclaration_scope_signature() {
+ Source source = addSource(EngineTestCase.createSource(["const app = 0;", "f(@app int app) {}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_functionTypeAlias_scope_returnType() {
+ Source source = addSource(EngineTestCase.createSource(["typedef int f(int);"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+ void test_functionTypeAlias_scope_signature() {
+ Source source = addSource(EngineTestCase.createSource(["const app = 0;", "typedef int f(@app int app);"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
void test_implicitThisReferenceInInitializer_constructorName() {
Source source = addSource(EngineTestCase.createSource([
"class A {",
@@ -1684,6 +1718,21 @@
assertNoErrors(source);
verify([source]);
}
+ void test_importPrefixes_withFirstLetterDifference() {
+ Source source = addSource(EngineTestCase.createSource([
+ "library L;",
+ "import 'lib1.dart' as math;",
+ "import 'lib2.dart' as path;",
+ "main() {",
+ " math.test1();",
+ " path.test2();",
+ "}"]));
+ addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "test1() {}"]));
+ addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "test2() {}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
void test_inconsistentCaseExpressionTypes() {
Source source = addSource(EngineTestCase.createSource([
"f(var p) {",
@@ -2204,6 +2253,16 @@
assertNoErrors(source);
verify([source]);
}
+ void test_methodDeclaration_scope_signature() {
+ Source source = addSource(EngineTestCase.createSource([
+ "const app = 0;",
+ "class A {",
+ " foo(@app int app) {}",
+ "}"]));
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
void test_misMatchedGetterAndSetterTypes_instance_sameTypes() {
Source source = addSource(EngineTestCase.createSource([
"class C {",
@@ -3452,6 +3511,10 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_constWithUndefinedConstructorDefault);
});
+ _ut.test('test_constructorDeclaration_scope_signature', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_constructorDeclaration_scope_signature);
+ });
_ut.test('test_defaultValueInFunctionTypeAlias', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_defaultValueInFunctionTypeAlias);
@@ -3560,6 +3623,22 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_finalNotInitialized_redirectingConstructor);
});
+ _ut.test('test_functionDeclaration_scope_returnType', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_functionDeclaration_scope_returnType);
+ });
+ _ut.test('test_functionDeclaration_scope_signature', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_functionDeclaration_scope_signature);
+ });
+ _ut.test('test_functionTypeAlias_scope_returnType', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_functionTypeAlias_scope_returnType);
+ });
+ _ut.test('test_functionTypeAlias_scope_signature', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_functionTypeAlias_scope_signature);
+ });
_ut.test('test_implicitThisReferenceInInitializer_constructorName', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_constructorName);
@@ -3616,6 +3695,10 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_importOfNonLibrary_libraryNotDeclared);
});
+ _ut.test('test_importPrefixes_withFirstLetterDifference', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_importPrefixes_withFirstLetterDifference);
+ });
_ut.test('test_inconsistentCaseExpressionTypes', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_inconsistentCaseExpressionTypes);
@@ -3812,6 +3895,10 @@
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_memberWithClassName_setter);
});
+ _ut.test('test_methodDeclaration_scope_signature', () {
+ final __test = new NonErrorResolverTest();
+ runJUnitTest(__test, __test.test_methodDeclaration_scope_signature);
+ });
_ut.test('test_misMatchedGetterAndSetterTypes_instance_sameTypes', () {
final __test = new NonErrorResolverTest();
runJUnitTest(__test, __test.test_misMatchedGetterAndSetterTypes_instance_sameTypes);
@@ -4906,6 +4993,18 @@
resolve(source);
assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
}
+ void test_undefinedMethod_assignmentExpression() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "class B {",
+ " f(A a) {",
+ " A a2 = new A();",
+ " a += a2;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+ }
void test_undefinedMethod_ignoreTypePropagation() {
Source source = addSource(EngineTestCase.createSource([
"class A {}",
@@ -4913,7 +5012,7 @@
" m() {}",
"}",
"class C {",
- "f() {",
+ " f() {",
" A a = new B();",
" a.m();",
" }",
@@ -4943,6 +5042,16 @@
resolve(source);
assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
+ void test_undefinedOperator_postfixExpression() {
+ Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", " a++;", "}"]));
+ resolve(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ }
+ void test_undefinedOperator_prefixExpression() {
+ Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", " ++a;", "}"]));
+ resolve(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+ }
void test_undefinedSetter() {
Source source = addSource(EngineTestCase.createSource(["class T {}", "f(T e1) { e1.m = 0; }"]));
resolve(source);
@@ -5280,6 +5389,10 @@
final __test = new StaticTypeWarningCodeTest();
runJUnitTest(__test, __test.test_undefinedMethod);
});
+ _ut.test('test_undefinedMethod_assignmentExpression', () {
+ final __test = new StaticTypeWarningCodeTest();
+ runJUnitTest(__test, __test.test_undefinedMethod_assignmentExpression);
+ });
_ut.test('test_undefinedMethod_ignoreTypePropagation', () {
final __test = new StaticTypeWarningCodeTest();
runJUnitTest(__test, __test.test_undefinedMethod_ignoreTypePropagation);
@@ -5300,6 +5413,14 @@
final __test = new StaticTypeWarningCodeTest();
runJUnitTest(__test, __test.test_undefinedOperator_plus);
});
+ _ut.test('test_undefinedOperator_postfixExpression', () {
+ final __test = new StaticTypeWarningCodeTest();
+ runJUnitTest(__test, __test.test_undefinedOperator_postfixExpression);
+ });
+ _ut.test('test_undefinedOperator_prefixExpression', () {
+ final __test = new StaticTypeWarningCodeTest();
+ runJUnitTest(__test, __test.test_undefinedOperator_prefixExpression);
+ });
_ut.test('test_undefinedSetter', () {
final __test = new StaticTypeWarningCodeTest();
runJUnitTest(__test, __test.test_undefinedSetter);
@@ -5705,6 +5826,122 @@
assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
verify([source]);
}
+ void test_undefinedGetter() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "f(var a) {",
+ " if(a is A) {",
+ " return a.m;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_GETTER]);
+ }
+ void test_undefinedGetter_message() {
+ JUnitTestCase.assertEquals(StaticTypeWarningCode.UNDEFINED_GETTER.message, StaticWarningCode.UNDEFINED_GETTER.message);
+ }
+ void test_undefinedMethod() {
+ Source source = addSource(EngineTestCase.createSource([
+ "f() {",
+ " var a = 'str';",
+ " a.notAMethodOnString();",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_METHOD]);
+ }
+ void test_undefinedMethod_assignmentExpression() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "class B {",
+ " f(var a, var a2) {",
+ " a = new A();",
+ " a2 = new A();",
+ " a += a2;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_METHOD]);
+ }
+ void test_undefinedOperator_indexBoth() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "f(var a) {",
+ " if(a is A) {",
+ " a[0]++;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR, HintCode.UNDEFINED_OPERATOR]);
+ }
+ void test_undefinedOperator_indexGetter() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "f(var a) {",
+ " if(a is A) {",
+ " a[0];",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+ void test_undefinedOperator_indexSetter() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "f(var a) {",
+ " if(a is A) {",
+ " a[0] = 1;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+ void test_undefinedOperator_plus() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "f(var a) {",
+ " if(a is A) {",
+ " a + 1;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+ void test_undefinedOperator_postfixExpression() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "f(var a) {",
+ " if(a is A) {",
+ " a++;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+ void test_undefinedOperator_prefixExpression() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "f(var a) {",
+ " if(a is A) {",
+ " ++a;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+ void test_undefinedSetter() {
+ Source source = addSource(EngineTestCase.createSource([
+ "class A {}",
+ "f(var a) {",
+ " if(a is A) {",
+ " a.m = 0;",
+ " }",
+ "}"]));
+ resolve(source);
+ assertErrors(source, [HintCode.UNDEFINED_SETTER]);
+ }
+ void test_undefinedSetter_message() {
+ JUnitTestCase.assertEquals(StaticTypeWarningCode.UNDEFINED_SETTER.message, StaticWarningCode.UNDEFINED_SETTER.message);
+ }
void test_unnecessaryCast_type_supertype() {
Source source = addSource(EngineTestCase.createSource(["m(int i) {", " var b = i as Object;", "}"]));
resolve(source);
@@ -5959,6 +6196,54 @@
final __test = new HintCodeTest();
runJUnitTest(__test, __test.test_typeCheck_type_not_Null);
});
+ _ut.test('test_undefinedGetter', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedGetter);
+ });
+ _ut.test('test_undefinedGetter_message', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedGetter_message);
+ });
+ _ut.test('test_undefinedMethod', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedMethod);
+ });
+ _ut.test('test_undefinedMethod_assignmentExpression', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedMethod_assignmentExpression);
+ });
+ _ut.test('test_undefinedOperator_indexBoth', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedOperator_indexBoth);
+ });
+ _ut.test('test_undefinedOperator_indexGetter', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedOperator_indexGetter);
+ });
+ _ut.test('test_undefinedOperator_indexSetter', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedOperator_indexSetter);
+ });
+ _ut.test('test_undefinedOperator_plus', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedOperator_plus);
+ });
+ _ut.test('test_undefinedOperator_postfixExpression', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedOperator_postfixExpression);
+ });
+ _ut.test('test_undefinedOperator_prefixExpression', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedOperator_prefixExpression);
+ });
+ _ut.test('test_undefinedSetter', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedSetter);
+ });
+ _ut.test('test_undefinedSetter_message', () {
+ final __test = new HintCodeTest();
+ runJUnitTest(__test, __test.test_undefinedSetter_message);
+ });
_ut.test('test_unnecessaryCast_type_supertype', () {
final __test = new HintCodeTest();
runJUnitTest(__test, __test.test_unnecessaryCast_type_supertype);
@@ -6420,7 +6705,7 @@
* @throws AssertionFailedError if any errors have been reported
*/
void assertNoErrors(Source source) {
- EngineTestCase.assertLength(0, analysisContext.computeErrors(source));
+ assertErrors(source, []);
}
/**
@@ -16466,16 +16751,16 @@
* @param body the body of the function
* @return a resolved function expression
*/
- FunctionExpression resolvedFunctionExpression(FormalParameterList parameters2, FunctionBody body) {
+ FunctionExpression resolvedFunctionExpression(FormalParameterList parameters, FunctionBody body) {
List<ParameterElement> parameterElements = new List<ParameterElement>();
- for (FormalParameter parameter in parameters2.parameters) {
+ for (FormalParameter parameter in parameters.parameters) {
ParameterElementImpl element = new ParameterElementImpl.con1(parameter.identifier);
element.parameterKind = parameter.kind;
element.type = _typeProvider.dynamicType;
parameter.identifier.staticElement = element;
parameterElements.add(element);
}
- FunctionExpression node = ASTFactory.functionExpression2(parameters2, body);
+ FunctionExpression node = ASTFactory.functionExpression2(parameters, body);
FunctionElementImpl element = new FunctionElementImpl.con1(null);
element.parameters = new List.from(parameterElements);
element.type = new FunctionTypeImpl.con1(element);
@@ -16514,12 +16799,12 @@
* @param variableName the name of the variable
* @return a simple identifier that has been resolved to a variable element with the given type
*/
- SimpleIdentifier resolvedVariable(InterfaceType type2, String variableName) {
+ SimpleIdentifier resolvedVariable(InterfaceType type, String variableName) {
SimpleIdentifier identifier = ASTFactory.identifier3(variableName);
VariableElementImpl element = ElementFactory.localVariableElement(identifier);
- element.type = type2;
+ element.type = type;
identifier.staticElement = element;
- identifier.staticType = type2;
+ identifier.staticType = type;
return identifier;
}
@@ -16529,14 +16814,14 @@
* @param parameter the parameter whose type is to be set
* @param type the new type of the given parameter
*/
- void setType(FormalParameter parameter, Type2 type2) {
+ void setType(FormalParameter parameter, Type2 type) {
SimpleIdentifier identifier = parameter.identifier;
Element element = identifier.staticElement;
if (element is! ParameterElement) {
element = new ParameterElementImpl.con1(identifier);
identifier.staticElement = element;
}
- ((element as ParameterElementImpl)).type = type2;
+ ((element as ParameterElementImpl)).type = type;
}
static dartSuite() {
_ut.group('StaticTypeAnalyzerTest', () {
@@ -17035,6 +17320,13 @@
assertNoErrors(source);
verify([source]);
}
+ void test_unusedImport_annotationOnDirective() {
+ Source source = addSource(EngineTestCase.createSource(["library L;", "@A()", "import 'lib1.dart';"]));
+ Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", " const A() {}", "}"]));
+ resolve(source);
+ assertErrors(source, []);
+ verify([source, source2]);
+ }
void test_unusedImport_core_library() {
Source source = addSource(EngineTestCase.createSource(["library L;", "import 'dart:core';"]));
resolve(source);
@@ -17169,6 +17461,10 @@
final __test = new NonHintCodeTest();
runJUnitTest(__test, __test.test_unnecessaryCast_type_dynamic);
});
+ _ut.test('test_unusedImport_annotationOnDirective', () {
+ final __test = new NonHintCodeTest();
+ runJUnitTest(__test, __test.test_unusedImport_annotationOnDirective);
+ });
_ut.test('test_unusedImport_core_library', () {
final __test = new NonHintCodeTest();
runJUnitTest(__test, __test.test_unusedImport_core_library);
diff --git a/pkg/analyzer_experimental/test/generated/scanner_test.dart b/pkg/analyzer_experimental/test/generated/scanner_test.dart
index aa74c46..e709c47 100644
--- a/pkg/analyzer_experimental/test/generated/scanner_test.dart
+++ b/pkg/analyzer_experimental/test/generated/scanner_test.dart
@@ -2089,7 +2089,7 @@
void assertError(ScannerErrorCode expectedError, int expectedOffset, String source) {
GatheringErrorListener listener = new GatheringErrorListener();
scan(source, listener);
- listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [(source.codeUnitAt(expectedOffset) as int)])]);
+ listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [source.codeUnitAt(expectedOffset) as int])]);
}
/**
diff --git a/pkg/analyzer_experimental/test/generated/test_support.dart b/pkg/analyzer_experimental/test/generated/test_support.dart
index d0977be..90af45a 100644
--- a/pkg/analyzer_experimental/test/generated/test_support.dart
+++ b/pkg/analyzer_experimental/test/generated/test_support.dart
@@ -232,9 +232,9 @@
* @param errorCode the error code being searched for
* @return `true` if an error with the given error code has been gathered
*/
- bool hasError(ErrorCode errorCode2) {
+ bool hasError(ErrorCode errorCode) {
for (AnalysisError error in errors) {
- if (identical(error.errorCode, errorCode2)) {
+ if (identical(error.errorCode, errorCode)) {
return true;
}
}
diff --git a/pkg/analyzer_experimental/test/services/formatter_test.dart b/pkg/analyzer_experimental/test/services/formatter_test.dart
index 51187f3..c2e1f18 100644
--- a/pkg/analyzer_experimental/test/services/formatter_test.dart
+++ b/pkg/analyzer_experimental/test/services/formatter_test.dart
@@ -598,7 +598,8 @@
'}\n',
'class A {\n'
' int _a;\n'
- ' A(a) : _a = a;\n'
+ ' A(a)\n'
+ ' : _a = a;\n'
'}\n'
);
});
@@ -622,6 +623,20 @@
'part of foo;\n'
);
});
+
+ test('CU (cons inits)', () {
+ expectCUFormatsTo('class X {\n'
+ ' var x, y;\n'
+ ' X() : x = 1, y = 2;\n'
+ '}\n',
+ 'class X {\n'
+ ' var x, y;\n'
+ ' X()\n'
+ ' : x = 1,\n'
+ ' y = 2;\n'
+ '}\n'
+ );
+ });
test('stmt', () {
expectStmtFormatsTo(
@@ -763,6 +778,21 @@
'}'
);
});
+
+ test('Statement (if)', () {
+ expectStmtFormatsTo('if (true) print("true!");',
+ 'if (true) print("true!");');
+ expectStmtFormatsTo('if (true) { print("true!"); }',
+ 'if (true) {\n'
+ ' print("true!");\n'
+ '}');
+ expectStmtFormatsTo('if (true) print("true!"); else print("false!");',
+ 'if (true) {\n'
+ ' print("true!");\n'
+ '} else {\n'
+ ' print("false!");\n'
+ '}');
+ });
test('initialIndent', () {
var formatter = new CodeFormatter(
diff --git a/pkg/browser/lib/interop.js b/pkg/browser/lib/interop.js
index 40e1700..8577e4f 100644
--- a/pkg/browser/lib/interop.js
+++ b/pkg/browser/lib/interop.js
@@ -224,7 +224,9 @@
(function() {
// Proxy support for js.dart.
- var globalContext = window;
+ // We don't use 'window' because we might be in a web worker, but we don't
+ // use 'self' because not all browsers support it
+ var globalContext = function() { return this; }();
// Table for local objects and functions that are proxied.
function ProxiedObjectTable() {
diff --git a/pkg/custom_element/lib/custom-elements.debug.js b/pkg/custom_element/lib/custom-elements.debug.js
index 843e8a7..a391b8a 100644
--- a/pkg/custom_element/lib/custom-elements.debug.js
+++ b/pkg/custom_element/lib/custom-elements.debug.js
@@ -1207,8 +1207,8 @@
changeAttribute.call(this, name, value, setAttribute);
}
var removeAttribute = prototype.removeAttribute;
- prototype.removeAttribute = function(name, value) {
- changeAttribute.call(this, name, value, removeAttribute);
+ prototype.removeAttribute = function(name) {
+ changeAttribute.call(this, name, null, removeAttribute);
}
}
@@ -1217,7 +1217,7 @@
operation.apply(this, arguments);
if (this.attributeChangedCallback
&& (this.getAttribute(name) !== oldValue)) {
- this.attributeChangedCallback(name, oldValue);
+ this.attributeChangedCallback(name, oldValue, value);
}
}
diff --git a/pkg/custom_element/lib/custom-elements.min.js b/pkg/custom_element/lib/custom-elements.min.js
index fdec66a..8ecb7a4 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.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}}}();
+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){l.call(this,a,null,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,b)}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 98bef74..19824cf 100644
--- a/pkg/custom_element/lib/custom_element.dart
+++ b/pkg/custom_element/lib/custom_element.dart
@@ -23,6 +23,8 @@
import 'package:meta/meta.dart';
import 'src/custom_tag_name.dart';
+part 'src/attribute_map.dart';
+
// TODO(jmesserly): replace with a real custom element polyfill.
// This is just something temporary.
/**
@@ -115,6 +117,7 @@
/** The web component element wrapped by this class. */
Element _host;
List _shadowRoots;
+ _AttributeMap _attributes;
/**
* Shadow roots generated by dwc for each custom element, indexed by the
@@ -171,6 +174,9 @@
* Note that [root] will be a [ShadowRoot] if the browser supports Shadow DOM.
*/
void created() {}
+ // Added for analyzer warnings
+ @deprecated
+ void createdCallback() {}
/** Invoked when this component gets inserted in the DOM tree. */
void inserted() {}
@@ -182,10 +188,8 @@
@deprecated
void leftView() {}
- // TODO(jmesserly): how do we implement this efficiently?
- // See https://github.com/dart-lang/web-ui/issues/37
/** Invoked when any attribute of the component is modified. */
- void attributeChanged(String name, String oldValue, String newValue) {}
+ void attributeChanged(String name, String oldValue) {}
get model => host.model;
@@ -272,9 +276,12 @@
Node insertAllBefore(Iterable<Node> newChild, Node refChild) =>
host.insertAllBefore(newChild, refChild);
- Map<String, String> get attributes => host.attributes;
+ Map<String, String> get attributes {
+ if (_attributes == null) _attributes = new _AttributeMap(this);
+ return _attributes;
+ }
set attributes(Map<String, String> value) {
- host.attributes = value;
+ (attributes as _AttributeMap)._replaceAll(value);
}
List<Element> get elements => host.children;
@@ -316,10 +323,7 @@
String get nodeValue => host.nodeValue;
- @deprecated
- // TODO(sigmund): restore the old return type and call host.on when
- // dartbug.com/8131 is fixed.
- dynamic get on { throw new UnsupportedError('on is deprecated'); }
+ Events get on => host.on;
String get contentEditable => host.contentEditable;
set contentEditable(String v) { host.contentEditable = v; }
diff --git a/pkg/custom_element/lib/src/attribute_map.dart b/pkg/custom_element/lib/src/attribute_map.dart
new file mode 100644
index 0000000..8af62c3
--- /dev/null
+++ b/pkg/custom_element/lib/src/attribute_map.dart
@@ -0,0 +1,85 @@
+// 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 custom_element;
+
+/**
+ * Represents an attribute map of model values. If any items are added,
+ * removed, or replaced, then observers that are listening to [changes]
+ * will be notified.
+ */
+class _AttributeMap implements Map<String, String> {
+ final CustomElement _element;
+ final Map<String, String> _map;
+
+ /** Creates an attribute map wrapping the host attributes. */
+ _AttributeMap(CustomElement element)
+ : _element = element, _map = element.host.attributes;
+
+ // Forward all read methods:
+ Iterable<String> get keys => _map.keys;
+ Iterable<String> get values => _map.values;
+ int get length =>_map.length;
+ bool get isEmpty => _map.isEmpty;
+ bool get isNotEmpty => _map.isNotEmpty;
+ bool containsValue(Object value) => _map.containsValue(value);
+ bool containsKey(Object key) => _map.containsKey(key);
+ String operator [](Object key) => _map[key];
+ void forEach(void f(String key, String value)) => _map.forEach(f);
+ String toString() => _map.toString();
+
+ // Override the write methods and ensure attributeChanged is called:
+ void operator []=(String key, String value) {
+ int len = _map.length;
+ String oldValue = _map[key];
+ _map[key] = value;
+ if (len != _map.length || !identical(oldValue, value)) {
+ _element.attributeChanged(key, oldValue);
+ }
+ }
+
+ void addAll(Map<String, String> other) {
+ other.forEach((String key, String value) { this[key] = value; });
+ }
+
+ String putIfAbsent(String key, String ifAbsent()) {
+ int len = _map.length;
+ String result = _map.putIfAbsent(key, ifAbsent);
+ if (len != _map.length) {
+ _element.attributeChanged(key, null);
+ }
+ return result;
+ }
+
+ String remove(Object key) {
+ int len = _map.length;
+ String result = _map.remove(key);
+ if (len != _map.length) {
+ _element.attributeChanged(key, result);
+ }
+ return result;
+ }
+
+ void clear() {
+ int len = _map.length;
+ if (len > 0) {
+ _map.forEach((key, value) {
+ _element.attributeChanged(key, value);
+ });
+ }
+ _map.clear();
+ }
+
+ /**
+ * This is not a [Map] method. We use it to implement "set attributes", which
+ * is a global replace operation. Rather than [clear] followed by [addAll],
+ * we try to be a bit smarter.
+ */
+ void _replaceAll(Map<String, String> other) {
+ for (var key in keys) {
+ if (!other.containsKey(key)) remove(key);
+ }
+ addAll(other);
+ }
+}
diff --git a/pkg/docgen/test/single_library_test.dart b/pkg/docgen/test/single_library_test.dart
index 78c8a5d..dd4044e 100644
--- a/pkg/docgen/test/single_library_test.dart
+++ b/pkg/docgen/test/single_library_test.dart
@@ -10,7 +10,7 @@
main() {
group('Generate docs for', () {
test('one simple file.', () {
- var temporaryDir = new Directory('single_library').createTempSync();
+ var temporaryDir = Directory.createSystemTempSync('single_library_');
var fileName = path.join(temporaryDir.path, 'temp.dart');
var file = new File(fileName);
file.writeAsStringSync('''
diff --git a/pkg/observe/lib/src/bind_property.dart b/pkg/observe/lib/src/bind_property.dart
index c8524e7..c35bfb9 100644
--- a/pkg/observe/lib/src/bind_property.dart
+++ b/pkg/observe/lib/src/bind_property.dart
@@ -13,7 +13,7 @@
*
* MyModel() {
* ...
- * _sub = bindProperty(_otherModel, const Symbol('value'),
+ * _sub = onPropertyChange(_otherModel, const Symbol('value'),
* () => notifyProperty(this, const Symbol('prop'));
* }
*
@@ -23,7 +23,8 @@
*
* See also [notifyProperty].
*/
-StreamSubscription bindProperty(Observable source, Symbol sourceName,
+// TODO(jmesserly): make this an instance method?
+StreamSubscription onPropertyChange(Observable source, Symbol sourceName,
void callback()) {
return source.changes.listen((records) {
for (var record in records) {
diff --git a/pkg/observe/lib/src/observable.dart b/pkg/observe/lib/src/observable.dart
index d39f84a..c5c56ab 100644
--- a/pkg/observe/lib/src/observable.dart
+++ b/pkg/observe/lib/src/observable.dart
@@ -7,7 +7,7 @@
/**
* Use `@observable` to make a field automatically observable.
*/
-const Object observable = const _ObservableAnnotation();
+const ObservableProperty observable = const ObservableProperty();
/**
* Interface representing an observable object. This is used by data in
@@ -124,7 +124,7 @@
if (field.isFinal || field.isStatic || field.isPrivate) continue;
for (var meta in field.metadata) {
- if (identical(observable, meta.reflectee)) {
+ if (meta.reflectee is ObservableProperty) {
var name = field.simpleName;
// Note: since this is a field, getting the value shouldn't execute
// user code, so we don't need to worry about errors.
@@ -220,12 +220,16 @@
/**
- * The type of the `@observable` annotation.
+ * An annotation that is used to make a property observable.
+ * Normally this is used via the [observable] constant, for example:
*
- * Library private because you should be able to use the [observable] field
- * to get the one and only instance. We could make it public though, if anyone
- * needs it for some reason.
+ * class Monster {
+ * @observable int health;
+ * }
+ *
+ * If needed, you can subclass this to create another annotation that will also
+ * be treated as observable.
*/
-class _ObservableAnnotation {
- const _ObservableAnnotation();
+class ObservableProperty {
+ const ObservableProperty();
}
diff --git a/pkg/observe/lib/transform.dart b/pkg/observe/lib/transform.dart
index 029a017..d1e8139 100644
--- a/pkg/observe/lib/transform.dart
+++ b/pkg/observe/lib/transform.dart
@@ -34,7 +34,8 @@
// as much work as applying the transform. We rather have some false
// positives here, and then generate no outputs when we apply this
// transform.
- return input.readAsString().then((c) => c.contains("@observable"));
+ return input.readAsString().then(
+ (c) => c.contains("@observable") || c.contains("@published"));
}
Future apply(Transform transform) {
@@ -102,8 +103,12 @@
_getSpan(SourceFile file, ASTNode node) => file.span(node.offset, node.end);
-/** True if the node has the `@observable` annotation. */
-bool _hasObservable(AnnotatedNode node) => _hasAnnotation(node, 'observable');
+/** True if the node has the `@observable` or `@published` annotation. */
+// TODO(jmesserly): it is not good to be hard coding these. We should do a
+// resolve and do a proper ObservableProperty subtype check. However resolve
+// is very expensive in analyzer_experimental, so it isn't feasible yet.
+bool _hasObservable(AnnotatedNode node) =>
+ _hasAnnotation(node, 'observable') || _hasAnnotation(node, 'published');
bool _hasAnnotation(AnnotatedNode node, String name) {
// TODO(jmesserly): this isn't correct if the annotation has been imported
@@ -134,7 +139,7 @@
declaresObservable = true;
} else if (id.name == 'ChangeNotifierBase') {
declaresObservable = true;
- } else if (id.name != 'PolymerElement' && id.name != 'CustomElement'
+ } else if (id.name != 'HtmlElement' && id.name != 'CustomElement'
&& id.name != 'Object') {
// TODO(sigmund): this is conservative, consider using type-resolution to
// improve this check.
@@ -183,14 +188,13 @@
}
if (_hasObservable(member)) {
if (!declaresObservable) {
- logger.warning('Observable fields should be put in an observable'
- ' objects. Please declare that this class extends from '
+ logger.warning('Observable fields should be put in an observable '
+ 'objects. Please declare that this class extends from '
'ObservableBase, includes ObservableMixin, or implements '
'Observable.',
_getSpan(file, member));
-
}
- _transformFields(member.fields, code, member.offset, member.end);
+ _transformFields(file, member, code, logger);
var names = member.fields.variables.map((v) => v.name.name);
@@ -289,40 +293,89 @@
_hasKeyword(fields.keyword, Keyword.FINAL);
}
-void _transformFields(VariableDeclarationList fields, TextEditTransaction code,
- int begin, int end) {
+void _transformFields(SourceFile file, FieldDeclaration member,
+ TextEditTransaction code, TransformLogger logger) {
+ final fields = member.fields;
if (_isReadOnly(fields)) return;
- var indent = guessIndent(code.original, begin);
- var replace = new StringBuffer();
+ // Private fields aren't supported:
+ for (var field in fields.variables) {
+ final name = field.name.name;
+ if (Identifier.isPrivateName(name)) {
+ logger.warning('Cannot make private field $name observable.',
+ _getSpan(file, field));
+ return;
+ }
+ }
// Unfortunately "var" doesn't work in all positions where type annotations
// are allowed, such as "var get name". So we use "dynamic" instead.
var type = 'dynamic';
if (fields.type != null) {
type = _getOriginalCode(code, fields.type);
+ } else if (_hasKeyword(fields.keyword, Keyword.VAR)) {
+ // Replace 'var' with 'dynamic'
+ code.edit(fields.keyword.offset, fields.keyword.end, type);
}
- for (var field in fields.variables) {
- var initializer = '';
- if (field.initializer != null) {
- initializer = ' = ${_getOriginalCode(code, field.initializer)}';
- }
+ // Note: the replacements here are a bit subtle. It needs to support multiple
+ // fields declared via the same @observable, as well as preserving newlines.
+ // (Preserving newlines is important because it allows the generated code to
+ // be debugged without needing a source map.)
+ //
+ // For example:
+ //
+ // @observable
+ // @otherMetaData
+ // Foo
+ // foo = 1, bar = 2,
+ // baz;
+ //
+ // Will be transformed into something like:
+ //
+ // @observable
+ // @OtherMetaData()
+ // Foo
+ // get foo => __foo; Foo __foo = 1; set foo ...; ... bar ...
+ // @observable @OtherMetaData() Foo get baz => __baz; Foo baz; ...
+ //
+ // Metadata is moved to the getter.
- var name = field.name.name;
+ String metadata = '';
+ if (fields.variables.length > 1) {
+ metadata = member.metadata
+ .map((m) => _getOriginalCode(code, m))
+ .join(' ');
+ }
- // TODO(jmesserly): should we generate this one one line, so source maps
- // don't break?
- if (replace.length > 0) replace.write('\n\n$indent');
- replace.write('''
-$type __\$$name$initializer;
-$type get $name => __\$$name;
-set $name($type value) {
- __\$$name = notifyPropertyChange(const Symbol('$name'), __\$$name, value);
+ for (int i = 0; i < fields.variables.length; i++) {
+ final field = fields.variables[i];
+ final name = field.name.name;
+
+ var beforeInit = 'get $name => __\$$name; $type __\$$name';
+
+ // The first field is expanded differently from subsequent fields, because
+ // we can reuse the metadata and type annotation.
+ if (i > 0) beforeInit = '$metadata $type $beforeInit';
+
+ code.edit(field.name.offset, field.name.end, beforeInit);
+
+ // Replace comma with semicolon
+ final end = _findFieldSeperator(field.endToken.next);
+ if (end.type == TokenType.COMMA) code.edit(end.offset, end.end, ';');
+
+ code.edit(end.end, end.end, ' set $name($type value) { '
+ '__\$$name = notifyPropertyChange(#$name, __\$$name, value); }');
+ }
}
-'''.replaceAll('\n', '\n$indent'));
- }
- code.edit(begin, end, '$replace');
+Token _findFieldSeperator(Token token) {
+ while (token != null) {
+ if (token.type == TokenType.COMMA || token.type == TokenType.SEMICOLON) {
+ break;
+ }
+ token = token.next;
+ }
+ return token;
}
diff --git a/pkg/observe/test/transform_test.dart b/pkg/observe/test/transform_test.dart
index 9a64fac..5a4b138 100644
--- a/pkg/observe/test/transform_test.dart
+++ b/pkg/observe/test/transform_test.dart
@@ -47,17 +47,24 @@
_testInitializers('this.a, {this.b}', '(a, {b}) : __\$a = a, __\$b = b');
});
- group('test full text', () {
- test('with changes', () {
- return _transform(_sampleObservable('A', 'foo'))
- .then((output) => expect(output, _sampleObservableOutput('A', 'foo')));
- });
+ for (var annotation in ['observable', 'published']) {
+ group('@$annotation full text', () {
+ test('with changes', () {
+ return _transform(_sampleObservable(annotation)).then(
+ (out) => expect(out, _sampleObservableOutput(annotation)));
+ });
- test('no changes', () {
- var input = 'class A {/*@observable annotation to trigger transform */;}';
- return _transform(input).then((output) => expect(output, input));
+ test('complex with changes', () {
+ return _transform(_complexObservable(annotation)).then(
+ (out) => expect(out, _complexObservableOutput(annotation)));
+ });
+
+ test('no changes', () {
+ var input = 'class A {/*@$annotation annotation to trigger transform */;}';
+ return _transform(input).then((output) => expect(output, input));
+ });
});
- });
+ }
}
_testClause(String clauses, String expected) {
@@ -121,37 +128,64 @@
Asset get primaryInput => _asset;
_MockTransform(this._asset);
- Future<Asset> getInput(Asset id) {
+ Future<Asset> getInput(AssetId id) {
if (id == primaryInput.id) return new Future.value(primaryInput);
- fail();
+ fail('_MockTransform fail');
}
void addOutput(Asset output) {
outs.add(output);
}
+
+ readInput(id) => throw new UnimplementedError();
+ readInputAsString(id, {encoding}) => throw new UnimplementedError();
}
-String _sampleObservable(String className, String fieldName) => '''
-library ${className}_$fieldName;
+String _sampleObservable(String annotation) => '''
+library A_foo;
import 'package:observe/observe.dart';
-class $className extends ObservableBase {
- @observable int $fieldName;
- $className(this.$fieldName);
+class A extends ObservableBase {
+ @$annotation int foo;
+ A(this.foo);
}
''';
-String _sampleObservableOutput(String className, String fieldName) => '''
-library ${className}_$fieldName;
-import 'package:observe/observe.dart';
+String _sampleObservableOutput(String annotation) =>
+ "library A_foo;\n"
+ "import 'package:observe/observe.dart';\n\n"
+ "class A extends ChangeNotifierBase {\n"
+ " @$annotation int get foo => __\$foo; int __\$foo; "
+ "${_makeSetter('int', 'foo')}\n"
+ " A(foo) : __\$foo = foo;\n"
+ "}\n";
-class $className extends ChangeNotifierBase {
- int __\$$fieldName;
- int get $fieldName => __\$$fieldName;
- set $fieldName(int value) {
- __\$$fieldName = notifyPropertyChange(const Symbol('$fieldName'), __\$$fieldName, value);
- }
-
- $className($fieldName) : __\$$fieldName = $fieldName;
+_makeSetter(type, name) => 'set $name($type value) { '
+ '__\$$name = notifyPropertyChange(#$name, __\$$name, value); }';
+
+String _complexObservable(String annotation) => '''
+class Foo extends ObservableBase {
+ @$annotation
+ @otherMetadata
+ Foo
+ foo/*D*/= 1, bar =/*A*/2/*B*/,
+ quux/*C*/;
+
+ @$annotation var baz;
}
''';
+
+String _complexObservableOutput(String annotation) =>
+ "class Foo extends ChangeNotifierBase {\n"
+ " @$annotation\n"
+ " @otherMetadata\n"
+ " Foo\n"
+ " get foo => __\$foo; Foo __\$foo/*D*/= 1; "
+ "${_makeSetter('Foo', 'foo')} "
+ "@$annotation @otherMetadata Foo get bar => __\$bar; "
+ "Foo __\$bar =/*A*/2/*B*/; ${_makeSetter('Foo', 'bar')}\n"
+ " @$annotation @otherMetadata Foo get quux => __\$quux; "
+ "Foo __\$quux/*C*/; ${_makeSetter('Foo', 'quux')}\n\n"
+ " @$annotation dynamic get baz => __\$baz; dynamic __\$baz; "
+ "${_makeSetter('dynamic', 'baz')}\n"
+ "}\n";
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 9ff7d8d..d5c5205 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -57,24 +57,42 @@
stack_trace/test/trace_test: Fail # http://dartbug.com/12380
crypto/test/sha256_test: Pass, Fail # Issue 12502
crypto/test/hmac_sha256_test: Pass, Fail # Issue 12502
-polymer/test/events_test: Fail # Issue 12865, 13197
+polymer/test/attr_deserialize_test: Fail # Issue 12865, 13197
+polymer/test/attr_mustache_test: Fail # Issue 12865, 13197
polymer/test/event_path_test: Fail # Issue 12865, 13197
+polymer/test/events_test: Fail # Issue 12865, 13197
+polymer/test/prop_attr_reflection_test: Fail # Issue 12865, 13197
[ $runtime == ie9 || $runtime == ie10 ]
-polymer/test/events_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/attr_deserialize_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/attr_mustache_test: Fail, Timeout # Issue 12865, 13197, 13260
polymer/test/event_path_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/events_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/prop_attr_reflection_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/publish_attributes_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/take_attributes_test: Fail, Timeout # Issue 12865, 13197, 13260
[ $system == windows && ($runtime == chrome || $runtime == ff) ]
-polymer/test/events_test: Pass, Timeout # Issue 13260
+polymer/test/attr_deserialize_test: Pass, Timeout # Issue 13260
+polymer/test/attr_mustache_test: Pass, Timeout # Issue 13260
polymer/test/event_path_test: Pass, Timeout # Issue 13260
+polymer/test/events_test: Pass, Timeout # Issue 13260
+polymer/test/prop_attr_reflection_test: Pass, Timeout # Issue 13260
+polymer/test/publish_attributes_test: Pass, Timeout # Issue 13260
+polymer/test/take_attributes_test: Pass, Timeout # Issue 13260
# Skip browser-specific tests on VM
[ $runtime == vm ]
path/test/browser_test: Fail, OK # Uses dart:html
intl/test/find_default_locale_browser_test: Skip
intl/test/date_time_format_http_request_test: Skip
-polymer/test/events_test: Fail, OK # Uses dart:html
+polymer/test/attr_deserialize_test: Fail, OK # Uses dart:html
+polymer/test/attr_mustache_test: Fail, OK # Uses dart:html
polymer/test/event_path_test: Fail, OK # Uses dart:html
+polymer/test/events_test: Fail, OK # Uses dart:html
+polymer/test/prop_attr_reflection_test: Fail, OK # Uses dart:html
+polymer/test/publish_attributes_test: Fail, OK # Uses dart:html
+polymer/test/take_attributes_test: Fail, OK # Uses dart:html
polymer/example: Fail, OK # Uses dart:html
[ $runtime == vm && $system == windows ]
@@ -140,7 +158,6 @@
observe/test/transform_test: Fail, OK # Uses dart:io.
path/test/io_test: Fail, OK # Uses dart:io.
polymer/test/build/*: Fail, OK # Uses dart:io.
-polymer/test/utils_test: Fail, OK # Uses dart:io.
watcher/test/*: Fail, OK # Uses dart:io.
scheduled_test/test/descriptor/async_test: Fail # http://dartbug.com/8440
@@ -182,17 +199,17 @@
# not minified.
unittest/test/*_minified_test: Skip # DO NOT COPY THIS UNLESS YOU WORK ON DART2JS
+[ $arch == mips ]
+*: Skip # Issue 13650
+
[ $arch == arm ]
-*: Skip
+*: Skip # Issue 13624
[ $arch == simarm ]
-*: Skip
+watcher/test/no_subscription_test: Pass, Fail # Issue 13705.
-[ $arch == mips ]
-*: Skip
-
-[ $arch == simmips ]
-*: Skip
+[ $arch == simarm || $arch == simmips ]
+third_party/html5lib/test/tokenizer_test: Pass, Slow
# Skip serialization test that explicitly has no library declaration in the
# test on Dartium, which requires all tests to have a library.
diff --git a/pkg/polymer/example/component/news/web/news-component.html b/pkg/polymer/example/component/news/web/news-component.html
index 7f63f54..70254b8 100644
--- a/pkg/polymer/example/component/news/web/news-component.html
+++ b/pkg/polymer/example/component/news/web/news-component.html
@@ -31,7 +31,7 @@
@initMethod
_init() {
- registerPolymerElement('x-news', () => new XNews());
+ Polymer.register('x-news', XNews);
}
</script>
</polymer-element>
diff --git a/pkg/polymer/lib/boot.js b/pkg/polymer/lib/boot.js
index 0a3fe62..2bcb590 100644
--- a/pkg/polymer/lib/boot.js
+++ b/pkg/polymer/lib/boot.js
@@ -56,8 +56,30 @@
' tool to compile a depolyable JavaScript version')
return;
}
- document.write(
- '<script src="packages/html_import/html_import.min.js"></script>');
+
+
+ // Load HTML Imports:
+ var htmlImportsSrc = 'src="packages/html_import/html_import.min.js"';
+ document.write('<script ' + htmlImportsSrc + '></script>');
+ var importScript = document.querySelector('script[' + htmlImportsSrc + ']');
+ importScript.addEventListener('load', function() {
+ // NOTE: this is from polymer/src/lib/dom.js
+ window.HTMLImports.importer.preloadSelectors +=
+ ', polymer-element link[rel=stylesheet]';
+ });
+
+ // TODO(jmesserly): we need this in deploy tool too.
+ // NOTE: this is from polymer/src/boot.js:
+ // FOUC prevention tactic
+ var style = document.createElement('style');
+ style.textContent = 'body {opacity: 0;}';
+ var head = document.querySelector('head');
+ head.insertBefore(style, head.firstChild);
+
+ window.addEventListener('WebComponentsReady', function() {
+ document.body.style.webkitTransition = 'opacity 0.3s';
+ document.body.style.opacity = 1;
+ });
// Extract a Dart import URL from a script tag, which is the 'src' attribute
// of the script tag, or a data-url with the script contents for inlined code.
diff --git a/pkg/polymer/lib/component_build.dart b/pkg/polymer/lib/component_build.dart
index 6a923f0..cdd0820 100644
--- a/pkg/polymer/lib/component_build.dart
+++ b/pkg/polymer/lib/component_build.dart
@@ -6,6 +6,7 @@
@deprecated
library build_utils;
+import 'dart:async';
import 'package:meta/meta.dart';
import 'builder.dart' as builder;
@@ -18,5 +19,5 @@
Future build(List<String> arguments, List<String> entryPoints,
{bool printTime: true, bool shouldPrint: true}) {
return builder.build(
- entryPoints: entryPoints, options: parseOptions(arguments));
+ entryPoints: entryPoints, options: builder.parseOptions(arguments));
}
diff --git a/pkg/polymer/lib/deserialize.dart b/pkg/polymer/lib/deserialize.dart
new file mode 100644
index 0000000..7f72c2c
--- /dev/null
+++ b/pkg/polymer/lib/deserialize.dart
@@ -0,0 +1,51 @@
+// 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 polymer.deserialize;
+
+import 'dart:convert' show JSON;
+import 'dart:mirrors' show reflect, TypeMirror;
+
+final _typeHandlers = () {
+ // TODO(jmesserly): switch to map and symbol literal form when supported.
+ var m = new Map();
+ m[const Symbol('dart.core.String')] = (x, _) => x;
+ m[const Symbol('dart.core.Null')] = (x, _) => x;
+ m[const Symbol('dart.core.DateTime')] = (x, _) {
+ // TODO(jmesserly): shouldn't need to try-catch here
+ // See: https://code.google.com/p/dart/issues/detail?id=1878
+ try {
+ return DateTime.parse(x);
+ } catch (e) {
+ return new DateTime.now();
+ }
+ };
+ m[const Symbol('dart.core.bool')] = (x, _) => x != 'false';
+ m[const Symbol('dart.core.int')] =
+ (x, def) => int.parse(x, onError: (_) => def);
+ m[const Symbol('dart.core.double')] =
+ (x, def) => double.parse(x, (_) => def);
+ return m;
+}();
+
+/**
+ * Convert representation of [value] based on type of [defaultValue].
+ */
+Object deserializeValue(String value, Object defaultValue, TypeMirror type) {
+ var handler = _typeHandlers[type.qualifiedName];
+ if (handler != null) return handler(value, defaultValue);
+
+ try {
+ // If the string is an object, we can parse is with the JSON library.
+ // include convenience replace for single-quotes. If the author omits
+ // quotes altogether, parse will fail.
+ return JSON.decode(value.replaceAll("'", '"'));
+
+ // TODO(jmesserly): deserialized JSON is not assignable to most objects in
+ // Dart. We should attempt to convert it appropriately.
+ } catch(e) {
+ // The object isn't valid JSON, return the raw value
+ return value;
+ }
+}
diff --git a/pkg/polymer/lib/job.dart b/pkg/polymer/lib/job.dart
new file mode 100644
index 0000000..677784a
--- /dev/null
+++ b/pkg/polymer/lib/job.dart
@@ -0,0 +1,53 @@
+// 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 polymer.job;
+
+import 'dart:async' show Timer;
+
+/**
+ * Invoke [callback] in [wait], unless the job is re-registered,
+ * which resets the timer. For example:
+ *
+ * _myJob = runJob(_myJob, callback, const Duration(milliseconds: 100));
+ *
+ * Returns a job handle which can be used to re-register a job.
+ */
+// Dart note: renamed to runJob to avoid conflict with instance member "job".
+Job runJob(Job job, void callback(), Duration wait) {
+ if (job != null) {
+ job.stop();
+ } else {
+ job = new Job();
+ }
+ job.go(callback, wait);
+ return job;
+}
+
+// TODO(jmesserly): it isn't clear to me what is supposed to be public API here.
+// Or what name we should use. "Job" is awfully generic.
+// (The type itself is not exported in Polymer.)
+class Job {
+ Function _callback;
+ Timer _timer;
+
+ void go(void callback(), Duration wait) {
+ this._callback = callback;
+ _timer = new Timer(wait, complete);
+ }
+
+ void stop() {
+ if (_timer != null) {
+ _timer.cancel();
+ _timer = null;
+ }
+ }
+
+ void complete() {
+ if (_timer != null) {
+ stop();
+ _callback();
+ }
+ }
+}
diff --git a/pkg/polymer/lib/platform.dart b/pkg/polymer/lib/platform.dart
new file mode 100644
index 0000000..5dc5c3e
--- /dev/null
+++ b/pkg/polymer/lib/platform.dart
@@ -0,0 +1,41 @@
+// 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.
+
+/**
+ * Exposes helper functionality for interacting with the platform. Similar to
+ * the [Platform] class from dart:html.
+ */
+// TODO(jmesserly): in Polymer this is a static class called "Platform", but
+// that conflicts with dart:html. What should we do? Does this functionality
+// belong in html's Platform instead?
+library polymer.platform;
+
+import 'dart:html' show Text, MutationObserver;
+import 'dart:collection' show Queue;
+import 'package:observe/src/microtask.dart' show performMicrotaskCheckpoint;
+
+void flush() {
+ endOfMicrotask(performMicrotaskCheckpoint);
+}
+
+int _iterations = 0;
+final Queue _callbacks = new Queue();
+final Text _twiddle = () {
+ var twiddle = new Text('');
+ new MutationObserver((x, y) {
+ while (_callbacks.isNotEmpty) {
+ try {
+ _callbacks.removeFirst()();
+ } catch (e) { // Dart note: fire the error async.
+ new Completer().completeError(e);
+ }
+ }
+ }).observe(twiddle, characterData: true);
+ return twiddle;
+}();
+
+void endOfMicrotask(void callback()) {
+ _twiddle.text = '${_iterations++}';
+ _callbacks.add(callback);
+}
diff --git a/pkg/polymer/lib/polymer.dart b/pkg/polymer/lib/polymer.dart
index e417fe5..a7ae73f 100644
--- a/pkg/polymer/lib/polymer.dart
+++ b/pkg/polymer/lib/polymer.dart
@@ -40,136 +40,31 @@
library polymer;
import 'dart:async';
+import 'dart:collection' show HashMap;
+import 'dart:html';
+import 'dart:js' as js;
import 'dart:mirrors';
+import 'package:custom_element/custom_element.dart';
+import 'package:logging/logging.dart' show Logger, Level;
import 'package:mdv/mdv.dart' as mdv;
+import 'package:mdv/mdv.dart' show NodeBinding;
+import 'package:meta/meta.dart' show deprecated;
+import 'package:observe/observe.dart';
import 'package:observe/src/microtask.dart';
import 'package:path/path.dart' as path;
-import 'polymer_element.dart' show registerPolymerElement;
+import 'package:polymer_expressions/polymer_expressions.dart'
+ show PolymerExpressions;
+
+import 'deserialize.dart' as deserialize;
+import 'job.dart';
+import 'platform.dart' as platform;
export 'package:custom_element/custom_element.dart';
export 'package:observe/observe.dart';
export 'package:observe/html.dart';
export 'package:observe/src/microtask.dart';
-export 'polymer_element.dart';
-
-
-/** Annotation used to automatically register polymer elements. */
-class CustomTag {
- final String tagName;
- const CustomTag(this.tagName);
-}
-
-/**
- * Metadata used to label static or top-level methods that are called
- * automatically when loading the library of a custom element.
- */
-const initMethod = const _InitMethodAnnotation();
-
-/**
- * Initializes a polymer application as follows:
- * * set up up polling for observable changes
- * * initialize MDV
- * * for each library in [libraries], register custom elements labeled with
- * [CustomTag] and invoke the initialization method on it.
- *
- * The initialization on each library is either a method named `main` or
- * a top-level function and annotated with [initMethod].
- *
- * The urls in [libraries] can be absolute or relative to [srcUrl].
- */
-void initPolymer(List<String> libraries, [String srcUrl]) {
- wrapMicrotask(() {
- // DOM events don't yet go through microtasks, so we catch those here.
- new Timer.periodic(new Duration(milliseconds: 125),
- (_) => performMicrotaskCheckpoint());
-
- // TODO(jmesserly): mdv should use initMdv instead of mdv.initialize.
- mdv.initialize();
- for (var lib in libraries) {
- _loadLibrary(lib, srcUrl);
- }
- })();
-}
-
-/** All libraries in the current isolate. */
-final _libs = currentMirrorSystem().libraries;
-
-/**
- * Reads the library at [uriString] (which can be an absolute URI or a relative
- * URI from [srcUrl]), and:
- *
- * * If present, invokes `main`.
- *
- * * If present, invokes any top-level and static functions marked
- * with the [initMethod] annotation (in the order they appear).
- *
- * * Registers any [PolymerElement] that is marked with the [CustomTag]
- * annotation.
- */
-void _loadLibrary(String uriString, [String srcUrl]) {
- var uri = Uri.parse(uriString);
- if (uri.scheme == '' && srcUrl != null) {
- uri = Uri.parse(path.normalize(path.join(path.dirname(srcUrl), uriString)));
- }
- var lib = _libs[uri];
- if (lib == null) {
- print('warning: $uri library not found');
- return;
- }
-
- // Invoke `main`, if present.
- if (lib.functions[const Symbol('main')] != null) {
- lib.invoke(const Symbol('main'), const []);
- }
-
- // Search top-level functions marked with @initMethod
- for (var f in lib.functions.values) {
- _maybeInvoke(lib, f);
- }
-
- for (var c in lib.classes.values) {
- // Search for @CustomTag on classes
- for (var m in c.metadata) {
- var meta = m.reflectee;
- if (meta is CustomTag) {
- registerPolymerElement(meta.tagName,
- () => c.newInstance(const Symbol(''), const []).reflectee);
- }
- }
-
- // TODO(sigmund): check also static methods marked with @initMethod.
- // This is blocked on two bugs:
- // - dartbug.com/12133 (static methods are incorrectly listed as top-level
- // in dart2js, so they end up being called twice)
- // - dartbug.com/12134 (sometimes "method.metadata" throws an exception,
- // we could wrap and hide those exceptions, but it's not ideal).
- }
-}
-
-void _maybeInvoke(ObjectMirror obj, MethodMirror method) {
- var annotationFound = false;
- for (var meta in method.metadata) {
- if (identical(meta.reflectee, initMethod)) {
- annotationFound = true;
- break;
- }
- }
- if (!annotationFound) return;
- if (!method.isStatic) {
- print("warning: methods marked with @initMethod should be static,"
- " ${method.simpleName} is not.");
- return;
- }
- if (!method.parameters.where((p) => !p.isOptional).isEmpty) {
- print("warning: methods marked with @initMethod should take no "
- "arguments, ${method.simpleName} expects some.");
- return;
- }
- obj.invoke(method.simpleName, const []);
-}
-
-class _InitMethodAnnotation {
- const _InitMethodAnnotation();
-}
+part 'src/declaration.dart';
+part 'src/instance.dart';
+part 'src/loader.dart';
diff --git a/pkg/polymer/lib/polymer_element.dart b/pkg/polymer/lib/polymer_element.dart
index a7ade34..c004985 100644
--- a/pkg/polymer/lib/polymer_element.dart
+++ b/pkg/polymer/lib/polymer_element.dart
@@ -4,555 +4,4 @@
library polymer.polymer_element;
-import 'dart:async';
-import 'dart:html';
-import 'dart:mirrors';
-import 'dart:js' as js;
-
-import 'package:custom_element/custom_element.dart';
-import 'package:mdv/mdv.dart' show NodeBinding;
-import 'package:observe/observe.dart';
-import 'package:observe/src/microtask.dart';
-import 'package:polymer_expressions/polymer_expressions.dart';
-
-import 'src/utils.dart' show toCamelCase, toHyphenedName;
-
-/**
- * Registers a [PolymerElement]. This is similar to [registerCustomElement]
- * but it is designed to work with the `<element>` element and adds additional
- * features.
- */
-void registerPolymerElement(String localName, PolymerElement create()) {
- registerCustomElement(localName, () => create().._initialize(localName));
-}
-
-/**
- * *Warning*: many features of this class are not fully implemented.
- *
- * The base class for Polymer elements. It provides convience features on top
- * of the custom elements web standard.
- *
- * Currently it supports publishing attributes via:
- *
- * <element name="..." attributes="foo, bar, baz">
- *
- * Any attribute published this way can be used in a data binding expression,
- * and it should contain a corresponding DOM field.
- *
- * *Warning*: due to dart2js mirror limititations, the mapping from HTML
- * attribute to element property is a conversion from `dash-separated-words`
- * to camelCase, rather than searching for a property with the same name.
- */
-// TODO(jmesserly): fix the dash-separated-words issue. Polymer uses lowercase.
-class PolymerElement extends CustomElement with _EventsMixin {
- // This is a partial port of:
- // https://github.com/Polymer/polymer/blob/stable/src/attrs.js
- // https://github.com/Polymer/polymer/blob/stable/src/bindProperties.js
- // https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
- // https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
- // TODO(jmesserly): we still need to port more of the functionality
-
- /// The one syntax to rule them all.
- static BindingDelegate _polymerSyntax = new PolymerExpressions();
- // TODO(sigmund): delete. The next line is only added to avoid warnings from
- // the analyzer (see http://dartbug.com/11672)
- Element get host => super.host;
-
- bool get applyAuthorStyles => false;
- bool get resetStyleInheritance => false;
-
- /**
- * The declaration of this polymer-element, used to extract template contents
- * and other information.
- */
- static Map<String, Element> _declarations = {};
- static Element getDeclaration(String localName) {
- if (localName == null) return null;
- var element = _declarations[localName];
- if (element == null) {
- element = document.query('polymer-element[name="$localName"]');
- _declarations[localName] = element;
- }
- return element;
- }
-
- Map<String, PathObserver> _publishedAttrs;
- Map<String, StreamSubscription> _bindings;
- final List<String> _localNames = [];
-
- void _initialize(String localName) {
- if (localName == null) return;
-
- var declaration = getDeclaration(localName);
- if (declaration == null) return;
-
- var extendee = declaration.attributes['extends'];
- if (extendee != null) {
- // Skip normal tags, only initialize parent custom elements.
- if (extendee.contains('-')) _initialize(extendee);
- }
-
- _parseHostEvents(declaration);
- _parseLocalEvents(declaration);
- _publishAttributes(declaration);
-
- var templateContent = declaration.query('template').content;
- _shimStyling(templateContent, localName);
-
- _localNames.add(localName);
- }
-
- void _publishAttributes(elementElement) {
- _bindings = {};
- _publishedAttrs = {};
-
- var attrs = elementElement.attributes['attributes'];
- if (attrs != null) {
- // attributes='a b c' or attributes='a,b,c'
- for (var name in attrs.split(attrs.contains(',') ? ',' : ' ')) {
- name = name.trim();
-
- // TODO(jmesserly): PathObserver is overkill here; it helps avoid
- // "new Symbol" and other mirrors-related warnings.
- _publishedAttrs[name] = new PathObserver(this, toCamelCase(name));
- }
- }
- }
-
- void created() {
- // TODO(jmesserly): this breaks until we get some kind of type conversion.
- // _publishedAttrs.forEach((name, propObserver) {
- // var value = attributes[name];
- // if (value != null) propObserver.value = value;
- // });
- _initShadowRoot();
- _addHostListeners();
- }
-
- /**
- * Creates the document fragment to use for each instance of the custom
- * element, given the `<template>` node. By default this is equivalent to:
- *
- * template.createInstance(this, polymerSyntax);
- *
- * Where polymerSyntax is a singleton `PolymerExpressions` instance from the
- * [polymer_expressions](https://pub.dartlang.org/packages/polymer_expressions)
- * package.
- *
- * You can override this method to change the instantiation behavior of the
- * template, for example to use a different data-binding syntax.
- */
- DocumentFragment instanceTemplate(Element template) =>
- template.createInstance(this, _polymerSyntax);
-
- void _initShadowRoot() {
- for (var localName in _localNames) {
- var declaration = getDeclaration(localName);
- var root = createShadowRoot(localName);
- _addInstanceListeners(root, localName);
-
- root.applyAuthorStyles = applyAuthorStyles;
- root.resetStyleInheritance = resetStyleInheritance;
-
- var templateNode = declaration.query('template');
- if (templateNode == null) return;
-
- // Create the contents of the element's ShadowRoot, and add them.
- root.nodes.add(instanceTemplate(templateNode));
- }
- }
-
- NodeBinding createBinding(String name, model, String path) {
- var propObserver = _publishedAttrs[name];
- if (propObserver != null) {
- return new _PolymerBinding(this, name, model, path, propObserver);
- }
- return super.createBinding(name, model, path);
- }
-
- /**
- * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
- */
- void _shimStyling(DocumentFragment template, String localName) {
- if (js.context == null) return;
-
- var platform = js.context['Platform'];
- if (platform == null) return;
-
- var style = template.query('style');
- if (style == null) return;
-
- var shadowCss = platform['ShadowCSS'];
- if (shadowCss == null) return;
-
- // TODO(terry): Remove calls to shimShadowDOMStyling2 and replace with
- // shimShadowDOMStyling when we support unwrapping dart:html
- // Element to a JS DOM node.
- var shimShadowDOMStyling2 = shadowCss['shimShadowDOMStyling2'];
- if (shimShadowDOMStyling2 == null) return;
-
- var scopedCSS = shimShadowDOMStyling2.apply(shadowCss,
- [style.text, localName]);
-
- // TODO(terry): Remove when shimShadowDOMStyling is called we don't need to
- // replace original CSS with scoped CSS shimShadowDOMStyling
- // does that.
- style.text = scopedCSS;
- }
-}
-
-class _PolymerBinding extends NodeBinding {
- final PathObserver _publishedAttr;
-
- _PolymerBinding(node, property, model, path, PathObserver this._publishedAttr)
- : super(node, property, model, path);
-
- void boundValueChanged(newValue) {
- _publishedAttr.value = newValue;
- }
-}
-
-/**
- * Polymer features to handle the syntactic sugar on-* to declare to
- * automatically map event handlers to instance methods of the [PolymerElement].
- * This mixin is a port of:
- * https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
- * https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
- */
-abstract class _EventsMixin {
- // TODO(sigmund): implement the Dart equivalent of 'inheritDelegates'
- // Notes about differences in the implementation below:
- // - _templateDelegates: polymer stores the template delegates directly on
- // the template node (see in parseLocalEvents: 't.delegates = {}'). Here we
- // simply use a separate map, where keys are the name of the
- // custom-element.
- // - _listenLocal we return true/false and propagate that up, JS
- // implementation does't forward the return value.
- // - we don't keep the side-table (weak hash map) of unhandled events (see
- // handleIfNotHandled)
- // - we don't use event.type to dispatch events, instead we save the event
- // name with the event listeners. We do so to avoid translating back and
- // forth between Dom and Dart event names.
-
- // ---------------------------------------------------------------------------
- // The following section was ported from:
- // https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
- // ---------------------------------------------------------------------------
-
- /** Maps event names and their associated method in the element class. */
- final Map<String, String> _delegates = {};
-
- /** Expected events per element node. */
- // TODO(sigmund): investigate whether we need more than 1 set of local events
- // per element (why does the js implementation stores 1 per template node?)
- final Map<String, Set<String>> _templateDelegates =
- new Map<String, Set<String>>();
-
- /** [host] is needed by this mixin, but not defined here. */
- Element get host;
-
- /** Attribute prefix used for declarative event handlers. */
- static const _eventPrefix = 'on-';
-
- /** Whether an attribute declares an event. */
- static bool _isEvent(String attr) => attr.startsWith(_eventPrefix);
-
- /** Extracts events from the element tag attributes. */
- void _parseHostEvents(elementElement) {
- for (var attr in elementElement.attributes.keys.where(_isEvent)) {
- _delegates[toCamelCase(attr)] = elementElement.attributes[attr];
- }
- }
-
- /** Extracts events under the element's <template>. */
- void _parseLocalEvents(elementElement) {
- var name = elementElement.attributes["name"];
- if (name == null) return;
- var events = null;
- for (var template in elementElement.queryAll('template')) {
- var content = template.content;
- if (content != null) {
- for (var child in content.children) {
- events = _accumulateEvents(child, events);
- }
- }
- }
- if (events != null) {
- _templateDelegates[name] = events;
- }
- }
-
- /** Returns all events names listened by [element] and it's children. */
- static Set<String> _accumulateEvents(Element element, [Set<String> events]) {
- events = events == null ? new Set<String>() : events;
-
- // from: accumulateAttributeEvents, accumulateEvent
- events.addAll(element.attributes.keys.where(_isEvent).map(toCamelCase));
-
- // from: accumulateChildEvents
- for (var child in element.children) {
- _accumulateEvents(child, events);
- }
-
- // from: accumulateTemplatedEvents
- if (element.isTemplate) {
- var content = element.content;
- if (content != null) {
- for (var child in content.children) {
- _accumulateEvents(child, events);
- }
- }
- }
- return events;
- }
-
- // ---------------------------------------------------------------------------
- // The following section was ported from:
- // https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
- // ---------------------------------------------------------------------------
-
- /** Attaches event listeners on the [host] element. */
- void _addHostListeners() {
- for (var eventName in _delegates.keys) {
- _addNodeListener(host, eventName,
- (e) => _hostEventListener(eventName, e));
- }
- }
-
- void _addNodeListener(node, String onEvent, Function listener) {
- // If [node] is an element (typically when listening for host events) we
- // use directly the '.onFoo' event stream of the element instance.
- if (node is Element) {
- reflect(node).getField(new Symbol(onEvent)).reflectee.listen(listener);
- return;
- }
-
- // When [node] is not an element, most commonly when [node] is the
- // shadow-root of the polymer-element, we find the appropriate static event
- // stream providers and attach it to [node].
- var eventProvider = _eventStreamProviders[onEvent];
- if (eventProvider != null) {
- eventProvider.forTarget(node).listen(listener);
- return;
- }
-
- // When no provider is available, mainly because of custom-events, we use
- // the underlying event listeners from the DOM.
- var eventName = onEvent.substring(2).toLowerCase(); // onOneTwo => onetwo
- // Most events names in Dart match those in JS in lowercase except for some
- // few events listed in this map. We expect these cases to be handled above,
- // but just in case we include them as a safety net here.
- var jsNameFixes = const {
- 'animationend': 'webkitAnimationEnd',
- 'animationiteration': 'webkitAnimationIteration',
- 'animationstart': 'webkitAnimationStart',
- 'doubleclick': 'dblclick',
- 'fullscreenchange': 'webkitfullscreenchange',
- 'fullscreenerror': 'webkitfullscreenerror',
- 'keyadded': 'webkitkeyadded',
- 'keyerror': 'webkitkeyerror',
- 'keymessage': 'webkitkeymessage',
- 'needkey': 'webkitneedkey',
- 'speechchange': 'webkitSpeechChange',
- };
- var fixedName = jsNameFixes[eventName];
- node.on[fixedName != null ? fixedName : eventName].listen(listener);
- }
-
- void _addInstanceListeners(ShadowRoot root, String elementName) {
- var events = _templateDelegates[elementName];
- if (events == null) return;
- for (var eventName in events) {
- _addNodeListener(root, eventName,
- (e) => _instanceEventListener(eventName, e));
- }
- }
-
- void _hostEventListener(String eventName, Event event) {
- var method = _delegates[eventName];
- if (event.bubbles && method != null) {
- _dispatchMethod(this, method, event, host);
- }
- }
-
- void _dispatchMethod(Object receiver, String methodName, Event event,
- Node target) {
- var detail = event is CustomEvent ? (event as CustomEvent).detail : null;
- var args = [event, detail, target];
-
- var method = new Symbol(methodName);
- // TODO(sigmund): consider making event listeners list all arguments
- // explicitly. Unless VM mirrors are optimized first, this reflectClass call
- // will be expensive once custom elements extend directly from Element (see
- // dartbug.com/11108).
- var methodDecl = reflectClass(receiver.runtimeType).methods[method];
- if (methodDecl != null) {
- // This will either truncate the argument list or extend it with extra
- // null arguments, so it will match the signature.
- // TODO(sigmund): consider accepting optional arguments when we can tell
- // them appart from named arguments (see http://dartbug.com/11334)
- args.length = methodDecl.parameters.where((p) => !p.isOptional).length;
- }
- reflect(receiver).invoke(method, args);
- performMicrotaskCheckpoint();
- }
-
- bool _instanceEventListener(String eventName, Event event) {
- if (event.bubbles) {
- if (event.path == null || !ShadowRoot.supported) {
- return _listenLocalNoEventPath(eventName, event);
- } else {
- return _listenLocal(eventName, event);
- }
- }
- return false;
- }
-
- bool _listenLocal(String eventName, Event event) {
- var controller = null;
- for (var target in event.path) {
- // if we hit host, stop
- if (target == host) return true;
-
- // find a controller for the target, unless we already found `host`
- // as a controller
- controller = (controller == host) ? controller : _findController(target);
-
- // if we have a controller, dispatch the event, and stop if the handler
- // returns true
- if (controller != null
- && handleEvent(controller, eventName, event, target)) {
- return true;
- }
- }
- return false;
- }
-
- // TODO(sorvell): remove when ShadowDOM polyfill supports event path.
- // Note that _findController will not return the expected controller when the
- // event target is a distributed node. This is because we cannot traverse
- // from a composed node to a node in shadowRoot.
- // This will be addressed via an event path api
- // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21066
- bool _listenLocalNoEventPath(String eventName, Event event) {
- var target = event.target;
- var controller = null;
- while (target != null && target != host) {
- controller = (controller == host) ? controller : _findController(target);
- if (controller != null
- && handleEvent(controller, eventName, event, target)) {
- return true;
- }
- target = target.parent;
- }
- return false;
- }
-
- // TODO(sigmund): investigate if this implementation is correct. Polymer looks
- // up the shadow-root that contains [node] and uses a weak-hashmap to find the
- // host associated with that root. This implementation assumes that the
- // [node] is under [host]'s shadow-root.
- Element _findController(Node node) => host.xtag;
-
- bool handleEvent(
- Element controller, String eventName, Event event, Element element) {
- // Note: local events are listened only in the shadow root. This dynamic
- // lookup is used to distinguish determine whether the target actually has a
- // listener, and if so, to determine lazily what's the target method.
- var methodName = element.attributes[toHyphenedName(eventName)];
- if (methodName != null) {
- _dispatchMethod(controller, methodName, event, element);
- }
- return event.bubbles;
- }
-}
-
-
-/** Event stream providers per event name. */
-// TODO(sigmund): after dartbug.com/11108 is fixed, consider eliminating this
-// table and using reflection instead.
-const Map<String, EventStreamProvider> _eventStreamProviders = const {
- 'onMouseWheel': Element.mouseWheelEvent,
- 'onTransitionEnd': Element.transitionEndEvent,
- 'onAbort': Element.abortEvent,
- 'onBeforeCopy': Element.beforeCopyEvent,
- 'onBeforeCut': Element.beforeCutEvent,
- 'onBeforePaste': Element.beforePasteEvent,
- 'onBlur': Element.blurEvent,
- 'onChange': Element.changeEvent,
- 'onClick': Element.clickEvent,
- 'onContextMenu': Element.contextMenuEvent,
- 'onCopy': Element.copyEvent,
- 'onCut': Element.cutEvent,
- 'onDoubleClick': Element.doubleClickEvent,
- 'onDrag': Element.dragEvent,
- 'onDragEnd': Element.dragEndEvent,
- 'onDragEnter': Element.dragEnterEvent,
- 'onDragLeave': Element.dragLeaveEvent,
- 'onDragOver': Element.dragOverEvent,
- 'onDragStart': Element.dragStartEvent,
- 'onDrop': Element.dropEvent,
- 'onError': Element.errorEvent,
- 'onFocus': Element.focusEvent,
- 'onInput': Element.inputEvent,
- 'onInvalid': Element.invalidEvent,
- 'onKeyDown': Element.keyDownEvent,
- 'onKeyPress': Element.keyPressEvent,
- 'onKeyUp': Element.keyUpEvent,
- 'onLoad': Element.loadEvent,
- 'onMouseDown': Element.mouseDownEvent,
- 'onMouseMove': Element.mouseMoveEvent,
- 'onMouseOut': Element.mouseOutEvent,
- 'onMouseOver': Element.mouseOverEvent,
- 'onMouseUp': Element.mouseUpEvent,
- 'onPaste': Element.pasteEvent,
- 'onReset': Element.resetEvent,
- 'onScroll': Element.scrollEvent,
- 'onSearch': Element.searchEvent,
- 'onSelect': Element.selectEvent,
- 'onSelectStart': Element.selectStartEvent,
- 'onSubmit': Element.submitEvent,
- 'onTouchCancel': Element.touchCancelEvent,
- 'onTouchEnd': Element.touchEndEvent,
- 'onTouchEnter': Element.touchEnterEvent,
- 'onTouchLeave': Element.touchLeaveEvent,
- 'onTouchMove': Element.touchMoveEvent,
- 'onTouchStart': Element.touchStartEvent,
- 'onFullscreenChange': Element.fullscreenChangeEvent,
- 'onFullscreenError': Element.fullscreenErrorEvent,
- 'onAutocomplete': FormElement.autocompleteEvent,
- 'onAutocompleteError': FormElement.autocompleteErrorEvent,
- 'onSpeechChange': InputElement.speechChangeEvent,
- 'onCanPlay': MediaElement.canPlayEvent,
- 'onCanPlayThrough': MediaElement.canPlayThroughEvent,
- 'onDurationChange': MediaElement.durationChangeEvent,
- 'onEmptied': MediaElement.emptiedEvent,
- 'onEnded': MediaElement.endedEvent,
- 'onLoadStart': MediaElement.loadStartEvent,
- 'onLoadedData': MediaElement.loadedDataEvent,
- 'onLoadedMetadata': MediaElement.loadedMetadataEvent,
- 'onPause': MediaElement.pauseEvent,
- 'onPlay': MediaElement.playEvent,
- 'onPlaying': MediaElement.playingEvent,
- 'onProgress': MediaElement.progressEvent,
- 'onRateChange': MediaElement.rateChangeEvent,
- 'onSeeked': MediaElement.seekedEvent,
- 'onSeeking': MediaElement.seekingEvent,
- 'onShow': MediaElement.showEvent,
- 'onStalled': MediaElement.stalledEvent,
- 'onSuspend': MediaElement.suspendEvent,
- 'onTimeUpdate': MediaElement.timeUpdateEvent,
- 'onVolumeChange': MediaElement.volumeChangeEvent,
- 'onWaiting': MediaElement.waitingEvent,
- 'onKeyAdded': MediaElement.keyAddedEvent,
- 'onKeyError': MediaElement.keyErrorEvent,
- 'onKeyMessage': MediaElement.keyMessageEvent,
- 'onNeedKey': MediaElement.needKeyEvent,
- 'onWebGlContextLost': CanvasElement.webGlContextLostEvent,
- 'onWebGlContextRestored': CanvasElement.webGlContextRestoredEvent,
- 'onPointerLockChange': Document.pointerLockChangeEvent,
- 'onPointerLockError': Document.pointerLockErrorEvent,
- 'onReadyStateChange': Document.readyStateChangeEvent,
- 'onSelectionChange': Document.selectionChangeEvent,
- 'onSecurityPolicyViolation': Document.securityPolicyViolationEvent,
-};
+export 'polymer.dart' show PolymerElement, registerPolymerElement;
diff --git a/pkg/polymer/lib/src/build/linter.dart b/pkg/polymer/lib/src/build/linter.dart
index 3ed9c50..6542df7 100644
--- a/pkg/polymer/lib/src/build/linter.dart
+++ b/pkg/polymer/lib/src/build/linter.dart
@@ -16,8 +16,10 @@
import 'package:barback/barback.dart';
import 'package:html5lib/dom.dart';
import 'package:html5lib/dom_parsing.dart';
+import 'package:source_maps/span.dart';
import 'common.dart';
+import 'utils.dart';
typedef String MessageFormatter(String kind, String message, Span span);
@@ -191,6 +193,9 @@
/**
* Information needed about other polymer-element tags in order to validate
* how they are used and extended.
+ *
+ * Note: these are only created for polymer-element, because pure custom
+ * elements don't have a declarative form.
*/
class _ElementSummary {
final String tagName;
@@ -284,6 +289,19 @@
node.sourceSpan);
}
+ var attrs = node.attributes['attributes'];
+ if (attrs != null) {
+ var attrsSpan = node.attributeSpans['attributes'];
+
+ // names='a b c' or names='a,b,c'
+ // record each name for publishing
+ for (var attr in attrs.split(attrs.contains(',') ? ',' : ' ')) {
+ // remove excess ws
+ attr = attr.trim();
+ if (!_validateCustomAttributeName(attr, attrsSpan)) break;
+ }
+ }
+
var oldValue = _inPolymerElement;
_inPolymerElement = true;
super.visitElement(node);
@@ -369,10 +387,13 @@
var info = _elements[customTagName];
if (info == null) {
- _logger.warning('definition for custom element with tag name '
+ // TODO(jmesserly): this warning is wrong if someone is using raw custom
+ // elements. Is there another way we can handle this warning that won't
+ // generate false positives?
+ _logger.warning('definition for Polymer element with tag name '
'"$customTagName" not found.', node.sourceSpan);
return;
- }
+ }
var baseTag = info.baseExtendsTag;
if (baseTag != null && !hasIsAttribute) {
@@ -384,7 +405,7 @@
'the custom element declaration.', node.sourceSpan);
return;
}
-
+
if (hasIsAttribute && baseTag == null) {
_logger.warning(
'custom element "$customTagName" doesn\'t declare any type '
@@ -393,7 +414,7 @@
'the custom element declaration.', node.sourceSpan);
return;
}
-
+
if (hasIsAttribute && baseTag != nodeTag) {
_logger.warning(
'custom element "$customTagName" extends from "$baseTag". '
@@ -402,6 +423,20 @@
}
}
+ /**
+ * Validate an attribute on a custom-element. Returns true if valid.
+ */
+ bool _validateCustomAttributeName(String name, FileSpan span) {
+ if (name.contains('-')) {
+ var newName = toCamelCase(name);
+ _logger.warning('PolymerElement no longer recognizes attribute names with '
+ 'dashes such as "$name". Use "$newName" or "${newName.toLowerCase()}" '
+ 'instead (both forms are equivalent in HTML).', span);
+ return false;
+ }
+ return true;
+ }
+
/** Validate event handlers are used correctly. */
void _validateEventHandler(Element node, String name, String value) {
if (!name.startsWith('on-')) {
@@ -409,20 +444,29 @@
' JavaScript event handler. Use the form '
'on-event-name="handlerName" if you want a Dart handler '
'that will automatically update the UI based on model changes.',
- node.sourceSpan);
+ node.attributeSpans[name]);
return;
}
if (!_inPolymerElement) {
_logger.warning('Inline event handlers are only supported inside '
- 'declarations of <polymer-element>.', node.sourceSpan);
+ 'declarations of <polymer-element>.', node.attributeSpans[name]);
+ }
+
+ var eventName = name.substring('on-'.length);
+ if (eventName.contains('-')) {
+ var newEvent = toCamelCase(eventName);
+ _logger.warning('Invalid event name "$name". After the "on-" the event '
+ 'name should not use dashes. For example use "on-$newEvent" or '
+ '"on-${newEvent.toLowerCase()}" (both forms are equivalent in HTML).',
+ node.attributeSpans[name]);
}
if (value.contains('.') || value.contains('(')) {
_logger.warning('Invalid event handler body "$value". Declare a method '
'in your custom element "void handlerName(event, detail, target)" '
'and use the form $name="handlerName".',
- node.sourceSpan);
+ node.attributeSpans[name]);
}
}
}
diff --git a/pkg/polymer/lib/src/build/runner.dart b/pkg/polymer/lib/src/build/runner.dart
index d940c18..3596e92 100644
--- a/pkg/polymer/lib/src/build/runner.dart
+++ b/pkg/polymer/lib/src/build/runner.dart
@@ -105,7 +105,7 @@
final Set<String> _polymerPackageDependencies = [
'analyzer_experimental', 'args', 'barback', 'browser', 'csslib',
'custom_element', 'fancy_syntax', 'html5lib', 'html_import', 'js',
- 'logging', 'mdv', 'meta', 'mutation_observer', 'observe', 'path', 'polymer',
+ 'logging', 'mdv', 'meta', 'mutation_observer', 'observe', 'path'
'polymer_expressions', 'serialization', 'shadow_dom', 'source_maps',
'stack_trace', 'unittest', 'unmodifiable_collection', 'yaml'].toSet();
@@ -149,7 +149,9 @@
}
for (var package in options.packageDirs.keys) {
- // There is nothing to do in the 'polymer' package and its dependencies.
+ // There is nothing to do in the polymer package dependencies.
+ // However: in Polymer package *itself*, we need to replace ObservableMixin
+ // with ChangeNotifierMixin.
if (!options.transformPolymerDependencies &&
_polymerPackageDependencies.contains(package)) continue;
barback.updateTransformers(package, options.phases);
diff --git a/pkg/polymer/lib/src/utils.dart b/pkg/polymer/lib/src/build/utils.dart
similarity index 100%
rename from pkg/polymer/lib/src/utils.dart
rename to pkg/polymer/lib/src/build/utils.dart
diff --git a/pkg/polymer/lib/src/declaration.dart b/pkg/polymer/lib/src/declaration.dart
new file mode 100644
index 0000000..a7584b6
--- /dev/null
+++ b/pkg/polymer/lib/src/declaration.dart
@@ -0,0 +1,713 @@
+// 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 polymer;
+
+/**
+ * **Deprecated**: use [Polymer.register] instead.
+ *
+ * Registers a [PolymerElement]. This is similar to [registerCustomElement]
+ * but it is designed to work with the `<element>` element and adds additional
+ * features.
+ */
+@deprecated
+void registerPolymerElement(String localName, PolymerElement create()) {
+ Polymer._registerClassMirror(localName, reflect(create()).type);
+}
+
+/**
+ * **Warning**: this class is experiental and subject to change.
+ *
+ * The implementation for the `polymer-element` element.
+ *
+ * Normally you do not need to use this class directly, see [PolymerElement].
+ */
+class PolymerDeclaration extends CustomElement {
+ // Fully ported from revision:
+ // https://github.com/Polymer/polymer/blob/4dc481c11505991a7c43228d3797d28f21267779
+ //
+ // src/declaration/attributes.js
+ // src/declaration/events.js
+ // src/declaration/polymer-element.js
+ // src/declaration/properties.js
+ // src/declaration/prototype.js (note: most code not needed in Dart)
+ // src/declaration/styles.js
+ //
+ // Not yet ported:
+ // src/declaration/path.js - blocked on HTMLImports.getDocumentUrl
+
+ // TODO(jmesserly): these should be Type not ClassMirror. But we can't get
+ // from ClassMirror to Type yet in dart2js, so we use ClassMirror for now.
+ // See https://code.google.com/p/dart/issues/detail?id=12607
+ ClassMirror _type;
+ ClassMirror get type => _type;
+
+ // TODO(jmesserly): this is a cache, because it's tricky in Dart to get from
+ // ClassMirror -> Supertype.
+ ClassMirror _supertype;
+ ClassMirror get supertype => _supertype;
+
+ // TODO(jmesserly): this is also a cache, since we can't store .element on
+ // each level of the __proto__ like JS does.
+ PolymerDeclaration _super;
+ PolymerDeclaration get superDeclaration => _super;
+
+ String _name;
+ String get name => _name;
+
+ /**
+ * Map of publish properties. Can be a [VariableMirror] or a [MethodMirror]
+ * representing a getter. If it is a getter, there will also be a setter.
+ */
+ Map<String, DeclarationMirror> _publish;
+
+ /** The names of published properties for this polymer-element. */
+ Iterable<String> get publishedProperties =>
+ _publish != null ? _publish.keys : const [];
+
+ /** Same as [_publish] but with lower case names. */
+ Map<String, DeclarationMirror> _publishLC;
+
+ Map<String, Symbol> _observe;
+
+ Map<Symbol, Object> _instanceAttributes;
+
+ List<Element> _sheets;
+ List<Element> get sheets => _sheets;
+
+ List<Element> _styles;
+ List<Element> get styles => _styles;
+
+ DocumentFragment get templateContent {
+ final template = query('template');
+ return template != null ? template.content : null;
+ }
+
+ /** Maps event names and their associated method in the element class. */
+ final Map<String, String> _eventDelegates = {};
+
+ /** Expected events per element node. */
+ // TODO(sigmund): investigate whether we need more than 1 set of local events
+ // per element (why does the js implementation stores 1 per template node?)
+ Expando<Set<String>> _templateDelegates;
+
+ void created() {
+ super.created();
+
+ // fetch the element name
+ _name = attributes['name'];
+ // install element definition, if ready
+ registerWhenReady();
+ }
+
+ void registerWhenReady() {
+ // if we have no prototype, wait
+ if (waitingForType(name)) {
+ return;
+ }
+ // fetch our extendee name
+ var extendee = attributes['extends'];
+ if (waitingForExtendee(extendee)) {
+ //console.warn(name + ': waitingForExtendee:' + extendee);
+ return;
+ }
+ // TODO(sjmiles): HTMLImports polyfill awareness:
+ // elements in the main document are likely to parse
+ // in advance of elements in imports because the
+ // polyfill parser is simulated
+ // therefore, wait for imports loaded before
+ // finalizing elements in the main document
+ // TODO(jmesserly): Polymer.dart waits for HTMLImportsLoaded, so I've
+ // removed "whenImportsLoaded" for now. Restore the workaround if needed.
+ _register(extendee);
+ }
+
+ void _register(extendee) {
+ //console.group('registering', name);
+ register(name, extendee);
+ //console.groupEnd();
+ // subclasses may now register themselves
+ _notifySuper(name);
+ }
+
+ bool waitingForType(String name) {
+ if (_getRegisteredType(name) != null) return false;
+
+ // then wait for a prototype
+ _waitType[name] = this;
+ // if explicitly marked as 'noscript'
+ if (attributes.containsKey('noscript')) {
+ // TODO(sorvell): CustomElements polyfill awareness:
+ // noscript elements should upgrade in logical order
+ // script injection ensures this under native custom elements;
+ // under imports + ce polyfills, scripts run before upgrades.
+ // dependencies should be ready at upgrade time so register
+ // prototype at this time.
+ // TODO(jmesserly): I'm not sure how to port this; since script
+ // injection doesn't work for Dart, we'll just call Polymer.register
+ // here and hope for the best.
+ Polymer.register(name);
+ }
+ return true;
+ }
+
+ bool waitingForExtendee(String extendee) {
+ // if extending a custom element...
+ if (extendee != null && extendee.indexOf('-') >= 0) {
+ // wait for the extendee to be _registered first
+ if (!_isRegistered(extendee)) {
+ _waitSuper.putIfAbsent(extendee, () => []).add(this);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void register(String name, String extendee) {
+ // build prototype combining extendee, Polymer base, and named api
+ buildType(name, extendee);
+
+ // back reference declaration element
+ // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
+ _declarations[_type] = this;
+
+ // more declarative features
+ desugar();
+
+ // TODO(sorvell): install a helper method this.resolvePath to aid in
+ // setting resource paths. e.g.
+ // this.$.image.src = this.resolvePath('images/foo.png')
+ // Potentially remove when spec bug is addressed.
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407
+ // TODO(jmesserly): resolvePath not ported, see first comment in this class.
+
+ // under ShadowDOMPolyfill, transforms to approximate missing CSS features
+ _shimShadowDomStyling(templateContent, name);
+
+ // register our custom element
+ registerType(name);
+
+ // NOTE: skip in Dart because we don't have mutable global scope.
+ // reference constructor in a global named by 'constructor' attribute
+ // publishConstructor();
+ }
+
+ /**
+ * Gets the Dart type registered for this name, and sets up declarative
+ * features. Fills in the [type] and [supertype] fields.
+ *
+ * *Note*: unlike the JavaScript version, we do not have to metaprogram the
+ * prototype, which simplifies this method.
+ */
+ void buildType(String name, String extendee) {
+ // get our custom type
+ _type = _getRegisteredType(name);
+
+ // get basal prototype
+ _supertype = _getRegisteredType(extendee);
+ if (supertype != null) _super = _getDeclaration(supertype);
+
+ // transcribe `attributes` declarations onto own prototype's `publish`
+ publishAttributes(type, _super);
+
+ publishProperties(type);
+
+ inferObservers(type);
+
+ // Skip the rest in Dart:
+ // chain various meta-data objects to inherited versions
+ // chain custom api to inherited
+ // build side-chained lists to optimize iterations
+ // inherit publishing meta-data
+ //this.inheritAttributesObjects(prototype);
+ //this.inheritDelegates(prototype);
+ // x-platform fixups
+ }
+
+ /** Implement various declarative features. */
+ void desugar() {
+ // compile list of attributes to copy to instances
+ accumulateInstanceAttributes();
+ // parse on-* delegates declared on `this` element
+ parseHostEvents();
+ // parse on-* delegates declared in templates
+ parseLocalEvents();
+ // install external stylesheets as if they are inline
+ installSheets();
+ // TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient
+ // lazy static initialization, can we get by without it?
+ var registered = type.methods[const Symbol('registerCallback')];
+ if (registered != null && registered.isStatic &&
+ registered.isRegularMethod) {
+ type.invoke(const Symbol('registerCallback'), [this]);
+ }
+
+ }
+
+ void registerType(String name) {
+ // TODO(jmesserly): document.register
+ registerCustomElement(name, () =>
+ type.newInstance(const Symbol(''), const []).reflectee);
+ }
+
+ void publishAttributes(ClassMirror type, PolymerDeclaration superDecl) {
+ // get properties to publish
+ if (superDecl != null && superDecl._publish != null) {
+ _publish = new Map.from(superDecl._publish);
+ }
+ _publish = _getProperties(type, _publish, (x) => x is PublishedProperty);
+
+ // merge names from 'attributes' attribute
+ var attrs = attributes['attributes'];
+ if (attrs != null) {
+ // names='a b c' or names='a,b,c'
+ // record each name for publishing
+ for (var attr in attrs.split(attrs.contains(',') ? ',' : ' ')) {
+ // remove excess ws
+ attr = attr.trim();
+
+ // do not override explicit entries
+ if (_publish != null && _publish.containsKey(attr)) continue;
+
+ var property = new Symbol(attr);
+ var mirror = type.variables[property];
+ if (mirror == null) {
+ mirror = type.getters[property];
+ if (mirror != null && !_hasSetter(type, mirror)) mirror = null;
+ }
+ if (mirror == null) {
+ window.console.warn('property for attribute $attr of polymer-element '
+ 'name=$name not found.');
+ continue;
+ }
+ if (_publish == null) _publish = {};
+ _publish[attr] = mirror;
+ }
+ }
+
+ // NOTE: the following is not possible in Dart; fields must be declared.
+ // install 'attributes' as properties on the prototype,
+ // but don't override
+ }
+
+ void accumulateInstanceAttributes() {
+ // inherit instance attributes
+ _instanceAttributes = new Map<Symbol, Object>();
+ if (_super != null) _instanceAttributes.addAll(_super._instanceAttributes);
+
+ // merge attributes from element
+ attributes.forEach((name, value) {
+ if (isInstanceAttribute(name)) {
+ _instanceAttributes[new Symbol(name)] = value;
+ }
+ });
+ }
+
+ static bool isInstanceAttribute(name) {
+ // do not clone these attributes onto instances
+ final blackList = const {
+ 'name': 1, 'extends': 1, 'constructor': 1, 'noscript': 1,
+ 'attributes': 1};
+
+ return !blackList.containsKey(name) && !name.startsWith('on-');
+ }
+
+ /** Extracts events from the element tag attributes. */
+ void parseHostEvents() {
+ addAttributeDelegates(_eventDelegates);
+ }
+
+ void addAttributeDelegates(Map<String, String> delegates) {
+ attributes.forEach((name, value) {
+ if (_hasEventPrefix(name)) {
+ delegates[_removeEventPrefix(name)] = value;
+ }
+ });
+ }
+
+ /** Extracts events under the element's <template>. */
+ void parseLocalEvents() {
+ for (var t in queryAll('template')) {
+ final events = new Set<String>();
+ // acquire delegates from entire subtree at t
+ accumulateTemplatedEvents(t, events);
+ if (events.isNotEmpty) {
+ // store delegate information directly on template
+ if (_templateDelegates == null) {
+ _templateDelegates = new Expando<Set<String>>();
+ }
+ _templateDelegates[t] = events;
+ }
+ }
+ }
+
+ void accumulateTemplatedEvents(Element node, Set<String> events) {
+ if (node.localName == 'template' && node.content != null) {
+ accumulateChildEvents(node.content, events);
+ }
+ }
+
+ void accumulateChildEvents(node, Set<String> events) {
+ assert(node is Element || node is DocumentFragment);
+ for (var n in node.children) {
+ accumulateEvents(n, events);
+ }
+ }
+
+ void accumulateEvents(Element node, Set<String> events) {
+ accumulateAttributeEvents(node, events);
+ accumulateChildEvents(node, events);
+ accumulateTemplatedEvents(node, events);
+ }
+
+ void accumulateAttributeEvents(Element node, Set<String> events) {
+ for (var name in node.attributes.keys) {
+ if (_hasEventPrefix(name)) {
+ accumulateEvent(_removeEventPrefix(name), events);
+ }
+ }
+ }
+
+ void accumulateEvent(String name, Set<String> events) {
+ var translated = _eventTranslations[name];
+ events.add(translated != null ? translated : name);
+ }
+
+ String urlToPath(String url) {
+ if (url == null) return '';
+ return (url.split('/')..removeLast()..add('')).join('/');
+ }
+
+ /**
+ * Install external stylesheets loaded in <element> elements into the
+ * element's template.
+ */
+ void installSheets() {
+ cacheSheets();
+ cacheStyles();
+ installLocalSheets();
+ installGlobalStyles();
+ }
+
+ void cacheSheets() {
+ _sheets = findNodes(_SHEET_SELECTOR);
+ for (var s in sheets) s.remove();
+ }
+
+ void cacheStyles() {
+ _styles = findNodes('$_STYLE_SELECTOR[$_SCOPE_ATTR]');
+ for (var s in styles) s.remove();
+ }
+
+ /**
+ * Takes external stylesheets loaded in an `<element>` element and moves
+ * their content into a style element inside the `<element>`'s template.
+ * The sheet is then removed from the `<element>`. This is done only so
+ * that if the element is loaded in the main document, the sheet does
+ * not become active.
+ * Note, ignores sheets with the attribute 'polymer-scope'.
+ */
+ void installLocalSheets() {
+ var sheets = this.sheets.where(
+ (s) => !s.attributes.containsKey(_SCOPE_ATTR));
+ var content = this.templateContent;
+ if (content != null) {
+ var cssText = new StringBuffer();
+ for (var sheet in sheets) {
+ cssText..write(_cssTextFromSheet(sheet))..write('\n');
+ }
+ if (cssText.length > 0) {
+ content.insertBefore(
+ new StyleElement()..text = '$cssText',
+ content.firstChild);
+ }
+ }
+ }
+
+ List<Element> findNodes(String selector, [bool matcher(Element e)]) {
+ var nodes = this.queryAll(selector).toList();
+ var content = this.templateContent;
+ if (content != null) {
+ nodes = nodes..addAll(content.queryAll(selector));
+ }
+ if (matcher != null) return nodes.where(matcher).toList();
+ return nodes;
+ }
+
+ /**
+ * Promotes external stylesheets and style elements with the attribute
+ * polymer-scope='global' into global scope.
+ * This is particularly useful for defining @keyframe rules which
+ * currently do not function in scoped or shadow style elements.
+ * (See wkb.ug/72462)
+ */
+ // TODO(sorvell): remove when wkb.ug/72462 is addressed.
+ void installGlobalStyles() {
+ var style = styleForScope(_STYLE_GLOBAL_SCOPE);
+ _applyStyleToScope(style, document.head);
+ }
+
+ String cssTextForScope(String scopeDescriptor) {
+ var cssText = new StringBuffer();
+ // handle stylesheets
+ var selector = '[$_SCOPE_ATTR=$scopeDescriptor]';
+ matcher(s) => s.matches(selector);
+
+ for (var sheet in sheets.where(matcher)) {
+ cssText..write(_cssTextFromSheet(sheet))..write('\n\n');
+ }
+ // handle cached style elements
+ for (var style in styles.where(matcher)) {
+ cssText..write(style.textContent)..write('\n\n');
+ }
+ return cssText.toString();
+ }
+
+ StyleElement styleForScope(String scopeDescriptor) {
+ var cssText = cssTextForScope(scopeDescriptor);
+ return cssTextToScopeStyle(cssText, scopeDescriptor);
+ }
+
+ StyleElement cssTextToScopeStyle(String cssText, String scopeDescriptor) {
+ if (cssText == '') return null;
+
+ return new StyleElement()
+ ..text = cssText
+ ..attributes[_STYLE_SCOPE_ATTRIBUTE] = '$name-$scopeDescriptor';
+ }
+
+ /**
+ * fetch a list of all observable properties names in our inheritance chain
+ * above Polymer.
+ */
+ // TODO(sjmiles): perf: reflection is slow, relatively speaking
+ // If an element may take 6us to create, getCustomPropertyNames might
+ // cost 1.6us more.
+ void inferObservers(ClassMirror type) {
+ for (var method in type.methods.values) {
+ if (method.isStatic || !method.isRegularMethod) continue;
+
+ String name = MirrorSystem.getName(method.simpleName);
+ if (name.endsWith('Changed')) {
+ if (_observe == null) _observe = {};
+ name = name.substring(0, name.length - 7);
+ _observe[name] = method.simpleName;
+ }
+ }
+ }
+
+ void publishProperties(ClassMirror type) {
+ // Dart note: _publish was already populated by publishAttributes
+ if (_publish != null) _publishLC = _lowerCaseMap(_publish);
+ }
+
+ Map<String, dynamic> _lowerCaseMap(Map<String, dynamic> properties) {
+ final map = new Map<String, dynamic>();
+ properties.forEach((name, value) {
+ map[name.toLowerCase()] = value;
+ });
+ return map;
+ }
+}
+
+/// maps tag names to prototypes
+final Map _typesByName = new Map<String, ClassMirror>();
+
+ClassMirror _getRegisteredType(String name) => _typesByName[name];
+
+/// elements waiting for prototype, by name
+final Map _waitType = new Map<String, PolymerDeclaration>();
+
+void _notifyType(String name) {
+ var waiting = _waitType.remove(name);
+ if (waiting != null) waiting.registerWhenReady();
+}
+
+/// elements waiting for super, by name
+final Map _waitSuper = new Map<String, List<PolymerDeclaration>>();
+
+void _notifySuper(String name) {
+ _registered.add(name);
+ var waiting = _waitSuper.remove(name);
+ if (waiting != null) {
+ for (var w in waiting) {
+ w.registerWhenReady();
+ }
+ }
+}
+
+/// track document.register'ed tag names
+final Set _registered = new Set<String>();
+
+bool _isRegistered(name) => _registered.contains(name);
+
+final Map _declarations = new Map<ClassMirror, PolymerDeclaration>();
+
+PolymerDeclaration _getDeclaration(ClassMirror type) => _declarations[type];
+
+final _objectType = reflectClass(Object);
+
+Map _getProperties(ClassMirror type, Map props, bool matches(metadata)) {
+ for (var field in type.variables.values) {
+ if (field.isFinal || field.isStatic || field.isPrivate) continue;
+
+ for (var meta in field.metadata) {
+ if (matches(meta.reflectee)) {
+ if (props == null) props = {};
+ props[MirrorSystem.getName(field.simpleName)] = field;
+ break;
+ }
+ }
+ }
+
+ for (var getter in type.getters.values) {
+ if (getter.isStatic || getter.isPrivate) continue;
+
+ for (var meta in getter.metadata) {
+ if (matches(meta.reflectee)) {
+ if (_hasSetter(type, getter)) {
+ if (props == null) props = {};
+ props[MirrorSystem.getName(getter.simpleName)] = getter;
+ }
+ break;
+ }
+ }
+ }
+
+ return props;
+}
+
+bool _hasSetter(ClassMirror type, MethodMirror getter) {
+ var setterName = new Symbol('${MirrorSystem.getName(getter.simpleName)}=');
+ return type.setters.containsKey(setterName);
+}
+
+bool _inDartHtml(ClassMirror type) =>
+ type.owner.simpleName == const Symbol('dart.dom.html');
+
+
+/** Attribute prefix used for declarative event handlers. */
+const _EVENT_PREFIX = 'on-';
+
+/** Whether an attribute declares an event. */
+bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX);
+
+String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length);
+
+/**
+ * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
+ */
+void _shimShadowDomStyling(DocumentFragment template, String localName) {
+ if (js.context == null || template == null) return;
+
+ var platform = js.context['Platform'];
+ if (platform == null) return;
+
+ var style = template.query('style');
+ if (style == null) return;
+
+ var shadowCss = platform['ShadowCSS'];
+ if (shadowCss == null) return;
+
+ // TODO(terry): Remove calls to shimShadowDOMStyling2 and replace with
+ // shimShadowDOMStyling when we support unwrapping dart:html
+ // Element to a JS DOM node.
+ var shimShadowDOMStyling2 = shadowCss['shimShadowDOMStyling2'];
+ if (shimShadowDOMStyling2 == null) return;
+
+ var scopedCSS = shimShadowDOMStyling2.apply(shadowCss,
+ [style.text, localName]);
+
+ // TODO(terry): Remove when shimShadowDOMStyling is called we don't need to
+ // replace original CSS with scoped CSS shimShadowDOMStyling
+ // does that.
+ style.text = scopedCSS;
+}
+
+const _STYLE_SELECTOR = 'style';
+const _SHEET_SELECTOR = '[rel=stylesheet]';
+const _STYLE_GLOBAL_SCOPE = 'global';
+const _SCOPE_ATTR = 'polymer-scope';
+const _STYLE_SCOPE_ATTRIBUTE = 'element';
+
+void _applyStyleToScope(StyleElement style, Node scope) {
+ if (style == null) return;
+
+ // TODO(sorvell): necessary for IE
+ // see https://connect.microsoft.com/IE/feedback/details/790212/
+ // cloning-a-style-element-and-adding-to-document-produces
+ // -unexpected-result#details
+ // var clone = style.cloneNode(true);
+ var clone = new StyleElement()..text = style.text;
+
+ var attr = style.attributes[_STYLE_SCOPE_ATTRIBUTE];
+ if (attr != null) {
+ clone.attributes[_STYLE_SCOPE_ATTRIBUTE] = attr;
+ }
+
+ scope.append(clone);
+}
+
+String _cssTextFromSheet(Element sheet) {
+ if (sheet == null || js.context == null) return '';
+
+ // TODO(jmesserly): this is a hacky way to communcate with HTMLImports...
+
+ // Remove rel=stylesheet, href to keep this inert.
+ var href = sheet.attributes.remove('href');
+ var rel = sheet.attributes.remove('rel');
+ document.body.append(sheet);
+ String resource;
+ try {
+ resource = js.context['document']['body']['lastChild']['__resource'];
+ } finally {
+ sheet.remove();
+ if (href != null) sheet.attributes['href'] = href;
+ if (rel != null) sheet.attributes['rel'] = rel;
+ }
+ return resource != null ? resource : '';
+}
+
+const _OBSERVE_SUFFIX = 'Changed';
+
+// TODO(jmesserly): is this list complete?
+final _eventTranslations = const {
+ // TODO(jmesserly): these three Polymer.js translations won't work in Dart,
+ // because we strip the webkit prefix (below). Reconcile.
+ 'webkitanimationstart': 'webkitAnimationStart',
+ 'webkitanimationend': 'webkitAnimationEnd',
+ 'webkittransitionend': 'webkitTransitionEnd',
+
+ 'domfocusout': 'DOMFocusOut',
+ 'domfocusin': 'DOMFocusIn',
+
+ // TODO(jmesserly): Dart specific renames. Reconcile with Polymer.js
+ 'animationend': 'webkitAnimationEnd',
+ 'animationiteration': 'webkitAnimationIteration',
+ 'animationstart': 'webkitAnimationStart',
+ 'doubleclick': 'dblclick',
+ 'fullscreenchange': 'webkitfullscreenchange',
+ 'fullscreenerror': 'webkitfullscreenerror',
+ 'keyadded': 'webkitkeyadded',
+ 'keyerror': 'webkitkeyerror',
+ 'keymessage': 'webkitkeymessage',
+ 'needkey': 'webkitneedkey',
+ 'speechchange': 'webkitSpeechChange',
+};
+
+final _reverseEventTranslations = () {
+ final map = new Map<String, String>();
+ _eventTranslations.forEach((onName, eventType) {
+ map[eventType] = onName;
+ });
+ return map;
+}();
+
+// Dart note: we need this function because we have additional renames JS does
+// not have. The JS renames are simply case differences, whereas we have ones
+// like doubleclick -> dblclick and stripping the webkit prefix.
+String _eventNameFromType(String eventType) {
+ final result = _reverseEventTranslations[eventType];
+ return result != null ? result : eventType;
+}
diff --git a/pkg/polymer/lib/src/instance.dart b/pkg/polymer/lib/src/instance.dart
new file mode 100644
index 0000000..f0bff99
--- /dev/null
+++ b/pkg/polymer/lib/src/instance.dart
@@ -0,0 +1,930 @@
+// 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 polymer;
+
+/**
+ * Use this annotation to publish a field as an attribute. For example:
+ *
+ * class MyPlaybackElement extends PolymerElement {
+ * // This will be available as an HTML attribute, for example:
+ * // <my-playback volume="11">
+ * @published double volume;
+ * }
+ */
+// TODO(jmesserly): does @published imply @observable or vice versa?
+const published = const PublishedProperty();
+
+/** An annotation used to publish a field as an attribute. See [published]. */
+class PublishedProperty extends ObservableProperty {
+ const PublishedProperty();
+}
+
+// TODO(jmesserly): make this the mixin so we can have Polymer type extensions,
+// and move the implementation of PolymerElement in here. Once done it will look
+// like:
+// abstract class Polymer { ... all the things ... }
+// typedef PolymerElement = HtmlElement with Polymer, Observable;
+abstract class Polymer {
+ // TODO(jmesserly): should this really be public?
+ /** Regular expression that matches data-bindings. */
+ static final bindPattern = new RegExp(r'\{\{([^{}]*)}}');
+
+ /**
+ * Like [document.register] but for Polymer elements.
+ *
+ * Use the [name] to specify custom elment's tag name, for example:
+ * "fancy-button" if the tag is used as `<fancy-button>`.
+ *
+ * The [type] is the type to construct. If not supplied, it defaults to
+ * [PolymerElement].
+ */
+ // NOTE: this is called "element" in src/declaration/polymer-element.js, and
+ // exported as "Polymer".
+ static void register(String name, [Type type]) {
+ //console.log('registering [' + name + ']');
+ if (type == null) type = PolymerElement;
+ _registerClassMirror(name, reflectClass(type));
+ }
+
+ // TODO(jmesserly): we use ClassMirror internall for now, until it is possible
+ // to get from ClassMirror -> Type.
+ static void _registerClassMirror(String name, ClassMirror type) {
+ _typesByName[name] = type;
+ // notify the registrar waiting for 'name', if any
+ _notifyType(name);
+ }
+}
+
+/**
+ * The base class for Polymer elements. It provides convience features on top
+ * of the custom elements web standard.
+ */
+class PolymerElement extends CustomElement with ObservableMixin {
+ // Fully ported from revision:
+ // https://github.com/Polymer/polymer/blob/4dc481c11505991a7c43228d3797d28f21267779
+ //
+ // src/instance/attributes.js
+ // src/instance/base.js
+ // src/instance/events.js
+ // src/instance/mdv.js
+ // src/instance/properties.js
+ // src/instance/utils.js
+ //
+ // Not yet ported:
+ // src/instance/style.js -- blocked on ShadowCSS.shimPolyfillDirectives
+
+ /// The one syntax to rule them all.
+ static final BindingDelegate _polymerSyntax = new PolymerExpressions();
+
+ static int _preparingElements = 0;
+
+ PolymerDeclaration _declaration;
+
+ /** The most derived `<polymer-element>` declaration for this element. */
+ PolymerDeclaration get declaration => _declaration;
+
+ Map<String, StreamSubscription> _elementObservers;
+ bool _unbound; // lazy-initialized
+ Job _unbindAllJob;
+
+ bool get _elementPrepared => _declaration != null;
+
+ bool get applyAuthorStyles => false;
+ bool get resetStyleInheritance => false;
+ bool get alwaysPrepare => false;
+
+ /**
+ * Shadow roots created by [parseElement]. See [getShadowRoot].
+ */
+ final _shadowRoots = new HashMap<String, ShadowRoot>();
+
+ /** Map of items in the shadow root(s) by their [Element.id]. */
+ // TODO(jmesserly): various issues:
+ // * wrap in UnmodifiableMapView?
+ // * should we have an object that implements noSuchMethod?
+ // * should the map have a key order (e.g. LinkedHash or SplayTree)?
+ // * should this be a live list? Polymer doesn't, maybe due to JS limitations?
+ // For now I picked the most performant choice: non-live HashMap.
+ final Map<String, Element> $ = new HashMap<String, Element>();
+
+ /**
+ * Gets the shadow root associated with the corresponding custom element.
+ *
+ * This is identical to [shadowRoot], unless there are multiple levels of
+ * inheritance and they each have their own shadow root. For example,
+ * this can happen if the base class and subclass both have `<template>` tags
+ * in their `<polymer-element>` tags.
+ */
+ // TODO(jmesserly): Polymer does not have this feature. Reconcile.
+ ShadowRoot getShadowRoot(String customTagName) => _shadowRoots[customTagName];
+
+ ShadowRoot createShadowRoot([name]) {
+ if (name != null) {
+ throw new ArgumentError('name argument must not be supplied.');
+ }
+
+ // Provides ability to traverse from ShadowRoot to the host.
+ // TODO(jmessery): remove once we have this ability on the DOM.
+ final root = super.createShadowRoot();
+ _shadowHost[root] = host;
+ return root;
+ }
+
+ /**
+ * Invoke [callback] in [wait], unless the job is re-registered,
+ * which resets the timer. For example:
+ *
+ * _myJob = job(_myJob, callback, const Duration(milliseconds: 100));
+ *
+ * Returns a job handle which can be used to re-register a job.
+ */
+ Job job(Job job, void callback(), Duration wait) =>
+ runJob(job, callback, wait);
+
+ // TODO(jmesserly): I am not sure if we should have the
+ // created/createdCallback distinction. See post here:
+ // https://groups.google.com/d/msg/polymer-dev/W0ZUpU5caIM/v5itFnvnehEJ
+ // Same issue with inserted and removed.
+ void created() {
+ if (document.window != null || alwaysPrepare || _preparingElements > 0) {
+ prepareElement();
+ }
+ }
+
+ void prepareElement() {
+ // Dart note: get the _declaration, which also marks _elementPrepared
+ _declaration = _getDeclaration(reflect(this).type);
+ // do this first so we can observe changes during initialization
+ observeProperties();
+ // install boilerplate attributes
+ copyInstanceAttributes();
+ // process input attributes
+ takeAttributes();
+ // add event listeners
+ addHostListeners();
+ // guarantees that while preparing, any sub-elements will also be prepared
+ _preparingElements++;
+ // process declarative resources
+ parseDeclarations(_declaration);
+ _preparingElements--;
+ // user entry point
+ ready();
+ }
+
+ /** Called when [prepareElement] is finished. */
+ void ready() {}
+
+ void inserted() {
+ if (!_elementPrepared) {
+ prepareElement();
+ }
+ cancelUnbindAll(preventCascade: true);
+ }
+
+ void removed() {
+ asyncUnbindAll();
+ }
+
+ /** Recursive ancestral <element> initialization, oldest first. */
+ void parseDeclarations(PolymerDeclaration declaration) {
+ if (declaration != null) {
+ parseDeclarations(declaration.superDeclaration);
+ parseDeclaration(declaration.host);
+ }
+ }
+
+ /**
+ * Parse input `<polymer-element>` as needed, override for custom behavior.
+ */
+ void parseDeclaration(Element elementElement) {
+ var root = shadowFromTemplate(fetchTemplate(elementElement));
+
+ // Dart note: this is extra code compared to Polymer to support
+ // the getShadowRoot method.
+ if (root == null) return;
+
+ var name = elementElement.attributes['name'];
+ if (name == null) return;
+ _shadowRoots[name] = root;
+ }
+
+ /**
+ * Return a shadow-root template (if desired), override for custom behavior.
+ */
+ Element fetchTemplate(Element elementElement) =>
+ elementElement.query('template');
+
+ /** Utility function that creates a shadow root from a `<template>`. */
+ ShadowRoot shadowFromTemplate(Element template) {
+ if (template == null) return null;
+ // cache elder shadow root (if any)
+ var elderRoot = this.shadowRoot;
+ // make a shadow root
+ var root = createShadowRoot();
+ // migrate flag(s)(
+ root.applyAuthorStyles = applyAuthorStyles;
+ root.resetStyleInheritance = resetStyleInheritance;
+ // stamp template
+ // which includes parsing and applying MDV bindings before being
+ // inserted (to avoid {{}} in attribute values)
+ // e.g. to prevent <img src="images/{{icon}}"> from generating a 404.
+ var dom = instanceTemplate(template);
+ // append to shadow dom
+ root.append(dom);
+ // perform post-construction initialization tasks on shadow root
+ shadowRootReady(root, template);
+ // return the created shadow root
+ return root;
+ }
+
+ void shadowRootReady(ShadowRoot root, Element template) {
+ // locate nodes with id and store references to them in this.$ hash
+ marshalNodeReferences(root);
+ // add local events of interest...
+ addInstanceListeners(root, template);
+ // TODO(jmesserly): port this
+ // set up pointer gestures
+ // PointerGestures.register(root);
+ }
+
+ /** Locate nodes with id and store references to them in [$] hash. */
+ void marshalNodeReferences(ShadowRoot root) {
+ if (root == null) return;
+ for (var n in root.queryAll('[id]')) {
+ $[n.id] = n;
+ }
+ }
+
+ void attributeChanged(String name, String oldValue) {
+ if (name != 'class' && name != 'style') {
+ attributeToProperty(name, attributes[name]);
+ }
+ }
+
+ // TODO(jmesserly): use stream or future here?
+ void onMutation(Node node, void listener(MutationObserver obs)) {
+ new MutationObserver((records, MutationObserver observer) {
+ listener(observer);
+ observer.disconnect();
+ })..observe(node, childList: true, subtree: true);
+ }
+
+ void copyInstanceAttributes() {
+ _declaration._instanceAttributes.forEach((name, value) {
+ attributes[name] = value;
+ });
+ }
+
+ void takeAttributes() {
+ if (_declaration._publishLC == null) return;
+ attributes.forEach(attributeToProperty);
+ }
+
+ /**
+ * If attribute [name] is mapped to a property, deserialize
+ * [value] into that property.
+ */
+ void attributeToProperty(String name, String value) {
+ // try to match this attribute to a property (attributes are
+ // all lower-case, so this is case-insensitive search)
+ var property = propertyForAttribute(name);
+ if (property == null) return;
+
+ // filter out 'mustached' values, these are to be
+ // replaced with bound-data and are not yet values
+ // themselves.
+ if (value == null || value.contains(Polymer.bindPattern)) return;
+
+ // get original value
+ final self = reflect(this);
+ final defaultValue = self.getField(property.simpleName).reflectee;
+
+ // deserialize Boolean or Number values from attribute
+ final newValue = deserializeValue(value, defaultValue,
+ _inferPropertyType(defaultValue, property));
+
+ // only act if the value has changed
+ if (!identical(newValue, defaultValue)) {
+ // install new value (has side-effects)
+ self.setField(property.simpleName, newValue);
+ }
+ }
+
+ /** Return the published property matching name, or null. */
+ // TODO(jmesserly): should we just return Symbol here?
+ DeclarationMirror propertyForAttribute(String name) {
+ final publishLC = _declaration._publishLC;
+ if (publishLC == null) return null;
+ //console.log('propertyForAttribute:', name, 'matches', match);
+ return publishLC[name];
+ }
+
+ /**
+ * Convert representation of [value] based on [type] and [defaultValue].
+ */
+ // TODO(jmesserly): this should probably take a ClassMirror instead of
+ // TypeMirror, but it is currently impossible to get from a TypeMirror to a
+ // ClassMirror.
+ Object deserializeValue(String value, Object defaultValue, TypeMirror type) =>
+ deserialize.deserializeValue(value, defaultValue, type);
+
+ String serializeValue(Object value, TypeMirror inferredType) {
+ if (value == null) return null;
+
+ final type = inferredType.qualifiedName;
+ if (type == const Symbol('dart.core.bool')) {
+ return _toBoolean(value) ? '' : null;
+ } else if (type == const Symbol('dart.core.String')
+ || type == const Symbol('dart.core.int')
+ || type == const Symbol('dart.core.double')) {
+ return '$value';
+ }
+ return null;
+ }
+
+ void reflectPropertyToAttribute(String name) {
+ // TODO(sjmiles): consider memoizing this
+ final self = reflect(this);
+ // try to intelligently serialize property value
+ // TODO(jmesserly): cache symbol?
+ final propValue = self.getField(new Symbol(name)).reflectee;
+ final property = _declaration._publish[name];
+ var inferredType = _inferPropertyType(propValue, property);
+ final serializedValue = serializeValue(propValue, inferredType);
+ // boolean properties must reflect as boolean attributes
+ if (serializedValue != null) {
+ attributes[name] = serializedValue;
+ // TODO(sorvell): we should remove attr for all properties
+ // that have undefined serialization; however, we will need to
+ // refine the attr reflection system to achieve this; pica, for example,
+ // relies on having inferredType object properties not removed as
+ // attrs.
+ } else if (inferredType.qualifiedName == const Symbol('dart.core.bool')) {
+ attributes.remove(name);
+ }
+ }
+
+ /**
+ * Creates the document fragment to use for each instance of the custom
+ * element, given the `<template>` node. By default this is equivalent to:
+ *
+ * template.createInstance(this, polymerSyntax);
+ *
+ * Where polymerSyntax is a singleton `PolymerExpressions` instance from the
+ * [polymer_expressions](https://pub.dartlang.org/packages/polymer_expressions)
+ * package.
+ *
+ * You can override this method to change the instantiation behavior of the
+ * template, for example to use a different data-binding syntax.
+ */
+ DocumentFragment instanceTemplate(Element template) =>
+ template.createInstance(this, _polymerSyntax);
+
+ NodeBinding bind(String name, model, String path) {
+ // note: binding is a prepare signal. This allows us to be sure that any
+ // property changes that occur as a result of binding will be observed.
+ if (!_elementPrepared) prepareElement();
+
+ var property = propertyForAttribute(name);
+ if (property != null) {
+ unbind(name);
+ // use n-way Polymer binding
+ var observer = bindProperty(property.simpleName, model, path);
+ // reflect bound property to attribute when binding
+ // to ensure binding is not left on attribute if property
+ // does not update due to not changing.
+ reflectPropertyToAttribute(name);
+ return bindings[name] = observer;
+ } else {
+ return super.bind(name, model, path);
+ }
+ }
+
+ void asyncUnbindAll() {
+ if (_unbound == true) return;
+ _unbindLog.info('[$localName] asyncUnbindAll');
+ _unbindAllJob = job(_unbindAllJob, unbindAll, const Duration(seconds: 0));
+ }
+
+ void unbindAll() {
+ if (_unbound == true) return;
+
+ unbindAllProperties();
+ super.unbindAll();
+ _unbindNodeTree(shadowRoot);
+ // TODO(sjmiles): must also unbind inherited shadow roots
+ _unbound = true;
+ }
+
+ void cancelUnbindAll({bool preventCascade}) {
+ if (_unbound == true) {
+ _unbindLog.warning(
+ '[$localName] already unbound, cannot cancel unbindAll');
+ return;
+ }
+ _unbindLog.info('[$localName] cancelUnbindAll');
+ if (_unbindAllJob != null) {
+ _unbindAllJob.stop();
+ _unbindAllJob = null;
+ }
+
+ // cancel unbinding our shadow tree iff we're not in the process of
+ // cascading our tree (as we do, for example, when the element is inserted).
+ if (preventCascade == true) return;
+ _forNodeTree(shadowRoot, (n) {
+ if (n is PolymerElement) {
+ (n as PolymerElement).cancelUnbindAll();
+ }
+ });
+ }
+
+ static void _unbindNodeTree(Node node) {
+ _forNodeTree(node, (node) => node.unbindAll());
+ }
+
+ static void _forNodeTree(Node node, void callback(Node node)) {
+ if (node == null) return;
+
+ callback(node);
+ for (var child = node.firstChild; child != null; child = child.nextNode) {
+ _forNodeTree(child, callback);
+ }
+ }
+
+ /** Set up property observers. */
+ void observeProperties() {
+ // TODO(sjmiles):
+ // we observe published properties so we can reflect them to attributes
+ // ~100% of our team's applications would work without this reflection,
+ // perhaps we can make it optional somehow
+ //
+ // add user's observers
+ final observe = _declaration._observe;
+ final publish = _declaration._publish;
+ if (observe != null) {
+ observe.forEach((name, value) {
+ if (publish != null && publish.containsKey(name)) {
+ observeBoth(name, value);
+ } else {
+ observeProperty(name, value);
+ }
+ });
+ }
+ // add observers for published properties
+ if (publish != null) {
+ publish.forEach((name, value) {
+ if (observe == null || !observe.containsKey(name)) {
+ observeAttributeProperty(name);
+ }
+ });
+ }
+ }
+
+ void _observe(String name, void callback(newValue, oldValue)) {
+ _observeLog.info('[$localName] watching [$name]');
+ // TODO(jmesserly): this is a little different than the JS version so we
+ // can pass the oldValue, which is missing from Dart's PathObserver.
+ // This probably gives us worse performance.
+ var path = new PathObserver(this, name);
+ Object oldValue = null;
+ _registerObserver(name, path.changes.listen((_) {
+ final newValue = path.value;
+ final old = oldValue;
+ oldValue = newValue;
+ callback(newValue, old);
+ }));
+ }
+
+ void _registerObserver(String name, StreamSubscription sub) {
+ if (_elementObservers == null) {
+ _elementObservers = new Map<String, StreamSubscription>();
+ }
+ _elementObservers[name] = sub;
+ }
+
+ void observeAttributeProperty(String name) {
+ _observe(name, (value, old) => reflectPropertyToAttribute(name));
+ }
+
+ void observeProperty(String name, Symbol method) {
+ final self = reflect(this);
+ _observe(name, (value, old) => self.invoke(method, [old]));
+ }
+
+ void observeBoth(String name, Symbol methodName) {
+ final self = reflect(this);
+ _observe(name, (value, old) {
+ reflectPropertyToAttribute(name);
+ self.invoke(methodName, [old]);
+ });
+ }
+
+ void unbindProperty(String name) {
+ if (_elementObservers == null) return;
+ var sub = _elementObservers.remove(name);
+ if (sub != null) sub.cancel();
+ }
+
+ void unbindAllProperties() {
+ if (_elementObservers == null) return;
+ for (var sub in _elementObservers.values) sub.cancel();
+ _elementObservers.clear();
+ }
+
+ /**
+ * Bind a [property] in this object to a [path] in model. *Note* in Dart it
+ * is necessary to also define the field:
+ *
+ * var myProperty;
+ *
+ * created() {
+ * super.created();
+ * bindProperty(#myProperty, this, 'myModel.path.to.otherProp');
+ * }
+ */
+ // TODO(jmesserly): replace with something more localized, like:
+ // @ComputedField('myModel.path.to.otherProp');
+ NodeBinding bindProperty(Symbol name, Object model, String path) =>
+ // apply Polymer two-way reference binding
+ _bindProperties(this, name, model, path);
+
+ /**
+ * bind a property in A to a path in B by converting A[property] to a
+ * getter/setter pair that accesses B[...path...]
+ */
+ static NodeBinding _bindProperties(PolymerElement inA, Symbol inProperty,
+ Object inB, String inPath) {
+
+ if (_bindLog.isLoggable(Level.INFO)) {
+ _bindLog.info('[$inB]: bindProperties: [$inPath] to '
+ '[${inA.localName}].[$inProperty]');
+ }
+
+ // Dart note: normally we only reach this code when we know it's a
+ // property, but if someone uses bindProperty directly they might get a
+ // NoSuchMethodError either from the getField below, or from the setField
+ // inside PolymerBinding. That doesn't seem unreasonable, but it's a slight
+ // difference from Polymer.js behavior.
+
+ // capture A's value if B's value is null or undefined,
+ // otherwise use B's value
+ var path = new PathObserver(inB, inPath);
+ if (path.value == null) {
+ path.value = reflect(inA).getField(inProperty).reflectee;
+ }
+ return new _PolymerBinding(inA, inProperty, inB, inPath);
+ }
+
+ /** Attach event listeners on the host (this) element. */
+ void addHostListeners() {
+ var events = _declaration._eventDelegates;
+ if (events.isEmpty) return;
+
+ if (_eventsLog.isLoggable(Level.INFO)) {
+ _eventsLog.info('[$localName] addHostListeners: $events');
+ }
+ addNodeListeners(this, events.keys, hostEventListener);
+ }
+
+ /** Attach event listeners inside a shadow [root]. */
+ void addInstanceListeners(ShadowRoot root, Element template) {
+ var templateDelegates = _declaration._templateDelegates;
+ if (templateDelegates == null) return;
+ var events = templateDelegates[template];
+ if (events == null) return;
+
+ if (_eventsLog.isLoggable(Level.INFO)) {
+ _eventsLog.info('[$localName] addInstanceListeners: $events');
+ }
+ addNodeListeners(root, events, instanceEventListener);
+ }
+
+ void addNodeListeners(Node node, Iterable<String> events,
+ void listener(Event e)) {
+
+ for (var name in events) {
+ addNodeListener(node, name, listener);
+ }
+ }
+
+ void addNodeListener(Node node, String event, void listener(Event e)) {
+ node.on[event].listen(listener);
+ }
+
+ void hostEventListener(Event event) {
+ // TODO(jmesserly): do we need this check? It was using cancelBubble, see:
+ // https://github.com/Polymer/polymer/issues/292
+ if (!event.bubbles) return;
+
+ bool log = _eventsLog.isLoggable(Level.INFO);
+ if (log) {
+ _eventsLog.info('>>> [$localName]: hostEventListener(${event.type})');
+ }
+
+ var h = findEventDelegate(event);
+ if (h != null) {
+ if (log) _eventsLog.info('[$localName] found host handler name [$h]');
+ var detail = event is CustomEvent ?
+ (event as CustomEvent).detail : null;
+ // TODO(jmesserly): cache the symbols?
+ dispatchMethod(new Symbol(h), [event, detail, this]);
+ }
+
+ if (log) {
+ _eventsLog.info('<<< [$localName]: hostEventListener(${event.type})');
+ }
+ }
+
+ String findEventDelegate(Event event) =>
+ _declaration._eventDelegates[_eventNameFromType(event.type)];
+
+ /** Call [methodName] method on [this] with [args], if the method exists. */
+ // TODO(jmesserly): I removed the [node] argument as it was unused. Reconcile.
+ void dispatchMethod(Symbol methodName, List args) {
+ bool log = _eventsLog.isLoggable(Level.INFO);
+ if (log) _eventsLog.info('>>> [$localName]: dispatch $methodName');
+
+ // TODO(sigmund): consider making event listeners list all arguments
+ // explicitly. Unless VM mirrors are optimized first, this reflectClass call
+ // will be expensive once custom elements extend directly from Element (see
+ // dartbug.com/11108).
+ var self = reflect(this);
+ var method = self.type.methods[methodName];
+ if (method != null) {
+ // This will either truncate the argument list or extend it with extra
+ // null arguments, so it will match the signature.
+ // TODO(sigmund): consider accepting optional arguments when we can tell
+ // them appart from named arguments (see http://dartbug.com/11334)
+ args.length = method.parameters.where((p) => !p.isOptional).length;
+ }
+ self.invoke(methodName, args);
+
+ if (log) _eventsLog.info('<<< [$localName]: dispatch $methodName');
+
+ // TODO(jmesserly): workaround for HTML events not supporting zones.
+ performMicrotaskCheckpoint();
+ }
+
+ void instanceEventListener(Event event) {
+ _listenLocal(host, event);
+ }
+
+ // TODO(sjmiles): much of the below privatized only because of the vague
+ // notion this code is too fiddly and we need to revisit the core feature
+ void _listenLocal(Element host, Event event) {
+ // TODO(jmesserly): do we need this check? It was using cancelBubble, see:
+ // https://github.com/Polymer/polymer/issues/292
+ if (!event.bubbles) return;
+
+ bool log = _eventsLog.isLoggable(Level.INFO);
+ if (log) _eventsLog.info('>>> [$localName]: listenLocal [${event.type}]');
+
+ final eventOn = '$_EVENT_PREFIX${_eventNameFromType(event.type)}';
+ if (event.path == null) {
+ _listenLocalNoEventPath(host, event, eventOn);
+ } else {
+ _listenLocalEventPath(host, event, eventOn);
+ }
+
+ if (log) _eventsLog.info('<<< [$localName]: listenLocal [${event.type}]');
+ }
+
+ static void _listenLocalEventPath(Element host, Event event, String eventOn) {
+ var c = null;
+ for (var target in event.path) {
+ // if we hit host, stop
+ if (identical(target, host)) return;
+
+ // find a controller for the target, unless we already found `host`
+ // as a controller
+ c = identical(c, host) ? c : _findController(target);
+
+ // if we have a controller, dispatch the event, and stop if the handler
+ // returns true
+ if (c != null && _handleEvent(c, target, event, eventOn)) {
+ return;
+ }
+ }
+ }
+
+ // TODO(sorvell): remove when ShadowDOM polyfill supports event path.
+ // Note that _findController will not return the expected controller when the
+ // event target is a distributed node. This is because we cannot traverse
+ // from a composed node to a node in shadowRoot.
+ // This will be addressed via an event path api
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21066
+ static void _listenLocalNoEventPath(Element host, Event event,
+ String eventOn) {
+
+ if (_eventsLog.isLoggable(Level.INFO)) {
+ _eventsLog.info('event.path() not supported for ${event.type}');
+ }
+
+ var target = event.target;
+ var c = null;
+ // if we hit dirt or host, stop
+ while (target != null && target != host) {
+ // find a controller for target `t`, unless we already found `host`
+ // as a controller
+ c = identical(c, host) ? c : _findController(target);
+
+ // if we have a controller, dispatch the event, return 'true' if
+ // handler returns true
+ if (c != null && _handleEvent(c, target, event, eventOn)) {
+ return;
+ }
+ target = target.parent;
+ }
+ }
+
+ // TODO(jmesserly): this won't find the correct host unless the ShadowRoot
+ // was created on a PolymerElement.
+ static Element _findController(Node node) {
+ while (node.parentNode != null) {
+ node = node.parentNode;
+ }
+ return _shadowHost[node];
+ }
+
+ static bool _handleEvent(Element ctrlr, Node node, Event event,
+ String eventOn) {
+
+ // Note: local events are listened only in the shadow root. This dynamic
+ // lookup is used to distinguish determine whether the target actually has a
+ // listener, and if so, to determine lazily what's the target method.
+ var name = node is Element ? (node as Element).attributes[eventOn] : null;
+ if (name != null && _handleIfNotHandled(node, event)) {
+ if (_eventsLog.isLoggable(Level.INFO)) {
+ _eventsLog.info('[${ctrlr.localName}] found handler name [$name]');
+ }
+ var detail = event is CustomEvent ?
+ (event as CustomEvent).detail : null;
+
+ if (node != null) {
+ // TODO(jmesserly): cache symbols?
+ ctrlr.xtag.dispatchMethod(new Symbol(name), [event, detail, node]);
+ }
+ }
+
+ // TODO(jmesserly): do we need this? It was using cancelBubble, see:
+ // https://github.com/Polymer/polymer/issues/292
+ return !event.bubbles;
+ }
+
+ // TODO(jmesserly): I don't understand this bit. It seems to be a duplicate
+ // delivery prevention mechanism?
+ static bool _handleIfNotHandled(Node node, Event event) {
+ var list = _eventHandledTable[event];
+ if (list == null) _eventHandledTable[event] = list = new Set<Node>();
+ if (!list.contains(node)) {
+ list.add(node);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Invokes a function asynchronously.
+ * This will call `Platform.flush()` and then return a `new Timer`
+ * with the provided [method] and [timeout].
+ *
+ * If you would prefer to run the callback using
+ * [window.requestAnimationFrame], see the [async] method.
+ */
+ // Dart note: "async" is split into 2 methods so it can have a sensible type
+ // signatures. Also removed the various features that don't make sense in a
+ // Dart world, like binding to "this" and taking arguments list.
+ Timer asyncTimer(void method(), Duration timeout) {
+ // when polyfilling Object.observe, ensure changes
+ // propagate before executing the async method
+ platform.flush();
+ return new Timer(timeout, method);
+ }
+
+ /**
+ * Invokes a function asynchronously.
+ * This will call `Platform.flush()` and then call
+ * [window.requestAnimationFrame] with the provided [method] and return the
+ * result.
+ *
+ * If you would prefer to run the callback after a given duration, see
+ * the [asyncTimer] method.
+ */
+ int async(RequestAnimationFrameCallback method) {
+ // when polyfilling Object.observe, ensure changes
+ // propagate before executing the async method
+ platform.flush();
+ return window.requestAnimationFrame(method);
+ }
+
+ /**
+ * Fire a [CustomEvent] targeting [toNode], or this if toNode is not
+ * supplied. Returns the [detail] object.
+ */
+ Object fire(String type, {Object detail, Node toNode, bool canBubble}) {
+ var node = toNode != null ? toNode : this;
+ //log.events && console.log('[%s]: sending [%s]', node.localName, inType);
+ node.dispatchEvent(new CustomEvent(
+ type,
+ canBubble: canBubble != null ? canBubble : true,
+ detail: detail
+ ));
+ return detail;
+ }
+
+ /**
+ * Fire an event asynchronously. See [async] and [fire].
+ */
+ asyncFire(String type, {Object detail, Node toNode, bool canBubble}) {
+ // TODO(jmesserly): I'm not sure this method adds much in Dart, it's easy to
+ // add "() =>"
+ async((x) => fire(
+ type, detail: detail, toNode: toNode, canBubble: canBubble));
+ }
+
+ /**
+ * Remove [className] from [old], add class to [anew], if they exist.
+ */
+ void classFollows(Element anew, Element old, String className) {
+ if (old != null) {
+ old.classes.remove(className);
+ }
+ if (anew != null) {
+ anew.classes.add(className);
+ }
+ }
+}
+
+// Dart note: Polymer addresses n-way bindings by metaprogramming: redefine
+// the property on the PolymerElement instance to always get its value from the
+// model@path. We can't replicate this in Dart so we do the next best thing:
+// listen to changes on both sides and update the values.
+// TODO(jmesserly): our approach leads to race conditions in the bindings.
+// See http://code.google.com/p/dart/issues/detail?id=13567
+class _PolymerBinding extends NodeBinding {
+ final InstanceMirror _target;
+ final Symbol _property;
+ StreamSubscription _sub;
+ Object _lastValue;
+
+ _PolymerBinding(PolymerElement node, Symbol property, model, path)
+ : _target = reflect(node),
+ _property = property,
+ super(node, MirrorSystem.getName(property), model, path) {
+
+ _sub = node.changes.listen(_propertyValueChanged);
+ }
+
+ void close() {
+ if (closed) return;
+ _sub.cancel();
+ super.close();
+ }
+
+ void boundValueChanged(newValue) {
+ _lastValue = newValue;
+ _target.setField(_property, newValue);
+ }
+
+ void _propertyValueChanged(List<ChangeRecord> records) {
+ for (var record in records) {
+ if (record.changes(_property)) {
+ final newValue = _target.getField(_property).reflectee;
+ if (!identical(_lastValue, newValue)) {
+ value = newValue;
+ }
+ return;
+ }
+ }
+ }
+}
+
+bool _toBoolean(value) => null != value && false != value;
+
+TypeMirror _propertyType(DeclarationMirror property) =>
+ property is VariableMirror
+ ? (property as VariableMirror).type
+ : (property as MethodMirror).returnType;
+
+TypeMirror _inferPropertyType(Object value, DeclarationMirror property) {
+ var type = _propertyType(property);
+ if (type.qualifiedName == const Symbol('dart.core.Object') ||
+ type.qualifiedName == const Symbol('dynamic')) {
+ // Attempt to infer field type from the default value.
+ if (value != null) {
+ type = reflect(value).type;
+ }
+ }
+ return type;
+}
+
+final Logger _observeLog = new Logger('polymer.observe');
+final Logger _eventsLog = new Logger('polymer.events');
+final Logger _unbindLog = new Logger('polymer.unbind');
+final Logger _bindLog = new Logger('polymer.bind');
+
+final Expando _shadowHost = new Expando<Element>();
+
+final Expando _eventHandledTable = new Expando<Set<Node>>();
diff --git a/pkg/polymer/lib/src/loader.dart b/pkg/polymer/lib/src/loader.dart
new file mode 100644
index 0000000..e8cbb90
--- /dev/null
+++ b/pkg/polymer/lib/src/loader.dart
@@ -0,0 +1,130 @@
+// 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 polymer;
+
+/** Annotation used to automatically register polymer elements. */
+class CustomTag {
+ final String tagName;
+ const CustomTag(this.tagName);
+}
+
+/**
+ * Metadata used to label static or top-level methods that are called
+ * automatically when loading the library of a custom element.
+ */
+const initMethod = const _InitMethodAnnotation();
+
+/**
+ * Initializes a polymer application as follows:
+ * * set up up polling for observable changes
+ * * initialize MDV
+ * * for each library in [libraries], register custom elements labeled with
+ * [CustomTag] and invoke the initialization method on it.
+ *
+ * The initialization on each library is either a method named `main` or
+ * a top-level function and annotated with [initMethod].
+ *
+ * The urls in [libraries] can be absolute or relative to [srcUrl].
+ */
+void initPolymer(List<String> libraries, [String srcUrl]) {
+ runMicrotask(() {
+ // DOM events don't yet go through microtasks, so we catch those here.
+ new Timer.periodic(new Duration(milliseconds: 125),
+ (_) => performMicrotaskCheckpoint());
+
+ // TODO(jmesserly): mdv should use initMdv instead of mdv.initialize.
+ mdv.initialize();
+ registerCustomElement('polymer-element', () => new PolymerDeclaration());
+
+ for (var lib in libraries) {
+ _loadLibrary(lib, srcUrl);
+ }
+
+ // TODO(jmesserly): this should be in the custom_element polyfill, not here.
+ // notify the system that we are bootstrapped
+ document.body.dispatchEvent(
+ new CustomEvent('WebComponentsReady', canBubble: true));
+ });
+}
+
+/** All libraries in the current isolate. */
+final _libs = currentMirrorSystem().libraries;
+
+/**
+ * Reads the library at [uriString] (which can be an absolute URI or a relative
+ * URI from [srcUrl]), and:
+ *
+ * * If present, invokes `main`.
+ *
+ * * If present, invokes any top-level and static functions marked
+ * with the [initMethod] annotation (in the order they appear).
+ *
+ * * Registers any [PolymerElement] that is marked with the [CustomTag]
+ * annotation.
+ */
+void _loadLibrary(String uriString, [String srcUrl]) {
+ var uri = Uri.parse(uriString);
+ if (uri.scheme == '' && srcUrl != null) {
+ uri = Uri.parse(path.normalize(path.join(path.dirname(srcUrl), uriString)));
+ }
+ var lib = _libs[uri];
+ if (lib == null) {
+ print('warning: $uri library not found');
+ return;
+ }
+
+ // Invoke `main`, if present.
+ if (lib.functions[const Symbol('main')] != null) {
+ lib.invoke(const Symbol('main'), const []);
+ }
+
+ // Search top-level functions marked with @initMethod
+ for (var f in lib.functions.values) {
+ _maybeInvoke(lib, f);
+ }
+
+ for (var c in lib.classes.values) {
+ // Search for @CustomTag on classes
+ for (var m in c.metadata) {
+ var meta = m.reflectee;
+ if (meta is CustomTag) {
+ Polymer._registerClassMirror(meta.tagName, c);
+ }
+ }
+
+ // TODO(sigmund): check also static methods marked with @initMethod.
+ // This is blocked on two bugs:
+ // - dartbug.com/12133 (static methods are incorrectly listed as top-level
+ // in dart2js, so they end up being called twice)
+ // - dartbug.com/12134 (sometimes "method.metadata" throws an exception,
+ // we could wrap and hide those exceptions, but it's not ideal).
+ }
+}
+
+void _maybeInvoke(ObjectMirror obj, MethodMirror method) {
+ var annotationFound = false;
+ for (var meta in method.metadata) {
+ if (identical(meta.reflectee, initMethod)) {
+ annotationFound = true;
+ break;
+ }
+ }
+ if (!annotationFound) return;
+ if (!method.isStatic) {
+ print("warning: methods marked with @initMethod should be static,"
+ " ${method.simpleName} is not.");
+ return;
+ }
+ if (!method.parameters.where((p) => !p.isOptional).isEmpty) {
+ print("warning: methods marked with @initMethod should take no "
+ "arguments, ${method.simpleName} expects some.");
+ return;
+ }
+ obj.invoke(method.simpleName, const []);
+}
+
+class _InitMethodAnnotation {
+ const _InitMethodAnnotation();
+}
diff --git a/pkg/polymer/lib/transformer.dart b/pkg/polymer/lib/transformer.dart
index 5f4dc02..26d5678 100644
--- a/pkg/polymer/lib/transformer.dart
+++ b/pkg/polymer/lib/transformer.dart
@@ -6,6 +6,7 @@
// TODO(sigmund): move into a plugin directory when pub supports it.
library polymer.src.transform;
+import 'package:barback/barback.dart';
import 'package:observe/transform.dart';
import 'src/build/code_extractor.dart';
import 'src/build/import_inliner.dart';
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index 4d93ad5..acd745f 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -1,5 +1,5 @@
name: polymer
-author: Web UI Authors <web-ui-dev@dartlang.org>
+author: Polymer.dart Authors <web-ui-dev@dartlang.org>
description: >
Polymer.dart is a new type of library for the web, built on top of Web
Components, and designed to leverage the evolving web platform on modern
@@ -16,11 +16,12 @@
html_import: any
logging: any
mdv: any
+ meta: any
observe: any
path: any
polymer_expressions: any
shadow_dom: any
source_maps: any
- # TODO(jmesserly): make this a dev_dependency
- unittest: any
yaml: any
+dev_dependencies:
+ unittest: any
diff --git a/pkg/polymer/test/attr_deserialize_test.dart b/pkg/polymer/test/attr_deserialize_test.dart
new file mode 100644
index 0000000..8497752
--- /dev/null
+++ b/pkg/polymer/test/attr_deserialize_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.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('my-element')
+class MyElement extends PolymerElement {
+ @published double volume;
+ @published int factor;
+ @published bool crankIt;
+ @published String msg;
+ @published DateTime time;
+ @published Object json;
+}
+
+main() {
+ useHtmlConfiguration();
+
+ test('attributes were deserialized', () {
+ MyElement elem = query('my-element').xtag;
+ final msg = 'property should match attribute.';
+ expect(elem.volume, 11.0, reason: '"volume" should match attribute');
+ expect(elem.factor, 3, reason: '"factor" should match attribute');
+ expect(elem.crankIt, true, reason: '"crankIt" should match attribute');
+ expect(elem.msg, "Yo!", reason: '"msg" should match attribute');
+ expect(elem.time, DateTime.parse('2013-08-08T18:34Z'),
+ reason: '"time" should match attribute');
+ expect(elem.json, {'here': 'is', 'some': 'json', 'x': 123},
+ reason: '"json" should match attribute');
+
+ var text = elem.shadowRoot.text;
+ // Collapse adjacent whitespace like a browser would:
+ text = text.replaceAll('\n', ' ').replaceAll(new RegExp(r'\s+'), ' ');
+
+ // Note: using "${33.0}" because the toString differs in JS vs Dart VM.
+ expect(text, " Yo! The volume is ${33.0} !! The time is "
+ "2013-08-08 18:34:00.000Z and here's some JSON: "
+ "{here: is, some: json, x: 123} ",
+ reason: 'text should match expected HTML template');
+ });
+}
diff --git a/pkg/polymer/test/attr_deserialize_test.html b/pkg/polymer/test/attr_deserialize_test.html
new file mode 100644
index 0000000..de10fac
--- /dev/null
+++ b/pkg/polymer/test/attr_deserialize_test.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<html>
+ <head>
+ <title>Polymer.dart attribute deserialization test</title>
+ <script src="packages/polymer/boot.js"></script>
+ <script src="packages/unittest/test_controller.js"></script>
+ </head>
+ <body>
+ <polymer-element name="my-element">
+ <template>
+ <h1>{{msg}} The volume is {{volume * factor}}
+ <template if="{{crankIt}}">!!</template></h1>
+ <h3>The time is {{time}} and here's some JSON: {{json}}</h3>
+ </template>
+ </polymer-element>
+
+ <my-element volume="11" crankit msg="Yo!" factor="3"
+ time="2013-08-08T18:34Z"
+ json="{'here': 'is', 'some': 'json', 'x': 123}">
+ </my-element>
+
+ <script type="application/dart" src="attr_deserialize_test.dart"></script>
+ </body>
+</html>
diff --git a/pkg/polymer/test/attr_mustache_test.dart b/pkg/polymer/test/attr_mustache_test.dart
new file mode 100644
index 0000000..fba0171
--- /dev/null
+++ b/pkg/polymer/test/attr_mustache_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.
+
+import 'dart:async';
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('x-target')
+class XTarget extends PolymerElement {
+ final Completer _found = new Completer();
+ Future get foundSrc => _found.future;
+
+ // force an mdv binding
+ bind(name, model, path) =>
+ TemplateElement.mdvPackage(this).bind(name, model, path);
+
+ inserted() {
+ testSrcForMustache();
+ }
+
+ attributeChanged(name, oldValue) {
+ testSrcForMustache();
+ if (attributes[name] == '../testSource') {
+ _found.complete();
+ }
+ }
+
+ testSrcForMustache() {
+ expect(attributes['src'], isNot(matches(Polymer.bindPattern)),
+ reason: 'attribute does not contain {{...}}');
+ }
+}
+
+@CustomTag('x-test')
+class XTest extends PolymerElement {
+ @observable var src = 'testSource';
+}
+
+main() {
+ useHtmlConfiguration();
+
+ test('mustache attributes', () {
+ final xtest = document.query('#test').xtag;
+ final xtarget = xtest.shadowRoot.query('#target').xtag;
+ return xtarget.foundSrc;
+ });
+}
diff --git a/pkg/polymer/test/attr_mustache_test.html b/pkg/polymer/test/attr_mustache_test.html
new file mode 100644
index 0000000..df9f9ee
--- /dev/null
+++ b/pkg/polymer/test/attr_mustache_test.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+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.
+-->
+<html>
+ <head>
+ <title>take attributes</title>
+ <script src="packages/polymer/boot.js"></script>
+ <script src="packages/unittest/test_controller.js"></script>
+ </head>
+ <body>
+ <x-test id="test"></x-test>
+
+ <polymer-element name="x-target" attributes="src">
+ </polymer-element>
+
+ <polymer-element name="x-test">
+ <template>
+ <x-target id="target" src="../{{src}}"></x-target>
+ </template>
+ </polymer-element>
+
+ <script type="application/dart" src="attr_mustache_test.dart"></script>
+ </body>
+</html>
diff --git a/pkg/polymer/test/build/all_phases_test.dart b/pkg/polymer/test/build/all_phases_test.dart
index 1c2dccc..9e6a9b7 100644
--- a/pkg/polymer/test/build/all_phases_test.dart
+++ b/pkg/polymer/test/build/all_phases_test.dart
@@ -198,17 +198,14 @@
}
''';
-String _sampleObservableOutput(String className, String fieldName) => '''
-library ${className}_$fieldName;
-import 'package:observe/observe.dart';
-
-class $className extends ChangeNotifierBase {
- int __\$$fieldName;
- int get $fieldName => __\$$fieldName;
- set $fieldName(int value) {
- __\$$fieldName = notifyPropertyChange(const Symbol('$fieldName'), __\$$fieldName, value);
- }
-
- $className($fieldName) : __\$$fieldName = $fieldName;
-}
-''';
+String _sampleObservableOutput(String className, String field) =>
+ "library ${className}_$field;\n"
+ "import 'package:observe/observe.dart';\n\n"
+ "class $className extends ChangeNotifierBase {\n"
+ " @observable int get $field => __\$$field; "
+ "int __\$$field; "
+ "set $field(int value) { "
+ "__\$$field = notifyPropertyChange(#$field, __\$$field, value); "
+ "}\n"
+ " $className($field) : __\$$field = $field;\n"
+ "}\n";
diff --git a/pkg/polymer/test/build/linter_test.dart b/pkg/polymer/test/build/linter_test.dart
index e4f3630..17975a8 100644
--- a/pkg/polymer/test/build/linter_test.dart
+++ b/pkg/polymer/test/build/linter_test.dart
@@ -261,7 +261,7 @@
'JavaScript event handler. Use the form '
'on-event-name="handlerName" if you want a Dart handler '
'that will automatically update the UI based on model changes. '
- '(lib/test.html 1 0)'
+ '(lib/test.html 1 5)'
});
_testLinter('on-foo is only supported in polymer elements', {
@@ -272,7 +272,7 @@
'a|lib/test.html.messages':
'warning: Inline event handlers are only supported inside '
'declarations of <polymer-element>. '
- '(lib/test.html 1 0)'
+ '(lib/test.html 1 5)'
});
_testLinter('on-foo is not an expression', {
@@ -285,7 +285,20 @@
'warning: Invalid event handler body "bar()". Declare a method '
'in your custom element "void handlerName(event, detail, target)" '
'and use the form on-foo="handlerName". '
- '(lib/test.html 1 28)'
+ '(lib/test.html 1 33)'
+ });
+
+ _testLinter('on-foo-bar is no longer supported', {
+ 'a|lib/test.html': '''<html><body>
+ <polymer-element name="x-a"><div on-foo-bar="quux"></div>
+ </polymer-element>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: Invalid event name "on-foo-bar". After the "on-" the '
+ 'event name should not use dashes. For example use "on-fooBar" or '
+ '"on-foobar" (both forms are equivalent in HTML). '
+ '(lib/test.html 1 33)'
});
});
@@ -294,7 +307,7 @@
'a|lib/test.html': '<x-foo></x-foo>',
}, {
'a|lib/test.html.messages':
- 'warning: definition for custom element with tag name "x-foo" not '
+ 'warning: definition for Polymer element with tag name "x-foo" not '
'found. (lib/test.html 0 0)'
});
@@ -302,7 +315,7 @@
'a|lib/test.html': '<div is="x-foo"></div>',
}, {
'a|lib/test.html.messages':
- 'warning: definition for custom element with tag name "x-foo" not '
+ 'warning: definition for Polymer element with tag name "x-foo" not '
'found. (lib/test.html 0 0)'
});
@@ -409,6 +422,20 @@
'to write <li is="x-a">? (lib/test.html 1 0)'
});
});
+
+ group('custom attributes', () {
+ _testLinter('foo-bar is no longer supported in attributes', {
+ 'a|lib/test.html': '''<html><body>
+ <polymer-element name="x-a" attributes="foo-bar">
+ </polymer-element>
+ '''.replaceAll(' ', ''),
+ }, {
+ 'a|lib/test.html.messages':
+ 'warning: PolymerElement no longer recognizes attribute names with '
+ 'dashes such as "foo-bar". Use "fooBar" or "foobar" instead (both '
+ 'forms are equivalent in HTML). (lib/test.html 1 28)'
+ });
+ });
}
_testLinter(String name, Map inputFiles, Map outputMessages) {
diff --git a/pkg/polymer/test/utils_test.dart b/pkg/polymer/test/build/utils_test.dart
similarity index 98%
rename from pkg/polymer/test/utils_test.dart
rename to pkg/polymer/test/build/utils_test.dart
index 335e538..cd99656 100644
--- a/pkg/polymer/test/utils_test.dart
+++ b/pkg/polymer/test/build/utils_test.dart
@@ -7,7 +7,7 @@
import 'package:unittest/compact_vm_config.dart';
import 'package:unittest/unittest.dart';
-import 'package:polymer/src/utils.dart';
+import 'package:polymer/src/build/utils.dart';
main() {
useCompactVMConfiguration();
diff --git a/pkg/polymer/test/prop_attr_reflection_test.dart b/pkg/polymer/test/prop_attr_reflection_test.dart
new file mode 100644
index 0000000..d74f5e4
--- /dev/null
+++ b/pkg/polymer/test/prop_attr_reflection_test.dart
@@ -0,0 +1,110 @@
+// 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/platform.dart' as Platform;
+import 'package:polymer/polymer.dart';
+
+class XFoo extends PolymerElement {
+ @observable var foo = '';
+ @observable String baz = '';
+}
+
+class XBar extends XFoo {
+ @observable int zot = 3;
+ @observable bool zim = false;
+ @observable String str = 'str';
+ @observable Object obj;
+}
+
+class XCompose extends PolymerElement {
+ @observable bool zim = false;
+}
+
+main() {
+ useHtmlConfiguration();
+
+ // Most tests use @CustomTag, here we test out the impertive register:
+ Polymer.register('x-foo', XFoo);
+ Polymer.register('x-bar', XBar);
+ Polymer.register('x-compose', XCompose);
+
+ test('property attribute reflection', () {
+ var xcompose = query('x-compose').xtag;
+ var xfoo = query('x-foo').xtag;
+ xfoo.foo = 5;
+ Platform.flush();
+ Platform.endOfMicrotask(expectAsync0(() {
+ expect(xcompose.$['bar'].attributes.containsKey('zim'), false,
+ reason: 'attribute bound to property updates when binding is made');
+
+ expect('${xfoo.foo}', xfoo.attributes['foo'],
+ reason: 'attribute reflects property as string');
+ xfoo.attributes['foo'] = '27';
+ // TODO(jmesserly): why is JS leaving this as a String? From the code it
+ // looks like it should use the type of 5 and parse it as a number.
+ expect('${xfoo.foo}', xfoo.attributes['foo'],
+ reason: 'property reflects attribute');
+ //
+ xfoo.baz = 'Hello';
+ Platform.flush();
+ Platform.endOfMicrotask(expectAsync0(() {
+ expect(xfoo.baz, xfoo.attributes['baz'],
+ reason: 'attribute reflects property');
+ //
+ var xbar = query('x-bar').xtag;
+ //
+ xbar.foo = 'foo!';
+ xbar.zot = 27;
+ xbar.zim = true;
+ xbar.str = 'str!';
+ xbar.obj = {'hello': 'world'};
+ Platform.flush();
+ Platform.endOfMicrotask(expectAsync0(() {
+ expect(xbar.foo, xbar.attributes['foo'],
+ reason: 'inherited published property is reflected');
+ expect('${xbar.zot}', xbar.attributes['zot'],
+ reason: 'attribute reflects property as number');
+ expect(xbar.attributes['zim'], '', reason:
+ 'attribute reflects true valued boolean property as '
+ 'having attribute');
+ expect(xbar.str, xbar.attributes['str'],
+ reason: 'attribute reflects property as published string');
+ expect(xbar.attributes.containsKey('obj'), false,
+ reason: 'attribute does not reflect object property');
+ xbar.attributes['zim'] = 'false';
+ xbar.attributes['foo'] = 'foo!!';
+ xbar.attributes['zot'] = '54';
+ xbar.attributes['str'] = 'str!!';
+ xbar.attributes['obj'] = "{'hello': 'world'}";
+ expect(xbar.foo, xbar.attributes['foo'],
+ reason: 'property reflects attribute as string');
+ expect(xbar.zot, 54,
+ reason: 'property reflects attribute as number');
+ expect(xbar.zim, false,
+ reason: 'property reflects attribute as boolean');
+ expect(xbar.str, 'str!!',
+ reason: 'property reflects attribute as published string');
+ expect(xbar.obj, {'hello': 'world'},
+ reason: 'property reflects attribute as object');
+ xbar.zim = false;
+ Platform.flush();
+ Platform.endOfMicrotask(expectAsync0(() {
+ expect(xbar.attributes.containsKey('zim'), false, reason:
+ 'attribute reflects false valued boolean property as NOT '
+ 'having attribute');
+ var objAttr = xbar.attributes['obj'];
+ xbar.obj = 'hi';
+ Platform.endOfMicrotask(expectAsync0(() {
+ expect(xbar.attributes['obj'], objAttr, reason:
+ 'do not reflect property with default type of object');
+ }));
+ }));
+ }));
+ }));
+ }));
+ });
+}
diff --git a/pkg/polymer/test/prop_attr_reflection_test.html b/pkg/polymer/test/prop_attr_reflection_test.html
new file mode 100644
index 0000000..e4466d3
--- /dev/null
+++ b/pkg/polymer/test/prop_attr_reflection_test.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<!--
+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.
+-->
+<html>
+ <head>
+ <title>publish attributes</title>
+ <script src="packages/polymer/boot.js"></script>
+ <script src="packages/unittest/test_controller.js"></script>
+ </head>
+ <body>
+
+ <x-foo></x-foo>
+ <polymer-element name="x-foo" attributes="foo baz">
+ </polymer-element>
+
+ <x-bar></x-bar>
+ <polymer-element name="x-bar" extends="x-foo" attributes="zot zim str obj">
+ </polymer-element>
+
+ <x-compose></x-compose>
+ <polymer-element name="x-compose">
+ <template>
+ <x-bar id="bar" zim="{{zim}}"></x-bar>
+ </template>
+ </polymer-element>
+
+ <script type="application/dart" src="prop_attr_reflection_test.dart"></script>
+ </body>
+</html>
\ No newline at end of file
diff --git a/pkg/polymer/test/publish_attributes_test.dart b/pkg/polymer/test/publish_attributes_test.dart
new file mode 100644
index 0000000..e31b74f
--- /dev/null
+++ b/pkg/polymer/test/publish_attributes_test.dart
@@ -0,0 +1,53 @@
+// 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+// Dart note: unlike JS, you can't publish something that doesn't
+// have a corresponding field because we can't dynamically add properties.
+// So we define XFoo and XBar types here.
+@CustomTag('x-foo')
+class XFoo extends PolymerElement {
+ @observable var Foo;
+ @observable var baz;
+}
+
+@CustomTag('x-bar')
+class XBar extends XFoo {
+ @observable var Bar;
+}
+
+@CustomTag('x-zot')
+class XZot extends XBar {
+ @published int zot = 3;
+}
+
+@CustomTag('x-squid')
+class XSquid extends XZot {
+ @published int baz = 13;
+ @published int zot = 5;
+ @published int squid = 7;
+}
+
+main() {
+ useHtmlConfiguration();
+
+ test('published properties', () {
+ published(tag) =>
+ query('polymer-element[name=$tag]').xtag.publishedProperties;
+
+ print(published('x-foo'));
+ print(published('x-bar'));
+ print(published('x-zot'));
+ print(published('x-squid'));
+
+ expect(published('x-foo'), ['Foo', 'baz']);
+ expect(published('x-bar'), ['Foo', 'baz', 'Bar']);
+ expect(published('x-zot'), ['Foo', 'baz', 'Bar', 'zot']);
+ expect(published('x-squid'), ['Foo', 'baz', 'Bar', 'zot', 'squid']);
+ });
+}
diff --git a/pkg/polymer/test/publish_attributes_test.html b/pkg/polymer/test/publish_attributes_test.html
new file mode 100644
index 0000000..6b9347a
--- /dev/null
+++ b/pkg/polymer/test/publish_attributes_test.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<!--
+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.
+-->
+<html>
+ <head>
+ <title>publish attributes</title>
+ <script src="packages/polymer/boot.js"></script>
+ <script src="packages/unittest/test_controller.js"></script>
+ </head>
+ <body>
+
+ <polymer-element name="x-foo" attributes="Foo baz">
+ </polymer-element>
+
+ <polymer-element name="x-bar" extends="x-foo" attributes="Bar">
+ </polymer-element>
+
+ <polymer-element name="x-zot" extends="x-bar">
+ </polymer-element>
+
+ <polymer-element name="x-squid" extends="x-zot" attributes="squid">
+ </polymer-element>
+
+ <script type="application/dart" src="publish_attributes_test.dart"></script>
+ </body>
+</html>
diff --git a/pkg/polymer/test/take_attributes_test.dart b/pkg/polymer/test/take_attributes_test.dart
new file mode 100644
index 0000000..a9e409f
--- /dev/null
+++ b/pkg/polymer/test/take_attributes_test.dart
@@ -0,0 +1,109 @@
+// 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('x-foo')
+class XFoo extends PolymerElement {
+ @published bool boolean = false;
+ @published num number = 42;
+ @published String str = "don't panic";
+}
+
+@CustomTag('x-bar')
+class XBar extends PolymerElement {
+ @observable bool boolean = false;
+ @observable num number = 42;
+ @observable String str = "don't panic";
+}
+
+@CustomTag('x-zot')
+class XZot extends XBar {
+ @observable num number = 84;
+}
+
+@CustomTag('x-date')
+class XDate extends PolymerElement {
+ @observable var value = new DateTime(2013, 9, 25);
+}
+
+@CustomTag('x-array')
+class XArray extends PolymerElement {
+ @observable List values;
+}
+
+@CustomTag('x-obj')
+class XObj extends PolymerElement {
+ @observable var values = {};
+}
+
+main() {
+ useHtmlConfiguration();
+
+ test('take attributes', () {
+ queryXTag(x) => document.query(x).xtag;
+
+ expect(queryXTag("#foo0").boolean, true);
+ expect(queryXTag("#foo1").boolean, false);
+ expect(queryXTag("#foo2").boolean, true);
+ expect(queryXTag("#foo3").boolean, false);
+ // this one is only 'truthy'
+ expect(queryXTag("#foo4").boolean, true);
+ // this one is also 'truthy', but should it be?
+ expect(queryXTag("#foo5").boolean, true);
+ //
+ expect(queryXTag("#foo0").number, 42);
+ expect(queryXTag("#foo0").str, "don't panic");
+ //
+ expect(queryXTag("#bar0").boolean, true);
+ expect(queryXTag("#bar1").boolean, false);
+ expect(queryXTag("#bar2").boolean, true);
+ expect(queryXTag("#bar3").boolean, false);
+ // this one is only 'truthy'
+ expect(queryXTag("#bar4").boolean, true);
+ // this one is also 'truthy', but should it be?
+ expect(queryXTag("#bar5").boolean, true);
+ //
+ expect(queryXTag("#bar0").number, 42);
+ expect(queryXTag("#bar0").str, "don't panic");
+ //
+ expect(queryXTag("#zot0").boolean, true);
+ expect(queryXTag("#zot1").boolean, false);
+ expect(queryXTag("#zot2").boolean, true);
+ expect(queryXTag("#zot3").boolean, false);
+ // this one is only 'truthy'
+ expect(queryXTag("#zot4").boolean, true);
+ // this one is also 'truthy', but should it be?
+ expect(queryXTag("#zot5").boolean, true);
+ //
+ expect(queryXTag("#zot0").number, 84);
+ expect(queryXTag("#zot6").number, 185);
+ expect(queryXTag("#zot0").str, "don't panic");
+ //
+ // Date deserialization tests
+ expect(queryXTag("#date1").value, new DateTime(2014, 12, 25));
+ expect(queryXTag("#date2").value, isNot(equals(new DateTime(2014, 12, 25))),
+ reason: 'Dart does not support this format');
+ expect(queryXTag("#date3").value, new DateTime(2014, 12, 25, 11, 45));
+ expect(queryXTag("#date4").value, new DateTime(2014, 12, 25, 11, 45, 30));
+ // Failures on Firefox. Need to fix this with custom parsing
+ //expect(String(queryXTag("#date5").value), String(new Date(2014, 11, 25, 11, 45, 30)));
+ //
+ // milliseconds in the Date string not supported on Firefox
+ //expect(queryXTag("#date5").value.getMilliseconds(), new Date(2014, 11, 25, 11, 45, 30, 33).getMilliseconds());
+ //
+ // Array deserialization tests
+ expect(queryXTag("#arr1").values, [0, 1, 2]);
+ expect(queryXTag("#arr2").values, [33]);
+ // Object deserialization tests
+ expect(queryXTag("#obj1").values, { 'name': 'Brandon',
+ 'nums': [1, 22, 33] });
+ expect(queryXTag("#obj2").values, { "color": "Red" });
+ expect(queryXTag("#obj3").values, { 'movie': 'Buckaroo Banzai',
+ 'DOB': '07/31/1978' });
+ });
+}
diff --git a/pkg/polymer/test/take_attributes_test.html b/pkg/polymer/test/take_attributes_test.html
new file mode 100644
index 0000000..c65f604
--- /dev/null
+++ b/pkg/polymer/test/take_attributes_test.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<!--
+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.
+-->
+<html>
+ <head>
+ <title>take attributes</title>
+ <script src="packages/polymer/boot.js"></script>
+ <script src="packages/unittest/test_controller.js"></script>
+ </head>
+ <body>
+
+ <polymer-element name="x-foo"></polymer-element>
+
+ <x-foo id="foo0" boolean="true"></x-foo>
+ <x-foo id="foo1" boolean="false"></x-foo>
+ <x-foo id="foo2" boolean></x-foo>
+ <x-foo id="foo3"></x-foo>
+ <x-foo id="foo4" boolean="squid"></x-foo>
+ <x-foo id="foo5" boolean="0"></x-foo>
+
+ <polymer-element name="x-bar" attributes="boolean number str">
+ </polymer-element>
+
+ <x-bar id="bar0" boolean="true"></x-bar>
+ <x-bar id="bar1" boolean="false"></x-bar>
+ <x-bar id="bar2" boolean></x-bar>
+ <x-bar id="bar3"></x-bar>
+ <x-bar id="bar4" boolean="squid"></x-bar>
+ <x-bar id="bar5" boolean="0"></x-bar>
+
+ <polymer-element name="x-zot" extends="x-bar" attributes="boolean">
+ </polymer-element>
+
+ <x-zot id="zot0" boolean="true"></x-zot>
+ <x-zot id="zot1" boolean="false"></x-zot>
+ <x-zot id="zot2" boolean></x-zot>
+ <x-zot id="zot3"></x-zot>
+ <x-zot id="zot4" boolean="squid"></x-zot>
+ <x-zot id="zot5" boolean="0"></x-zot>
+ <x-zot id="zot6" number="185"></x-zot>
+
+ <polymer-element name="x-date" attributes="value"></polymer-element>
+
+ <!--
+ TODO(jmesserly): Dart note: I changed these to dash "-" instead of slash "/"
+ as the year-month-day separator. Also the form "December 25, 2014" is not
+ supported in Dart.
+ -->
+ <x-date id="date1" value="2014-12-25"></x-date>
+ <x-date id="date2" value="December 25, 2014"></x-date>
+ <x-date id="date3" value="2014-12-25 11:45"></x-date>
+ <x-date id="date4" value="2014-12-25 11:45:30"></x-date>
+ <x-date id="date5" value="2014-12-25 11:45:30:33"></x-date>
+ <x-date id="dated" value="2014-12-25T11:45:30:33"></x-date>
+
+ <polymer-element name="x-array" attributes="values"></polymer-element>
+
+ <x-array id="arr1" values="[0, 1, 2]"></x-array>
+ <x-array id="arr2" values="[33]"></x-array>
+
+ <polymer-element name="x-obj" attributes="values"></polymer-element>
+
+ <x-obj id="obj1" values='{ "name": "Brandon", "nums": [1, 22, 33] }'>
+ </x-obj>
+ <x-obj id="obj2" values='{ "color": "Red" }'></x-obj>
+ <x-obj id="obj3"
+ values="{ 'movie': 'Buckaroo Banzai', 'DOB': '07/31/1978' }">
+ </x-obj>
+
+ <script type="application/dart" src="take_attributes_test.dart"></script>
+ </body>
+</html>
diff --git a/pkg/polymer_expressions/lib/expression.dart b/pkg/polymer_expressions/lib/expression.dart
index 0a5bb82..60b7548 100644
--- a/pkg/polymer_expressions/lib/expression.dart
+++ b/pkg/polymer_expressions/lib/expression.dart
@@ -8,7 +8,7 @@
// Helper functions for building expression trees programmatically
-EmptyExpression empty() => new EmptyExpression();
+EmptyExpression empty() => const EmptyExpression();
Literal literal(v) => new Literal(v);
MapLiteral mapLiteral(List<MapLiteralEntry> entries) => new MapLiteral(entries);
MapLiteralEntry mapLiteralEntry(Literal key, Expression value) =>
@@ -24,7 +24,7 @@
class AstFactory {
- EmptyExpression empty() => new EmptyExpression();
+ EmptyExpression empty() => const EmptyExpression();
Literal literal(v) => new Literal(v);
@@ -52,12 +52,13 @@
/// Base class for all expressions
abstract class Expression {
+ const Expression();
accept(Visitor v);
}
class EmptyExpression extends Expression {
+ const EmptyExpression();
accept(Visitor v) => v.visitEmptyExpression(this);
- bool operator ==(o) => o is EmptyExpression;
}
class Literal<T> extends Expression {
diff --git a/pkg/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
index 4b28309..b0ceaa3 100644
--- a/pkg/scheduled_test/lib/scheduled_process.dart
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -17,7 +17,9 @@
/// synchronously. All operations on this class are scheduled.
///
/// Before running the test, either [shouldExit] or [kill] must be called on
-/// this to ensure that the process terminates when expected.
+/// this to ensure that the process terminates when expected. Note that [kill]
+/// is using SIGKILL, to ensure the process is killed on Mac OS X (an early
+/// SIGTERM on Mac OS X may be ignored).
///
/// If the test fails, this will automatically print out any stdout and stderr
/// from the process to aid debugging.
@@ -220,7 +222,7 @@
if (!_exitCode.hasValue) {
killedPrematurely = true;
_endExpected = true;
- _process.value.kill();
+ _process.value.kill(ProcessSignal.SIGKILL);
// Ensure that the onException queue waits for the process to actually
// exit after being killed.
wrapFuture(_process.value.exitCode, "waiting for process "
@@ -328,7 +330,9 @@
_taskBeforeEnd = currentSchedule.tasks.contents.last;
schedule(() {
_endExpected = true;
- return _process.then((p) => p.kill()).then((_) => _exitCode);
+ return _process
+ .then((p) => p.kill(ProcessSignal.SIGKILL))
+ .then((_) => _exitCode);
}, "waiting for process '$description' to die");
}
diff --git a/pkg/unittest/lib/html_config.dart b/pkg/unittest/lib/html_config.dart
index e4eba0f..860ec4f 100644
--- a/pkg/unittest/lib/html_config.dart
+++ b/pkg/unittest/lib/html_config.dart
@@ -10,6 +10,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:html';
+import 'dart:js' as js;
import 'unittest.dart';
/** Creates a table showing tests results in HTML. */
@@ -100,7 +101,12 @@
void _installHandlers() {
if (_onErrorSubscription == null) {
_onErrorSubscription = window.onError.listen(
- (e) => handleExternalError(e, '(DOM callback has errors)'));
+ (e) {
+ // Some tests may expect this and have no way to suppress the error.
+ if (js.context['testExpectsGlobalError'] != true) {
+ handleExternalError(e, '(DOM callback has errors)');
+ }
+ });
}
if (_onMessageSubscription == null) {
_onMessageSubscription = window.onMessage.listen(
diff --git a/pkg/unittest/lib/test_controller.js b/pkg/unittest/lib/test_controller.js
index 4862e03..7cf6699 100644
--- a/pkg/unittest/lib/test_controller.js
+++ b/pkg/unittest/lib/test_controller.js
@@ -11,9 +11,20 @@
if (typeof console == "object" && typeof console.clear == "function") {
console.clear();
}
+
+// Some tests may expect and have no way to suppress global errors.
+var testExpectsGlobalError = false;
+var testSuppressedGlobalErrors = [];
+
// Set window onerror to make sure that we catch test harness errors across all
// browsers.
window.onerror = function (message, url, lineNumber) {
+ if (testExpectsGlobalError) {
+ testSuppressedGlobalErrors.push({
+ message: message
+ });
+ return;
+ }
if (url) {
showErrorAndExit(
"\n\n" + url + ":" + lineNumber + ":\n" + message + "\n\n");
@@ -67,7 +78,7 @@
// TODO(ricow): REMOVE, debug info, see issue 13292
if (!testRunner) {
- dartPrint('Calling notifyDone()');
+ printMessage('Calling notifyDone()');
}
// To support in browser launching of tests we post back start and result
// messages to the window.opener.
@@ -80,7 +91,7 @@
function processMessage(msg) {
// TODO(ricow): REMOVE, debug info, see issue 13292
if (!testRunner) {
- dartPrint('processMessage(): ' + msg);
+ printMessage('processMessage(): ' + msg);
}
if (typeof msg != 'string') return;
if (msg == 'unittest-suite-done') {
@@ -95,7 +106,7 @@
window.postMessage('unittest-suite-success', '*');
}
} else if (msg == 'unittest-suite-success') {
- dartPrint('PASS');
+ printMessage('PASS');
notifyDone();
} else if (msg == 'unittest-suite-fail') {
showErrorAndExit('Some tests failed.');
@@ -114,11 +125,11 @@
function showErrorAndExit(message) {
if (message) {
- dartPrint('Error: ' + String(message));
+ printMessage('Error: ' + String(message));
}
// dart/tools/testing/run_selenium.py is looking for either PASS or
// FAIL and will continue polling until one of these words show up.
- dartPrint('FAIL');
+ printMessage('FAIL');
notifyDone();
}
@@ -158,27 +169,50 @@
});
// dart2js will generate code to call this function to handle the Dart
-// [print] method. The base [Configuration] (config.html) calls
-// [print] with the secret messages "unittest-suite-success" and
-// "unittest-suite-wait-for-done". These messages are then posted so
-// processMessage above will see them.
+// [print] method.
+//
+// dartium will invoke this method for [print] calls if the environment variable
+// "DART_FORWARDING_PRINT" was set when launching dartium.
+//
+// Our tests will be wrapped, so we can detect when [main] is called and when
+// it has ended.
+// The wrapping happens either via "dartMainRunner" (for dart2js) or wrapped
+// tests for dartium.
+//
+// The following messages are handled specially:
+// dart-calling-main: signals that the dart [main] function will be invoked
+// dart-main-done: signals that the dart [main] function has finished
+// unittest-suite-wait-for-done: signals the start of an asynchronous test
+// unittest-suite-success: signals the end of an asynchrounous test
+//
+// These messages are used to communicate with the test and will be posted so
+// [processMessage] above can see it.
function dartPrint(msg) {
if ((msg === 'unittest-suite-success')
|| (msg === 'unittest-suite-done')
- || (msg === 'unittest-suite-wait-for-done')) {
+ || (msg === 'unittest-suite-wait-for-done')
+ || (msg === 'dart-calling-main')
+ || (msg === 'dart-main-done')) {
window.postMessage(msg, '*');
return;
}
+ printMessage(msg);
+}
+
+// Prints 'msg' to the console (if available) and to the body of the html
+// document.
+function printMessage(msg) {
if (typeof console === 'object') console.warn(msg);
- var pre = document.createElement("pre");
+ var pre = document.createElement('pre');
pre.appendChild(document.createTextNode(String(msg)));
document.body.appendChild(pre);
+ document.body.appendChild(document.createTextNode('\n'));
}
// dart2js will generate code to call this function instead of calling
// Dart [main] directly. The argument is a closure that invokes main.
function dartMainRunner(main) {
- window.postMessage('dart-calling-main', '*');
+ dartPrint('dart-calling-main');
try {
main();
} catch (e) {
@@ -187,5 +221,5 @@
window.postMessage('unittest-suite-fail', '*');
return;
}
- window.postMessage('dart-main-done', '*');
+ dartPrint('dart-main-done');
}
diff --git a/pkg/unittest/lib/vm_config.dart b/pkg/unittest/lib/vm_config.dart
index 962ca97..e37cf72 100644
--- a/pkg/unittest/lib/vm_config.dart
+++ b/pkg/unittest/lib/vm_config.dart
@@ -21,8 +21,9 @@
// We make this public so the user can turn it off if they want.
bool useColor;
- VMConfiguration() :
- super(), useColor = stdioType(stdout) == StdioType.TERMINAL;
+ VMConfiguration()
+ : super(),
+ useColor = stdioType(stdout) == StdioType.TERMINAL;
String formatResult(TestCase testCase) {
String result = super.formatResult(testCase);
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index 182f2ff..2486c5b 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -35,7 +35,7 @@
Dart_Handle patch_file_uri = DartUtils::NewString(patch_filename);
free(patch_filename);
- DART_CHECK_VALID(Dart_LoadPatch(library, patch_file_uri, patch_src));
+ DART_CHECK_VALID(Dart_LibraryLoadPatch(library, patch_file_uri, patch_src));
}
}
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 07cc545..48c10fb 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -13,6 +13,7 @@
#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/io_natives.h"
+#include "bin/platform.h"
namespace dart {
namespace bin {
@@ -26,7 +27,7 @@
V(Directory_Create, 1) \
V(Directory_Current, 0) \
V(Directory_SetCurrent, 1) \
- V(Directory_CreateTemp, 1) \
+ V(Directory_CreateTemp, 2) \
V(Directory_Delete, 2) \
V(Directory_Rename, 2) \
V(Directory_List, 3) \
@@ -108,12 +109,10 @@
// an isolate gets interrupted by the embedder in the middle of
// Dart_StringToUTF8? We need to make sure not to swallow the
// interrupt.
- fputs(Dart_GetError(result), stdout);
+ Platform::PrintBlocking(stdout, "%s\n", Dart_GetError(result));
} else {
- fwrite(chars, sizeof(*chars), length, stdout);
+ Platform::PrintBlocking(stdout, "%.*s\n", static_cast<int>(length), chars);
}
- fputc('\n', stdout);
- fflush(stdout);
}
} // namespace bin
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 323b4a9..6aa4d09 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -78,7 +78,14 @@
void FUNCTION_NAME(Directory_CreateTemp)(Dart_NativeArguments args) {
Dart_Handle path = Dart_GetNativeArgument(args, 0);
- char* result = Directory::CreateTemp(DartUtils::GetStringValue(path));
+ Dart_Handle system = Dart_GetNativeArgument(args, 1);
+ if (!Dart_IsString(path)) {
+ Dart_SetReturnValue(args, DartUtils::NewDartArgumentError(
+ "Template argument of CreateSystemTempSync is not a String"));
+ return;
+ }
+ char* result = Directory::CreateTemp(DartUtils::GetStringValue(path),
+ DartUtils::GetBooleanValue(system));
if (result != NULL) {
Dart_SetReturnValue(args, DartUtils::NewString(result));
free(result);
@@ -188,7 +195,7 @@
CObject* Directory::CreateTempRequest(const CObjectArray& request) {
if (request.Length() == 1 && request[0]->IsString()) {
CObjectString path(request[0]);
- char* result = Directory::CreateTemp(path.CString());
+ char* result = Directory::CreateTemp(path.CString(), false);
if (result != NULL) {
CObject* temp_dir = new CObjectString(CObject::NewString(result));
free(result);
@@ -200,6 +207,23 @@
return CObject::IllegalArgumentError();
}
+
+CObject* Directory::CreateSystemTempRequest(const CObjectArray& request) {
+ if (request.Length() == 1 && request[0]->IsString()) {
+ CObjectString path(request[0]);
+ char* result = Directory::CreateTemp(path.CString(), true);
+ if (result != NULL) {
+ CObject* temp_dir = new CObjectString(CObject::NewString(result));
+ free(result);
+ return temp_dir;
+ } else {
+ return CObject::NewOSError();
+ }
+ }
+ return CObject::IllegalArgumentError();
+}
+
+
static CObject* CreateIllegalArgumentError() {
// Respond with an illegal argument list error message.
CObjectArray* error = new CObjectArray(CObject::NewArray(3));
@@ -210,6 +234,7 @@
return error;
}
+
CObject* Directory::ListStartRequest(const CObjectArray& request) {
if (request.Length() == 3 &&
request[0]->IsString() &&
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index 210739e..57302a2 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -252,25 +252,12 @@
DOES_NOT_EXIST
};
- // This enum must be kept in sync with the request values in
- // directory_impl.dart.
- enum DirectoryRequest {
- kCreateRequest = 0,
- kDeleteRequest = 1,
- kExistsRequest = 2,
- kCreateTempRequest = 3,
- kListStartRequest = 4,
- kListNextRequest = 5,
- kListStopRequest = 6,
- kRenameRequest = 7
- };
-
static void List(DirectoryListing* listing);
static ExistsResult Exists(const char* path);
static char* Current();
static bool SetCurrent(const char* path);
static bool Create(const char* path);
- static char* CreateTemp(const char* const_template);
+ static char* CreateTemp(const char* const_template, bool system);
static bool Delete(const char* path, bool recursive);
static bool Rename(const char* path, const char* new_path);
@@ -278,6 +265,7 @@
static CObject* DeleteRequest(const CObjectArray& request);
static CObject* ExistsRequest(const CObjectArray& request);
static CObject* CreateTempRequest(const CObjectArray& request);
+ static CObject* CreateSystemTempRequest(const CObjectArray& request);
static CObject* ListStartRequest(const CObjectArray& request);
static CObject* ListNextRequest(const CObjectArray& request);
static CObject* ListStopRequest(const CObjectArray& request);
diff --git a/runtime/bin/directory_android.cc b/runtime/bin/directory_android.cc
index b48474d..6a2646a 100644
--- a/runtime/bin/directory_android.cc
+++ b/runtime/bin/directory_android.cc
@@ -382,33 +382,34 @@
}
-char* Directory::CreateTemp(const char* const_template) {
+char* Directory::CreateTemp(const char* const_template, bool system) {
// Returns a new, unused directory name, modifying the contents of
// dir_template. Creates the directory with the permissions specified
// by the process umask.
// The return value must be freed by the caller.
PathBuffer path;
- path.Add(const_template);
- if (path.length() == 0) {
+ if (system) {
// Android does not have a /tmp directory. A partial substitute,
// suitable for bring-up work and tests, is to create a tmp
// directory in /data/local/tmp.
//
// TODO(4413): In the long run, when running in an application we should
- // probably use android.content.Context.getCacheDir().
+ // probably use the appropriate directory from the Android API,
+ // probably what File.createTempFile uses.
#define ANDROID_TEMP_DIR "/data/local/tmp"
struct stat st;
if (stat(ANDROID_TEMP_DIR, &st) != 0) {
mkdir(ANDROID_TEMP_DIR, 0777);
}
- path.Add(ANDROID_TEMP_DIR "/temp_dir1_");
- } else if ((path.AsString())[path.length() - 1] == '/') {
- path.Add("temp_dir_");
+ path.Add(ANDROID_TEMP_DIR "/");
}
+
+ path.Add(const_template);
if (!path.Add("XXXXXX")) {
// Pattern has overflowed.
return NULL;
}
+
char* result;
do {
result = MakeTempDirectory(path.AsString());
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc
index 88c6f7c..e12dbfd 100644
--- a/runtime/bin/directory_linux.cc
+++ b/runtime/bin/directory_linux.cc
@@ -9,6 +9,7 @@
#include <dirent.h> // NOLINT
#include <errno.h> // NOLINT
+#include <stdlib.h> // NOLINT
#include <string.h> // NOLINT
#include <sys/param.h> // NOLINT
#include <sys/stat.h> // NOLINT
@@ -372,18 +373,27 @@
}
-char* Directory::CreateTemp(const char* const_template) {
+char* Directory::CreateTemp(const char* const_template, bool system) {
// Returns a new, unused directory name, modifying the contents of
// dir_template. Creates the directory with the permissions specified
// by the process umask.
// The return value must be freed by the caller.
PathBuffer path;
- path.Add(const_template);
- if (path.length() == 0) {
- path.Add("/tmp/temp_dir1_");
- } else if ((path.AsString())[path.length() - 1] == '/') {
- path.Add("temp_dir_");
+ if (system) {
+ const char* temp_dir = getenv("TMPDIR");
+ if (temp_dir == NULL) {
+ temp_dir = getenv("TMP");
+ }
+ if (temp_dir != NULL) {
+ path.Add(temp_dir);
+ if (temp_dir[strlen(temp_dir) - 1] != '/') {
+ path.Add("/");
+ }
+ } else {
+ path.Add("/tmp/");
+ }
}
+ path.Add(const_template);
if (!path.Add("XXXXXX")) {
// Pattern has overflowed.
return NULL;
diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc
index 08232d5..5757a9c 100644
--- a/runtime/bin/directory_macos.cc
+++ b/runtime/bin/directory_macos.cc
@@ -361,18 +361,27 @@
}
-char* Directory::CreateTemp(const char* const_template) {
+char* Directory::CreateTemp(const char* const_template, bool system) {
// Returns a new, unused directory name, modifying the contents of
// dir_template. Creates the directory with the permissions specified
// by the process umask.
// The return value must be freed by the caller.
PathBuffer path;
- path.Add(const_template);
- if (path.length() == 0) {
- path.Add("/tmp/temp_dir1_");
- } else if ((path.AsString())[path.length() - 1] == '/') {
- path.Add("temp_dir_");
+ if (system) {
+ const char* temp_dir = getenv("TMPDIR");
+ if (temp_dir == NULL) {
+ temp_dir = getenv("TMP");
+ }
+ if (temp_dir != NULL) {
+ path.Add(temp_dir);
+ if (temp_dir[strlen(temp_dir) - 1] != '/') {
+ path.Add("/");
+ }
+ } else {
+ path.Add("/tmp/");
+ }
}
+ path.Add(const_template);
if (!path.Add("XXXXXX")) {
// Pattern has overflowed.
return NULL;
diff --git a/runtime/bin/directory_patch.dart b/runtime/bin/directory_patch.dart
index da4e014..f5961b9 100644
--- a/runtime/bin/directory_patch.dart
+++ b/runtime/bin/directory_patch.dart
@@ -5,7 +5,8 @@
patch class _Directory {
/* patch */ static _current() native "Directory_Current";
/* patch */ static _setCurrent(path) native "Directory_SetCurrent";
- /* patch */ static _createTemp(String template) native "Directory_CreateTemp";
+ /* patch */ static _createTemp(String template, bool system)
+ native "Directory_CreateTemp";
/* patch */ static int _exists(String path) native "Directory_Exists";
/* patch */ static _create(String path) native "Directory_Create";
/* patch */ static _deleteNative(String path, bool recursive)
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index f5f77bd..c72f4ef 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -383,30 +383,26 @@
}
-char* Directory::CreateTemp(const char* const_template) {
+char* Directory::CreateTemp(const char* const_template, bool system) {
// Returns a new, unused directory name, modifying the contents of
// dir_template. Creates this directory, with a default security
// descriptor inherited from its parent directory.
// The return value must be freed by the caller.
PathBuffer path;
- if (0 == strncmp(const_template, "", 1)) {
+ if (system) {
path.Reset(GetTempPathW(MAX_PATH, path.AsStringW()));
if (path.length() == 0) {
return NULL;
}
- } else {
- const wchar_t* system_template = StringUtils::Utf8ToWide(const_template);
- path.AddW(system_template);
- free(const_cast<wchar_t*>(system_template));
}
- // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44.
- if (path.length() > MAX_PATH - 44) {
+ const wchar_t* system_template = StringUtils::Utf8ToWide(const_template);
+ path.AddW(system_template);
+ free(const_cast<wchar_t*>(system_template));
+
+ // Length of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36.
+ if (path.length() > MAX_PATH - 36) {
return NULL;
}
- if ((path.AsStringW())[path.length() - 1] == L'\\') {
- // No base name for the directory - use "tempdir".
- path.AddW(L"tempdir");
- }
UUID uuid;
RPC_STATUS status = UuidCreateSequential(&uuid);
@@ -419,7 +415,6 @@
return NULL;
}
- path.AddW(L"-");
// RPC_WSTR is an unsigned short*, so we cast to wchar_t*.
path.AddW(reinterpret_cast<wchar_t*>(uuid_string));
RpcStringFreeW(&uuid_string);
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 59b2207..51e98ac 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -7,7 +7,6 @@
#include "bin/eventhandler.h"
-#include <process.h> // NOLINT
#include <winsock2.h> // NOLINT
#include <ws2tcpip.h> // NOLINT
#include <mswsock.h> // NOLINT
@@ -19,7 +18,7 @@
#include "bin/log.h"
#include "bin/socket.h"
#include "bin/utils.h"
-#include "platform/thread.h"
+#include "vm/thread.h"
namespace dart {
@@ -107,7 +106,6 @@
pending_read_(NULL),
pending_write_(NULL),
last_error_(NOERROR),
- thread_wrote_(0),
flags_(0) {
InitializeCriticalSection(&cs_);
}
@@ -123,7 +121,6 @@
pending_read_(NULL),
pending_write_(NULL),
last_error_(NOERROR),
- thread_wrote_(0),
flags_(0) {
InitializeCriticalSection(&cs_);
}
@@ -211,10 +208,9 @@
}
-static unsigned int __stdcall ReadFileThread(void* args) {
+static void ReadFileThread(uword args) {
Handle* handle = reinterpret_cast<Handle*>(args);
handle->ReadSyncCompleteAsync();
- return 0;
}
@@ -273,11 +269,10 @@
} else {
// Completing asynchronously through thread.
pending_read_ = buffer;
- uint32_t tid;
- uintptr_t thread_handle =
- _beginthreadex(NULL, 32 * 1024, ReadFileThread, this, 0, &tid);
- if (thread_handle == -1) {
- FATAL("Failed to start read file thread");
+ int result = dart::Thread::Start(ReadFileThread,
+ reinterpret_cast<uword>(this));
+ if (result != 0) {
+ FATAL1("Failed to start read file thread %d", result);
}
return true;
}
@@ -333,18 +328,6 @@
}
-void FileHandle::DoClose() {
- if (handle_ == GetStdHandle(STD_OUTPUT_HANDLE)) {
- int fd = _open("NUL", _O_WRONLY);
- ASSERT(fd >= 0);
- _dup2(fd, _fileno(stdout));
- close(fd);
- } else {
- Handle::DoClose();
- }
-}
-
-
void DirectoryWatchHandle::EnsureInitialized(
EventHandlerImplementation* event_handler) {
ScopedLock lock(this);
@@ -560,14 +543,46 @@
}
-static unsigned int __stdcall WriteFileThread(void* args) {
- Handle* handle = reinterpret_cast<Handle*>(args);
- handle->WriteSyncCompleteAsync();
- return 0;
+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;
+ ASSERT(SupportsOverlappedIO());
+ if (completion_port_ == INVALID_HANDLE_VALUE) return 0;
+ pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
+ pending_write_->Write(buffer, num_bytes);
+ if (!IssueWrite()) return -1;
+ return num_bytes;
}
-void Handle::WriteSyncCompleteAsync() {
+static void WriteFileThread(uword args) {
+ StdHandle* handle = reinterpret_cast<StdHandle*>(args);
+ handle->RunWriteLoop();
+}
+
+
+void StdHandle::RunWriteLoop() {
+ write_monitor_->Enter();
+ write_thread_running_ = true;
+ // Notify we have started.
+ write_monitor_->Notify();
+
+ while (write_thread_running_) {
+ write_monitor_->Wait(Monitor::kNoTimeout);
+ if (pending_write_ != NULL) {
+ // We woke up and had a pending write. Execute it.
+ WriteSyncCompleteAsync();
+ }
+ }
+
+ write_thread_exists_ = false;
+ write_monitor_->Notify();
+ write_monitor_->Exit();
+}
+
+
+void StdHandle::WriteSyncCompleteAsync() {
ASSERT(pending_write_ != NULL);
DWORD bytes_written = -1;
@@ -593,39 +608,57 @@
}
}
-
-int Handle::Write(const void* buffer, int num_bytes) {
+int StdHandle::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 (completion_port_ == INVALID_HANDLE_VALUE) return 0;
- pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
- pending_write_->Write(buffer, num_bytes);
- if (!IssueWrite()) return -1;
+ // In the case of stdout and stderr, OverlappedIO is not supported.
+ // Here we'll instead use a thread, 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.
+ MonitorLocker locker(write_monitor_);
+ if (thread_wrote_ > 0) {
+ if (num_bytes > thread_wrote_) num_bytes = thread_wrote_;
+ thread_wrote_ -= num_bytes;
return num_bytes;
+ }
+ if (!write_thread_exists_) {
+ write_thread_exists_ = true;
+ int result = dart::Thread::Start(WriteFileThread,
+ reinterpret_cast<uword>(this));
+ if (result != 0) {
+ FATAL1("Failed to start write file thread %d", result);
+ }
+ while (!write_thread_running_) {
+ // Wait until we the thread is running.
+ locker.Wait(Monitor::kNoTimeout);
+ }
+ }
+ // Create buffer and notify thread about the new handle.
+ pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
+ pending_write_->Write(buffer, num_bytes);
+ locker.Notify();
+ return 0;
+}
+
+
+void StdHandle::DoClose() {
+ MonitorLocker locker(write_monitor_);
+ if (write_thread_exists_) {
+ write_thread_running_ = false;
+ locker.Notify();
+ while (write_thread_exists_) {
+ locker.Wait(Monitor::kNoTimeout);
+ }
+ }
+ if (handle_ == GetStdHandle(STD_OUTPUT_HANDLE)) {
+ int fd = _open("NUL", _O_WRONLY);
+ ASSERT(fd >= 0);
+ _dup2(fd, _fileno(stdout));
+ close(fd);
} else {
- // 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;
- }
- 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;
+ Handle::DoClose();
}
}
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 945277b..43562cd 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -13,6 +13,7 @@
#include <mswsock.h>
#include "bin/builtin.h"
+#include "platform/thread.h"
namespace dart {
@@ -132,6 +133,7 @@
public:
enum Type {
kFile,
+ kStd,
kDirectoryWatch,
kClientSocket,
kListenSocket
@@ -156,7 +158,7 @@
// Socket interface exposing normal socket operations.
int Available();
int Read(void* buffer, int num_bytes);
- int Write(const void* buffer, int num_bytes);
+ virtual int Write(const void* buffer, int num_bytes);
// Internal interface used by the event handler.
virtual bool IssueRead();
@@ -211,7 +213,6 @@
}
void ReadSyncCompleteAsync();
- void WriteSyncCompleteAsync();
DWORD last_error() { return last_error_; }
void set_last_error(DWORD last_error) { last_error_ = last_error; }
@@ -242,7 +243,6 @@
OverlappedBuffer* pending_write_; // Buffer for pending write
DWORD last_error_;
- DWORD thread_wrote_;
private:
int flags_;
@@ -259,7 +259,35 @@
virtual void EnsureInitialized(EventHandlerImplementation* event_handler);
virtual bool IsClosed();
+};
+
+
+class StdHandle : public FileHandle {
+ public:
+ explicit StdHandle(HANDLE handle)
+ : FileHandle(handle),
+ thread_wrote_(0),
+ write_thread_exists_(false),
+ write_thread_running_(false),
+ write_monitor_(new Monitor()) {
+ type_ = kStd;
+ }
+
+ ~StdHandle() {
+ delete write_monitor_;
+ }
+
virtual void DoClose();
+ virtual int Write(const void* buffer, int num_bytes);
+
+ void WriteSyncCompleteAsync();
+ void RunWriteLoop();
+
+ private:
+ DWORD thread_wrote_;
+ bool write_thread_exists_;
+ bool write_thread_running_;
+ dart::Monitor* write_monitor_;
};
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 6eec87a..41efb4c 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -60,35 +60,6 @@
kOther = 4
};
- enum FileRequest {
- kExistsRequest = 0,
- kCreateRequest = 1,
- kDeleteRequest = 2,
- kRenameRequest = 3,
- kOpenRequest = 4,
- kResolveSymbolicLinksRequest = 5,
- kCloseRequest = 6,
- kPositionRequest = 7,
- kSetPositionRequest = 8,
- kTruncateRequest = 9,
- kLengthRequest = 10,
- kLengthFromPathRequest = 11,
- kLastModifiedRequest = 12,
- kFlushRequest = 13,
- kReadByteRequest = 14,
- kWriteByteRequest = 15,
- kReadRequest = 16,
- kReadIntoRequest = 17,
- kWriteFromRequest = 18,
- kCreateLinkRequest = 19,
- kDeleteLinkRequest = 20,
- kRenameLinkRequest = 21,
- kLinkTargetRequest = 22,
- kTypeRequest = 23,
- kIdenticalRequest = 24,
- kStatRequest = 25
- };
-
enum FileStat {
// These match the constants in FileStat in file_system_entity.dart.
kType = 0,
diff --git a/runtime/bin/file_system_watcher_win.cc b/runtime/bin/file_system_watcher_win.cc
index 014d861..e08c28d 100644
--- a/runtime/bin/file_system_watcher_win.cc
+++ b/runtime/bin/file_system_watcher_win.cc
@@ -49,8 +49,13 @@
}
if (events & kModifyContent) list_events |= FILE_NOTIFY_CHANGE_LAST_WRITE;
- return reinterpret_cast<intptr_t>(
- new DirectoryWatchHandle(dir, list_events, recursive));
+ DirectoryWatchHandle* handle =
+ new DirectoryWatchHandle(dir, list_events, recursive);
+ // Issue a read directly, to be sure events are tracked from now on. This is
+ // okay, since in Dart, we create the socket and start reading immidiately.
+ handle->EnsureInitialized(EventHandler::delegate());
+ handle->IssueRead();
+ return reinterpret_cast<intptr_t>(handle);
}
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 0612f15..9f70743 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -143,8 +143,8 @@
static void WriteSnapshotFile(const uint8_t* buffer, const intptr_t size) {
File* file = File::Open(snapshot_filename, File::kWriteTruncate);
ASSERT(file != NULL);
- for (intptr_t i = 0; i < size; i++) {
- file->WriteByte(buffer[i]);
+ if (!file->WriteFully(buffer, size)) {
+ Log::PrintErr("Error: Failed to write full snapshot.\n\n");
}
delete file;
}
diff --git a/runtime/bin/io_service.h b/runtime/bin/io_service.h
index 0559039..8c1ba9f 100644
--- a/runtime/bin/io_service.h
+++ b/runtime/bin/io_service.h
@@ -12,6 +12,7 @@
namespace dart {
namespace bin {
+// This list must be kept in sync with the list in sdk/lib/io/io_service.dart
#define IO_SERVICE_REQUEST_LIST(V) \
V(File, Exists, 0) \
V(File, Create, 1) \
@@ -46,11 +47,12 @@
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)
+ V(Directory, CreateSystemTemp, 33) \
+ V(Directory, ListStart, 34) \
+ V(Directory, ListNext, 35) \
+ V(Directory, ListStop, 36) \
+ V(Directory, Rename, 37) \
+ V(SSLFilter, ProcessFilter, 38)
#define DECLARE_REQUEST(type, method, id) \
k##type##method##Request = id,
@@ -68,4 +70,3 @@
} // namespace dart
#endif // BIN_IO_SERVICE_H_
-
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index ca723ae3..16be960 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -62,6 +62,9 @@
return argv_;
}
+ static void PrintBlocking(FILE* file, const char* format, ...)
+ PRINTF_ATTRIBUTE(2, 3);
+
private:
static const char* executable_name_;
static const char* package_root_;
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index dfa2e27..445ea01 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -11,6 +11,8 @@
#include <string.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/fdutils.h"
+
namespace dart {
namespace bin {
@@ -64,6 +66,18 @@
delete[] env;
}
+
+void Platform::PrintBlocking(FILE* file, const char* format, ...) {
+ int fd = fileno(file);
+ FDUtils::SetBlocking(fd);
+ va_list args;
+ va_start(args, format);
+ vfprintf(file, format, args);
+ fflush(file);
+ va_end(args);
+ FDUtils::SetNonBlocking(fd);
+}
+
} // namespace bin
} // namespace dart
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index af557af..80aa0af 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -11,6 +11,8 @@
#include <string.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/fdutils.h"
+
namespace dart {
namespace bin {
@@ -64,6 +66,18 @@
delete[] env;
}
+
+void Platform::PrintBlocking(FILE* file, const char* format, ...) {
+ int fd = fileno(file);
+ FDUtils::SetBlocking(fd);
+ va_list args;
+ va_start(args, format);
+ vfprintf(file, format, args);
+ fflush(file);
+ va_end(args);
+ FDUtils::SetNonBlocking(fd);
+}
+
} // namespace bin
} // namespace dart
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 0576c34..5af6c5a 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -12,6 +12,8 @@
#include <string.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/fdutils.h"
+
namespace dart {
namespace bin {
@@ -68,6 +70,18 @@
delete[] env;
}
+
+void Platform::PrintBlocking(FILE* file, const char* format, ...) {
+ int fd = fileno(file);
+ FDUtils::SetBlocking(fd);
+ va_list args;
+ va_start(args, format);
+ vfprintf(file, format, args);
+ fflush(file);
+ va_end(args);
+ FDUtils::SetNonBlocking(fd);
+}
+
} // namespace bin
} // namespace dart
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 85b6694..cd0f0f2 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -64,6 +64,16 @@
delete[] env;
}
+
+void Platform::PrintBlocking(FILE* file, const char* format, ...) {
+ // No need to set blocking, as it's always blocking on Windows.
+ va_list args;
+ va_start(args, format);
+ vfprintf(file, format, args);
+ fflush(file);
+ va_end(args);
+}
+
} // namespace bin
} // namespace dart
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index d6f9b0d..63fc5ef 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -52,7 +52,7 @@
ADDRESS_LAST = ADDRESS_ANY_IP_V6,
};
- explicit SocketAddress(struct sockaddr* sockaddr);
+ explicit SocketAddress(struct sockaddr* sa);
~SocketAddress() {}
@@ -101,9 +101,9 @@
class InterfaceSocketAddress {
public:
- explicit InterfaceSocketAddress(struct sockaddr* sockaddr,
+ explicit InterfaceSocketAddress(struct sockaddr* sa,
const char* interface_name)
- : socket_address_(new SocketAddress(sockaddr)),
+ : socket_address_(new SocketAddress(sa)),
interface_name_(interface_name) {}
~InterfaceSocketAddress() {
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index 18b2bd8..38c1c7f 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -22,26 +22,19 @@
namespace dart {
namespace bin {
-SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
+SocketAddress::SocketAddress(struct sockaddr* sa) {
ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
- RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
- 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);
+ socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa));
+ if (TEMP_FAILURE_RETRY(getnameinfo(sa,
+ salen,
+ as_string_,
+ INET6_ADDRSTRLEN,
+ NULL,
+ 0,
+ NI_NUMERICHOST)) != 0) {
+ as_string_[0] = 0;
}
- if (result == NULL) as_string_[0] = 0;
- memmove(reinterpret_cast<void *>(&addr_),
- sockaddr,
- GetAddrLength(raw));
+ memmove(reinterpret_cast<void *>(&addr_), sa, salen);
}
@@ -157,20 +150,17 @@
Log::PrintErr("Error getpeername: %s\n", error_message);
return false;
}
- const void* src;
- if (raw.ss.ss_family == AF_INET6) {
- src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
- } else {
- src = reinterpret_cast<const void*>(&raw.in.sin_addr);
- }
- if (inet_ntop(raw.ss.ss_family,
- src,
- host,
- INET_ADDRSTRLEN) == NULL) {
+ if (TEMP_FAILURE_RETRY(getnameinfo(&raw.addr,
+ size,
+ host,
+ INET6_ADDRSTRLEN,
+ NULL,
+ 0,
+ NI_NUMERICHOST)) != 0) {
const int kBufferSize = 1024;
char error_message[kBufferSize];
strerror_r(errno, error_message, kBufferSize);
- Log::PrintErr("Error inet_ntop: %s\n", error_message);
+ Log::PrintErr("Error getnameinfo: %s\n", error_message);
return false;
}
*port = SocketAddress::GetAddrPort(&raw);
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 24e688d..b9431e1 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -23,26 +23,19 @@
namespace dart {
namespace bin {
-SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
+SocketAddress::SocketAddress(struct sockaddr* sa) {
ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
- RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
- 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);
+ socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa));
+ if (TEMP_FAILURE_RETRY(getnameinfo(sa,
+ salen,
+ as_string_,
+ INET6_ADDRSTRLEN,
+ NULL,
+ 0,
+ NI_NUMERICHOST)) != 0) {
+ as_string_[0] = 0;
}
- if (result == NULL) as_string_[0] = 0;
- memmove(reinterpret_cast<void *>(&addr_),
- sockaddr,
- GetAddrLength(raw));
+ memmove(reinterpret_cast<void *>(&addr_), sa, salen);
}
@@ -158,19 +151,16 @@
strerror_r(errno, error_buf, kBufferSize));
return false;
}
- const void* src;
- if (raw.ss.ss_family == AF_INET6) {
- src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
- } else {
- src = reinterpret_cast<const void*>(&raw.in.sin_addr);
- }
- if (inet_ntop(raw.ss.ss_family,
- src,
- host,
- INET_ADDRSTRLEN) == NULL) {
+ if (TEMP_FAILURE_RETRY(getnameinfo(&raw.addr,
+ size,
+ host,
+ INET6_ADDRSTRLEN,
+ NULL,
+ 0,
+ NI_NUMERICHOST)) != 0) {
const int kBufferSize = 1024;
char error_buf[kBufferSize];
- Log::PrintErr("Error inet_ntop: %s\n",
+ Log::PrintErr("Error getnameinfo: %s\n",
strerror_r(errno, error_buf, kBufferSize));
return false;
}
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 2b6138f..be7beca 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -23,26 +23,19 @@
namespace dart {
namespace bin {
-SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
+SocketAddress::SocketAddress(struct sockaddr* sa) {
ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
- RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
- 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);
+ socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa));
+ if (TEMP_FAILURE_RETRY(getnameinfo(sa,
+ salen,
+ as_string_,
+ INET6_ADDRSTRLEN,
+ NULL,
+ 0,
+ NI_NUMERICHOST)) != 0) {
+ as_string_[0] = 0;
}
- if (result == NULL) as_string_[0] = 0;
- memmove(reinterpret_cast<void *>(&addr_),
- sockaddr,
- GetAddrLength(raw));
+ memmove(reinterpret_cast<void *>(&addr_), sa, salen);
}
@@ -158,20 +151,17 @@
Log::PrintErr("Error getpeername: %s\n", error_message);
return false;
}
- const void* src;
- if (raw.ss.ss_family == AF_INET6) {
- src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
- } else {
- src = reinterpret_cast<const void*>(&raw.in.sin_addr);
- }
- if (inet_ntop(raw.ss.ss_family,
- src,
- host,
- INET_ADDRSTRLEN) == NULL) {
+ if (TEMP_FAILURE_RETRY(getnameinfo(&raw.addr,
+ size,
+ host,
+ INET6_ADDRSTRLEN,
+ NULL,
+ 0,
+ NI_NUMERICHOST)) != 0) {
const int kBufferSize = 1024;
char error_message[kBufferSize];
strerror_r(errno, error_message, kBufferSize);
- Log::PrintErr("Error inet_ntop: %s\n", error_message);
+ Log::PrintErr("Error getnameinfo: %s\n", error_message);
return false;
}
*port = SocketAddress::GetAddrPort(&raw);
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 0042aed..4fffbf7 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -484,7 +484,9 @@
continue;
}
if (i == ERROR_EVENT) {
- reportError(nativeGetError(), "");
+ if (!isClosing) {
+ reportError(nativeGetError(), "");
+ }
} else if (!isClosed) {
// If the connection is closed right after it's accepted, there's a
// chance the close-handler is not set.
@@ -711,6 +713,8 @@
int get port => _socket.port;
+ InternetAddress get address => _socket.address;
+
Future close() => _socket.close().then((_) => this);
void _pause() {
@@ -921,6 +925,8 @@
int get port => _socket.port;
+ InternetAddress get address => _socket.address;
+
Future close() => _socket.close().then((_) => this);
}
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 87a0b30..a5d55a9 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -198,11 +198,11 @@
if (handle == INVALID_HANDLE_VALUE) {
return -1;
}
- 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);
+ StdHandle* std_handle = new StdHandle(handle);
+ if (std_handle == NULL) return -1;
+ std_handle->MarkDoesNotSupportOverlappedIO();
+ std_handle->EnsureInitialized(EventHandler::delegate());
+ return reinterpret_cast<intptr_t>(std_handle);
}
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index 7c4f4c4..f89950a 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -15,20 +15,9 @@
'version_in_cc_file': 'vm/version_in.cc',
'version_cc_file': '<(gen_source_dir)/version.cc',
- # Disable the OpenGLUI embedder by default on desktop OSes. Note,
- # to build this on the desktop, you need GLUT installed.
- 'enable_openglui%': 0,
'libdart_deps': ['libdart_lib_withcore', 'libdart_lib', 'libdart_vm',
'libjscre', 'libdouble_conversion',],
},
- 'conditions': [
- ['OS=="android" or enable_openglui==1', {
- 'includes': [
- 'embedders/openglui/openglui_embedder.gypi',
- ],
- },
- ],
- ],
'targets': [
{
'target_name': 'libdart',
diff --git a/runtime/embedders/openglui/android/android_graphics_handler.cc b/runtime/embedders/openglui/android/android_graphics_handler.cc
deleted file mode 100644
index f2c0ea2..0000000
--- a/runtime/embedders/openglui/android/android_graphics_handler.cc
+++ /dev/null
@@ -1,87 +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 "embedders/openglui/android/android_graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-
-AndroidGraphicsHandler::AndroidGraphicsHandler(android_app* application,
- const char* resource_path)
- : GraphicsHandler(resource_path),
- application_(application),
- display_(EGL_NO_DISPLAY),
- surface_(EGL_NO_SURFACE),
- context_(EGL_NO_CONTEXT) {
-}
-
-int32_t AndroidGraphicsHandler::Start() {
- EGLint format, numConfigs;
- EGLConfig config;
- const EGLint attributes[] = {
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE
- };
- static const EGLint ctx_attribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
- display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (display_ != EGL_NO_DISPLAY) {
- LOGI("eglInitialize");
- if (eglInitialize(display_, NULL, NULL)) {
- LOGI("eglChooseConfig");
- if (eglChooseConfig(display_, attributes, &config, 1, &numConfigs) &&
- numConfigs > 0) {
- LOGI("eglGetConfigAttrib returned %d configs\n", numConfigs);
- if (eglGetConfigAttrib(display_, config,
- EGL_NATIVE_VISUAL_ID, &format)) {
- ANativeWindow_setBuffersGeometry(application_->window, 0, 0, format);
- surface_ = eglCreateWindowSurface(display_, config,
- (EGLNativeWindowType)application_->window, NULL);
- if (surface_ != EGL_NO_SURFACE) {
- LOGI("eglCreateContext");
- context_ = eglCreateContext(display_, config, EGL_NO_CONTEXT,
- ctx_attribs);
- if (context_ != EGL_NO_CONTEXT) {
- if (eglMakeCurrent(display_, surface_, surface_, context_) &&
- eglQuerySurface(display_, surface_, EGL_WIDTH, &width_) &&
- width_ > 0 &&
- eglQuerySurface(display_, surface_, EGL_HEIGHT, &height_) &&
- height_ > 0) {
- LOGI("Got dimensions %d x %d\n", width_, height_);
- SetViewport(0, 0, width_, height_);
- LOGI("GL version %s\n", glGetString(GL_VERSION));
- LOGI("GLSL version: %s\n",
- glGetString(GL_SHADING_LANGUAGE_VERSION));
- return GraphicsHandler::Start();
- }
- }
- }
- }
- }
- }
- }
- LOGE("Error starting graphics");
- Stop();
- return -1;
-}
-
-void AndroidGraphicsHandler::Stop() {
- LOGI("Stopping graphics");
- GraphicsHandler::Stop();
- if (display_ != EGL_NO_DISPLAY) {
- eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (context_ != EGL_NO_CONTEXT) {
- eglDestroyContext(display_, context_);
- context_ = EGL_NO_CONTEXT;
- }
- if (surface_ != EGL_NO_SURFACE) {
- eglDestroySurface(display_, surface_);
- surface_ = EGL_NO_SURFACE;
- }
- eglTerminate(display_);
- display_ = EGL_NO_DISPLAY;
- }
-}
-
diff --git a/runtime/embedders/openglui/android/android_graphics_handler.h b/runtime/embedders/openglui/android/android_graphics_handler.h
deleted file mode 100644
index c157d95..0000000
--- a/runtime/embedders/openglui/android/android_graphics_handler.h
+++ /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.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_GRAPHICS_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_GRAPHICS_HANDLER_H_
-
-#include <android_native_app_glue.h>
-#include "embedders/openglui/common/graphics_handler.h"
-
-class AndroidGraphicsHandler : public GraphicsHandler {
- public:
- AndroidGraphicsHandler(android_app* application,
- const char* resource_path);
-
- int32_t Start();
- void Stop();
-
- private:
- android_app* application_;
- EGLDisplay display_;
- EGLSurface surface_;
- EGLContext context_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_GRAPHICS_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/android/android_input_handler.h b/runtime/embedders/openglui/android/android_input_handler.h
deleted file mode 100644
index 420e459..0000000
--- a/runtime/embedders/openglui/android/android_input_handler.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_INPUT_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_INPUT_HANDLER_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/input_handler.h"
-
-class AndroidInputHandler : public InputHandler {
- public:
- AndroidInputHandler(VMGlue* vm_glue,
- GraphicsHandler* graphics_handler)
- : InputHandler(vm_glue),
- graphics_handler_(graphics_handler) {
- }
-
- public:
- int32_t Start() {
- if (graphics_handler_->width() == 0 ||
- graphics_handler_->height() == 0) {
- return -1;
- }
- return 0;
- }
-
- void Stop() {
- }
-
- private:
- GraphicsHandler* graphics_handler_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_INPUT_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/android/android_log.h b/runtime/embedders/openglui/android/android_log.h
deleted file mode 100644
index ff82d0b..0000000
--- a/runtime/embedders/openglui/android/android_log.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_LOG_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_LOG_H_
-
-#include <android/log.h>
-
-#define LOGX(LOG_LEVEL, ...) do { \
- __android_log_print(LOG_LEVEL, "DartExt", __VA_ARGS__); \
- } while (0)
-#define LOGI(...) LOGX(ANDROID_LOG_INFO, __VA_ARGS__)
-#define LOGE(...) LOGX(ANDROID_LOG_ERROR, __VA_ARGS__)
-
-#endif // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_LOG_H_
-
diff --git a/runtime/embedders/openglui/android/android_resource.h b/runtime/embedders/openglui/android/android_resource.h
deleted file mode 100644
index 85e0614..0000000
--- a/runtime/embedders/openglui/android/android_resource.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_RESOURCE_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_RESOURCE_H_
-
-#include <android_native_app_glue.h>
-
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/resource.h"
-
-class AndroidResource : public Resource {
- public:
- AndroidResource(android_app* application, const char* path)
- : Resource(path),
- asset_manager_(application->activity->assetManager),
- asset_(NULL) {
- }
-
- int32_t descriptor() {
- if (Open() == 0) {
- descriptor_ = AAsset_openFileDescriptor(asset_, &start_, &length_);
- LOGI("%s has start %d, length %d, fd %d",
- path_, static_cast<int>(start_), static_cast<int>(length_),
- descriptor_);
- return descriptor_;
- }
- return -1;
- }
-
- off_t length() {
- if (length_ < 0) {
- length_ = AAsset_getLength(asset_);
- }
- return length_;
- }
-
- int32_t Open() {
- LOGI("Attempting to open asset %s", path_);
- asset_ = AAssetManager_open(asset_manager_, path_, AASSET_MODE_UNKNOWN);
- if (asset_ != NULL) {
- return 0;
- }
- LOGE("Could not open asset %s", path_);
- return -1;
- }
-
- void Close() {
- if (asset_ != NULL) {
- AAsset_close(asset_);
- asset_ = NULL;
- }
- }
-
- int32_t Read(void* buffer, size_t count) {
- size_t actual = AAsset_read(asset_, buffer, count);
- return (actual == count) ? 0 : -1;
- }
-
- private:
- AAssetManager* asset_manager_;
- AAsset* asset_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_RESOURCE_H_
-
diff --git a/runtime/embedders/openglui/android/android_sound_handler.cc b/runtime/embedders/openglui/android/android_sound_handler.cc
deleted file mode 100644
index de9e977..0000000
--- a/runtime/embedders/openglui/android/android_sound_handler.cc
+++ /dev/null
@@ -1,277 +0,0 @@
-// 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.
-
-#include "embedders/openglui/android/android_sound_handler.h"
-
-#include "embedders/openglui/android/android_resource.h"
-#include "embedders/openglui/common/log.h"
-
-AndroidSoundHandler::AndroidSoundHandler(android_app* application)
- : SoundHandler(),
- application_(application),
- engine_(NULL),
- engine_if_(NULL),
- output_mix_(NULL),
- background_player_(NULL),
- background_player_if_(NULL),
- background_player_seek_if_(NULL),
- sample_player_(NULL),
- sample_player_if_(NULL),
- sample_player_queue_(NULL) {
-}
-
-int32_t AndroidSoundHandler::Start() {
- LOGI("Starting SoundService");
-
- const SLInterfaceID k_engine_mix_IIDs[] = { SL_IID_ENGINE };
- const SLboolean k_engine_mix_reqs[] = { SL_BOOLEAN_TRUE };
- const SLInterfaceID k_output_mix_IIDs[] = {};
- const SLboolean k_output_mix_reqs[] = {};
- int32_t res = slCreateEngine(&engine_, 0, NULL, 1,
- k_engine_mix_IIDs, k_engine_mix_reqs);
- if (res == SL_RESULT_SUCCESS) {
- res = (*engine_)->Realize(engine_, SL_BOOLEAN_FALSE);
- if (res == SL_RESULT_SUCCESS) {
- res = (*engine_)->GetInterface(engine_, SL_IID_ENGINE, &engine_if_);
- if (res == SL_RESULT_SUCCESS) {
- res = (*engine_if_)->CreateOutputMix(engine_if_, &output_mix_, 0,
- k_output_mix_IIDs, k_output_mix_reqs);
- if (res == SL_RESULT_SUCCESS) {
- res = (*output_mix_)->Realize(output_mix_, SL_BOOLEAN_FALSE);
- if (res == SL_RESULT_SUCCESS) {
- if (StartSamplePlayer() == 0) {
- return 0;
- }
- }
- }
- }
- }
- }
- LOGI("Failed to start SoundService");
- Stop();
- return -1;
-}
-
-void AndroidSoundHandler::Stop() {
- LOGI("Stopping SoundService");
- if (sample_player_ != NULL) {
- LOGI("Destroying sample player");
- (*sample_player_)->Destroy(sample_player_);
- sample_player_ = NULL;
- sample_player_if_ = NULL;
- sample_player_queue_ = NULL;
- }
- samples_.clear();
- if (output_mix_ != NULL) {
- LOGI("Destroying output mix");
- (*output_mix_)->Destroy(output_mix_);
- output_mix_ = NULL;
- }
- if (engine_ != NULL) {
- LOGI("Destroying engine");
- (*engine_)->Destroy(engine_);
- engine_ = NULL;
- engine_if_ = NULL;
- }
-}
-
-int32_t AndroidSoundHandler::SetBackgroundPlayerState(int state) {
- if (background_player_if_ != NULL) {
- SLuint32 state;
- (*background_player_)->GetState(background_player_, &state);
- if (state == SL_OBJECT_STATE_REALIZED) {
- (*background_player_if_)->SetPlayState(background_player_if_,
- state);
- return 0;
- }
- }
- return -1;
-}
-
-int32_t AndroidSoundHandler::Pause() {
- return SetBackgroundPlayerState(SL_PLAYSTATE_PAUSED);
-}
-
-
-int32_t AndroidSoundHandler::Resume() {
- return SetBackgroundPlayerState(SL_PLAYSTATE_PLAYING);
-}
-
-int32_t AndroidSoundHandler::CreateAudioPlayer(SLEngineItf engine_if,
- const SLInterfaceID extra_if,
- SLDataSource data_source,
- SLDataSink data_sink,
- SLObjectItf& player_out,
- SLPlayItf& player_if_out) {
- const SLuint32 SoundPlayerIIDCount = 2;
- const SLInterfaceID SoundPlayerIIDs[] = { SL_IID_PLAY, extra_if };
- const SLboolean SoundPlayerReqs[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
- int32_t res = (*engine_if)->CreateAudioPlayer(engine_if,
- &player_out,
- &data_source,
- &data_sink,
- SoundPlayerIIDCount,
- SoundPlayerIIDs,
- SoundPlayerReqs);
-
- if (res == SL_RESULT_SUCCESS) {
- res = (*player_out)->Realize(player_out, SL_BOOLEAN_FALSE);
- if (res == SL_RESULT_SUCCESS) {
- res = (*player_out)->GetInterface(sample_player_,
- SL_IID_PLAY,
- &player_if_out);
- if (res == SL_RESULT_SUCCESS) {
- return 0;
- }
- }
- }
- return -1;
-}
-
-int32_t AndroidSoundHandler::PlayBackground(const char* path) {
- LOGI("Creating audio player");
-
- Resource resource(path);
- int fd = resource.descriptor();
- if (fd < 0) {
- LOGI("Could not open file %s", path);
- return -1;
- }
-
- SLDataLocator_AndroidFD data_locator_in = {
- SL_DATALOCATOR_ANDROIDFD,
- fd,
- resource.start(),
- resource.length()
- };
- SLDataFormat_MIME data_format = {
- SL_DATAFORMAT_MIME,
- NULL,
- SL_CONTAINERTYPE_UNSPECIFIED
- };
- SLDataSource data_source = { &data_locator_in, &data_format };
-
- resource.Close();
-
- SLDataLocator_OutputMix data_locator_out =
- { SL_DATALOCATOR_OUTPUTMIX, output_mix_ };
- SLDataSink data_sink = { &data_locator_out, NULL };
-
- int32_t res = CreateAudioPlayer(engine_if_,
- SL_IID_SEEK,
- data_source,
- data_sink,
- background_player_,
- background_player_if_);
-
- if (res != SL_RESULT_SUCCESS) {
- LOGE("Couldn't create audio player");
- return -1;
- }
-
- if ((*background_player_)->
- GetInterface(background_player_, SL_IID_SEEK,
- &background_player_seek_if_) != SL_RESULT_SUCCESS) {
- LOGE("Couldn't get seek interface");
- return -1;
- }
- LOGI("Got seek interface");
- if ((*background_player_seek_if_)->
- SetLoop(background_player_seek_if_, SL_BOOLEAN_TRUE, 0,
- SL_TIME_UNKNOWN) != SL_RESULT_SUCCESS) {
- LOGE("Couldn't set loop");
- return -1;
- }
- LOGI("Set loop");
- if ((*background_player_if_)->
- SetPlayState(background_player_if_, SL_PLAYSTATE_PLAYING) !=
- SL_RESULT_SUCCESS) {
- LOGE("Couldn't start playing");
- return -1;
- }
- LOGI("Started playing");
- return 0;
-}
-
-void AndroidSoundHandler::StopBackground() {
- if (Pause() == 0) {
- (*background_player_)->Destroy(background_player_);
- background_player_ = NULL;
- background_player_if_ = NULL;
- background_player_seek_if_ = NULL;
- }
-}
-
-int32_t AndroidSoundHandler::StartSamplePlayer() {
- SLDataLocator_AndroidSimpleBufferQueue data_locator_in = {
- SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
- 1
- };
-
- SLDataFormat_PCM data_format= {
- SL_DATAFORMAT_PCM,
- 1,
- SL_SAMPLINGRATE_44_1,
- SL_PCMSAMPLEFORMAT_FIXED_16,
- SL_PCMSAMPLEFORMAT_FIXED_16,
- SL_SPEAKER_FRONT_CENTER,
- SL_BYTEORDER_LITTLEENDIAN
- };
-
- SLDataSource data_source = { &data_locator_in, &data_format };
-
- SLDataLocator_OutputMix data_locator_out =
- { SL_DATALOCATOR_OUTPUTMIX, output_mix_ };
- SLDataSink data_sink = { &data_locator_out, NULL };
-
- int32_t res = CreateAudioPlayer(engine_if_, SL_IID_BUFFERQUEUE,
- data_source,
- data_sink,
- sample_player_, sample_player_if_);
-
- if (res == SL_RESULT_SUCCESS) {
- res = (*sample_player_)->GetInterface(sample_player_,
- SL_IID_BUFFERQUEUE,
- &sample_player_queue_);
- if (res == SL_RESULT_SUCCESS) {
- res = (*sample_player_if_)->SetPlayState(sample_player_if_,
- SL_PLAYSTATE_PLAYING);
- if (res == SL_RESULT_SUCCESS) {
- return 0;
- }
- }
- }
- LOGE("Error while starting sample player");
- return -1;
-}
-
-int32_t AndroidSoundHandler::PlaySample(const char* path) {
- SLuint32 state;
- (*sample_player_)->GetState(sample_player_, &state);
- if (state != SL_OBJECT_STATE_REALIZED) {
- LOGE("Sample player has not been realized");
- } else {
- Sample* sample = GetSample(path);
- if (sample != NULL) {
- int16_t* buffer = reinterpret_cast<int16_t*>(sample->buffer());
- off_t len = sample->length();
-
- // Remove any current sample.
- int32_t res = (*sample_player_queue_)->Clear(sample_player_queue_);
- if (res == SL_RESULT_SUCCESS) {
- res = (*sample_player_queue_)->Enqueue(sample_player_queue_,
- buffer, len);
- if (res == SL_RESULT_SUCCESS) {
- LOGE("Enqueued sample %s of length %d", path,
- static_cast<int>(len));
- return 0;
- }
- LOGE("Enqueueing sample failed");
- }
- }
- }
- return -1;
-}
-
-
diff --git a/runtime/embedders/openglui/android/android_sound_handler.h b/runtime/embedders/openglui/android/android_sound_handler.h
deleted file mode 100644
index e699a69..0000000
--- a/runtime/embedders/openglui/android/android_sound_handler.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_SOUND_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_SOUND_HANDLER_H_
-
-#include <android_native_app_glue.h>
-#include <SLES/OpenSLES.h>
-#include <SLES/OpenSLES_Android.h>
-#include <SLES/OpenSLES_AndroidConfiguration.h>
-#include <vector>
-
-#include "embedders/openglui/common/sample.h"
-#include "embedders/openglui/common/sound_handler.h"
-#include "embedders/openglui/common/types.h"
-
-class AndroidSoundHandler : public SoundHandler {
- public:
- explicit AndroidSoundHandler(android_app* application);
- int32_t Start();
- void Stop();
- int32_t Pause();
- int32_t Resume();
-
- int32_t PlayBackground(const char* path);
- void StopBackground();
-
- int32_t PlaySample(const char* path);
-
- private:
- int32_t CreateAudioPlayer(SLEngineItf engine_if,
- const SLInterfaceID extra_if,
- SLDataSource data_source,
- SLDataSink data_sink,
- SLObjectItf& player_out,
- SLPlayItf& player_if_out);
-
- int32_t SetBackgroundPlayerState(int state);
- int32_t StartSamplePlayer();
-
- android_app* application_;
- SLObjectItf engine_;
- SLEngineItf engine_if_;
- SLObjectItf output_mix_;
- SLObjectItf background_player_;
- SLPlayItf background_player_if_;
- SLSeekItf background_player_seek_if_;
- SLObjectItf sample_player_;
- SLPlayItf sample_player_if_;
- SLBufferQueueItf sample_player_queue_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_SOUND_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/android/eventloop.cc b/runtime/embedders/openglui/android/eventloop.cc
deleted file mode 100644
index ed1645e..0000000
--- a/runtime/embedders/openglui/android/eventloop.cc
+++ /dev/null
@@ -1,464 +0,0 @@
-// 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.
-
-#include "embedders/openglui/android/eventloop.h"
-
-#include <time.h>
-#include "embedders/openglui/common/log.h"
-
-/*
- * The Android lifecycle events are:
- *
- * OnCreate: In NDK this is the call to android_main
- *
- * OnStart: technically, called to initiate the “visible” lifespan of the
- * app; at any time between OnStart and OnStop, the app may be visible.
- * We can either be OnResume’d or OnStop’ped from this state. Note that
- * there is also an event for OnRestart, which is called before OnStart
- * if the application is transitioning from OnStop to OnStart instead of
- * being started from scratch.
- *
- * OnResume: technically, the start of the “foreground” lifespan of the app,
- * but this does not mean that the app is fully visible and should be
- * rendering – more on that later
- *
- * OnPause: the app is losing its foregrounded state; this is normally an
- * indication that something is fully covering the app. On versions of
- * Android before Honeycomb, once we returned from this callback, we
- * could be killed at any time with no further app code called. We can
- * either be OnResume’d or OnStop’ped from this state. OnPause halts the
- * visible UI thread and so should be handled as quickly as possible.
- *
- * OnStop: the end of the current visible lifespan of the app – we may
- * transition to On(Re)Start to become visible again, or to OnDestroy if
- * we are shutting down entirely. Once we return from this callback, we
- * can be killed at any time with no further app code called on any
- * version of Android.
- *
- * OnDestroy: this can only be followed by the application being killed or
- * restarted with OnCreate.
- *
- * The above events occur in fixed orders. The events below can occur at
- * various times:
- *
- * OnGainedFocus: happens between OnResume and OnPause.
- * OnLostFocus: may occur at arbitrary times, and may in fact not happen
- * at all if the app is being destroyed. So OnPause and OnGainedFocus/
- * OnLostFocus must be used together to determine the visible and
- * interactable state of the app.
- *
- * OnCreateWindow: usually happens in the resumed state
- * OnDestroyWindow: can happen after OnPause or OnDestroy, so apps may
- * need to handle shutting down EGL before their surfaces are
- * destroyed.
- * OnConfigurationChanged: typically means the size has changed
- *
- * An application's EGL surface may only exist between the OnCreateWindow
- * and OnDestroyWindow callbacks.
- *
- * An application is "killable" after OnStop or OnDestroy (in earlier
- * Android versions, after OnPause too). That means any critical state
- * or resources must be handled by any of these callbacks.
- *
- * These callbacks run on the main thread. If they block any event
- * processing for more than 5 seconds this will result in an ANR
- * (Application Not Responding message).
- *
- * On application launch, this sequence will occur:
- *
- * - OnCreate
- * - OnStart
- * - OnResume
- * - OnCreateWindow
- * - OnConfigurationChanged
- * - OnGainedFocus
- *
- * If the back button is pressed, and the app does not handle it,
- * Android will pop the app of the UI stack and destroy the application's
- * activity:
- *
- * - OnPause
- * - OnLostFocus
- * - OnDestroyWindow
- * - OnStop
- * - OnDestroy
- *
- * If the home button is pressed, the app is sent down in the UI stack.
- * The app's Activity still exists but may be killed at any time, and
- * it loses its rendering surface:
- *
- * - OnPause
- * - OnLostFocus
- * - OnDestroyWindow
- * - OnStop
- *
- * If the app is then restarted (without having been killed in between):
- *
- * - OnRestart
- * - OnStart
- * - OnResume
- * - OnCreateWindow
- * - OnConfigurationChanged
- * - OnGainedFocus
- *
- * If a status icon pop up is opened, the app is still visible and can render
- * but is not focused and cannot receive input:
- *
- * - OnLostFocus
- *
- * When the popup is dismissed, the app regains focus:
- *
- * - OnGainedFocus
- *
- * When the device is suspended (power button or screen saver), the application
- * will typically be paused and lose focus:
- *
- * - OnPause
- * - OnLostFocus (sometimes this will only come when the device is resumed
- * to the lock screen)
- *
- * The application should have stopped all rendering and sound and any
- * non-critical background processing.
- *
- * When the device is resumed but not yet unlocked, the app will be resumed:
- *
- * - OnResume
- *
- * The application should not perform sound or graphics yet. If the lock
- * screen times out, the app will be paused again. If the screen is
- * unlocked, the app will regain focus.
- *
- * Turning all of this into a general framework, we can use the following:
- *
- * 1. In OnCreate/android_main, set up the main classes and possibly
- * load some lightweight resources.
- * 2. In OnCreateWindow, create the EGLSurface, bind the context, load
- * OpenGL resources. No rendering.
- * 3. When we are between OnResume and OnPause, and between OnCreateWindow
- * and OnDestroyWindow, and between OnGainedFocus and OnLostFocus,
- * we can render and process input.
- * 4. In OnLostFocus, stop sounds from playing, and stop rendering.
- * 5. In OnPause, stop all rendering
- * 6. In OnResume, prepare to start rendering again, but don't render.
- * 7. In OnGainedFocus after OnResume, start rendering and sound again.
- * 8. In OnStop, free all graphic resources, either through GLES calls
- * if the EGLContext is still bound, or via eglDestroyContext if the
- * context has been unbound because the rendering surface was destroyed.
- * 9. In OnDestroy, release all other resources.
- */
-EventLoop::EventLoop(android_app* application)
- : enabled_(false),
- quit_(false),
- isResumed_(false),
- hasSurface_(false),
- hasFocus_(false),
- application_(application),
- lifecycle_handler_(NULL),
- input_handler_(NULL),
- sensor_manager_(NULL),
- sensor_event_queue_(NULL),
- sensor_poll_source_() {
- application_->onAppCmd = ActivityCallback;
- application_->onInputEvent = InputCallback;
- application_->userData = this;
-}
-
-static int64_t getTimeInMillis() {
- struct timespec res;
- clock_gettime(CLOCK_REALTIME, &res);
- return 1000 * res.tv_sec + res.tv_nsec / 1000000;
-}
-
-void EventLoop::Run(LifeCycleHandler* lifecycle_handler,
- InputHandler* input_handler) {
- int32_t result;
- int32_t events;
- android_poll_source* source;
-
- lifecycle_handler_ = lifecycle_handler;
- input_handler_ = input_handler;
- int64_t last_frame_time = getTimeInMillis();
- if (lifecycle_handler_->OnStart() == 0) {
- LOGI("Starting event loop");
- while (!quit_) {
- // If not enabled, block indefinitely on events. If enabled, block
- // briefly so we can do useful work in onStep, but only long
- // enough that we can still do work at 60fps if possible.
- int64_t next_frame_time = last_frame_time + (1000/60);
- int64_t next_frame_delay = next_frame_time - getTimeInMillis();
- if (next_frame_delay < 0) next_frame_delay = 0;
- while ((result = ALooper_pollAll(enabled_ ? next_frame_delay : -1, NULL,
- &events, reinterpret_cast<void**>(&source))) >= 0) {
- if (source != NULL) {
- source->process(application_, source);
- }
- if (application_->destroyRequested) {
- return;
- }
- }
- if (enabled_ && !quit_) {
- int64_t now = getTimeInMillis();
- if (now >= next_frame_time) {
- LOGI("step");
- last_frame_time = now;
- if (lifecycle_handler_->OnStep() != 0) {
- quit_ = true;
- }
- }
- }
- }
- }
- ANativeActivity_finish(application_->activity);
-}
-
-void EventLoop::EnableSensorEvents() {
- sensor_poll_source_.id = LOOPER_ID_USER;
- sensor_poll_source_.app = application_;
- sensor_poll_source_.process = SensorCallback;
- sensor_manager_ = ASensorManager_getInstance();
- if (sensor_manager_ != NULL) {
- sensor_event_queue_ = ASensorManager_createEventQueue(
- sensor_manager_, application_->looper,
- LOOPER_ID_USER, NULL, &sensor_poll_source_);
-
- sensor_ = ASensorManager_getDefaultSensor(sensor_manager_,
- ASENSOR_TYPE_ACCELEROMETER);
- if (sensor_ != NULL) {
- int32_t min_delay = ASensor_getMinDelay(sensor_);
- if (ASensorEventQueue_enableSensor(sensor_event_queue_, sensor_) < 0 ||
- ASensorEventQueue_setEventRate(sensor_event_queue_, sensor_,
- min_delay) < 0) {
- LOGE("Error while activating sensor.");
- DisableSensorEvents();
- return;
- }
- LOGI("Activating sensor:");
- LOGI("Name : %s", ASensor_getName(sensor_));
- LOGI("Vendor : %s", ASensor_getVendor(sensor_));
- LOGI("Resolution : %f", ASensor_getResolution(sensor_));
- LOGI("Min Delay : %d", min_delay);
- } else {
- LOGI("No sensor");
- }
- }
-}
-
-void EventLoop::DisableSensorEvents() {
- if (sensor_ != NULL) {
- if (ASensorEventQueue_disableSensor(sensor_event_queue_, sensor_) < 0) {
- LOGE("Error while deactivating sensor.");
- }
- sensor_ = NULL;
- }
- if (sensor_event_queue_ != NULL) {
- ASensorManager_destroyEventQueue(sensor_manager_,
- sensor_event_queue_);
- sensor_event_queue_ = NULL;
- }
- sensor_manager_ = NULL;
-}
-
-void EventLoop::ProcessActivityEvent(int32_t command) {
- switch (command) {
- case APP_CMD_INIT_WINDOW:
- if (lifecycle_handler_->Activate() != 0) {
- quit_ = true;
- } else {
- hasSurface_ = true;
- }
- break;
- case APP_CMD_CONFIG_CHANGED:
- lifecycle_handler_->OnConfigurationChanged();
- break;
- case APP_CMD_DESTROY:
- hasFocus_ = false;
- lifecycle_handler_->FreeAllResources();
- break;
- case APP_CMD_GAINED_FOCUS:
- hasFocus_ = true;
- if (hasSurface_ && isResumed_ && hasFocus_) {
- enabled_ = (lifecycle_handler_->Resume() == 0);
- if (enabled_) {
- EnableSensorEvents();
- }
- }
- break;
- case APP_CMD_LOST_FOCUS:
- hasFocus_ = false;
- enabled_ = false;
- DisableSensorEvents();
- lifecycle_handler_->Pause();
- break;
- case APP_CMD_LOW_MEMORY:
- lifecycle_handler_->OnLowMemory();
- break;
- case APP_CMD_PAUSE:
- isResumed_ = false;
- enabled_ = false;
- DisableSensorEvents();
- lifecycle_handler_->Pause();
- break;
- case APP_CMD_RESUME:
- isResumed_ = true;
- break;
- case APP_CMD_SAVE_STATE:
- lifecycle_handler_->OnSaveState(&application_->savedState,
- &application_->savedStateSize);
- break;
- case APP_CMD_START:
- break;
- case APP_CMD_STOP:
- hasFocus_ = false;
- lifecycle_handler_->Deactivate();
- break;
- case APP_CMD_TERM_WINDOW:
- hasFocus_ = false;
- hasSurface_ = false;
- enabled_ = false;
- DisableSensorEvents();
- lifecycle_handler_->Pause();
- break;
- default:
- break;
- }
-}
-
-void EventLoop::ProcessSensorEvent() {
- ASensorEvent event;
- while (ASensorEventQueue_getEvents(sensor_event_queue_, &event, 1) > 0) {
- switch (event.type) {
- case ASENSOR_TYPE_ACCELEROMETER:
- input_handler_->OnAccelerometerEvent(event.vector.x,
- event.vector.y, event.vector.z);
- break;
- }
- }
-}
-
-bool EventLoop::OnTouchEvent(AInputEvent* event) {
- int32_t type = AMotionEvent_getAction(event);
- MotionEvent motion_event;
- switch (type) {
- case AMOTION_EVENT_ACTION_DOWN:
- motion_event = kMotionDown;
- break;
- case AMOTION_EVENT_ACTION_UP:
- motion_event = kMotionUp;
- break;
- case AMOTION_EVENT_ACTION_MOVE:
- motion_event = kMotionMove;
- break;
- case AMOTION_EVENT_ACTION_CANCEL:
- motion_event = kMotionCancel;
- break;
- case AMOTION_EVENT_ACTION_OUTSIDE:
- motion_event = kMotionOutside;
- break;
- case AMOTION_EVENT_ACTION_POINTER_DOWN:
- motion_event = kMotionPointerDown;
- break;
- case AMOTION_EVENT_ACTION_POINTER_UP:
- motion_event = kMotionPointerUp;
- break;
- default:
- return false;
- }
- // For now we just get the last coords.
- float move_x = AMotionEvent_getX(event, 0);
- float move_y = AMotionEvent_getY(event, 0);
- int64_t when = AMotionEvent_getEventTime(event);
- LOGI("Got motion event %d at %f, %f", type, move_x, move_y);
-
- if (input_handler_->OnMotionEvent(motion_event, when, move_x, move_y) != 0) {
- return false;
- }
- return true;
-}
-
-bool EventLoop::OnKeyEvent(AInputEvent* event) {
- int32_t type = AKeyEvent_getAction(event);
- KeyEvent key_event;
- switch (type) {
- case AKEY_EVENT_ACTION_DOWN:
- key_event = kKeyDown;
- break;
- case AKEY_EVENT_ACTION_UP:
- key_event = kKeyUp;
- break;
- case AKEY_EVENT_ACTION_MULTIPLE:
- key_event = kKeyMultiple;
- break;
- default:
- return false;
- }
- /* Get the key code of the key event.
- * This is the physical key that was pressed, not the Unicode character. */
- int32_t key_code = AKeyEvent_getKeyCode(event);
- /* Get the meta key state. */
- int32_t meta_state = AKeyEvent_getMetaState(event);
- /* Get the repeat count of the event.
- * For both key up an key down events, this is the number of times the key
- * has repeated with the first down starting at 0 and counting up from
- * there. For multiple key events, this is the number of down/up pairs
- * that have occurred. */
- int32_t repeat = AKeyEvent_getRepeatCount(event);
-
- /* Get the time of the most recent key down event, in the
- * java.lang.System.nanoTime() time base. If this is a down event,
- * this will be the same as eventTime.
- * Note that when chording keys, this value is the down time of the most
- * recently pressed key, which may not be the same physical key of this
- * event. */
- // TODO(gram): Use or remove this.
- // int64_t key_down_time = AKeyEvent_getDownTime(event);
-
- /* Get the time this event occurred, in the
- * java.lang.System.nanoTime() time base. */
- int64_t when = AKeyEvent_getEventTime(event);
- bool isAltKeyDown = (meta_state & AMETA_ALT_ON) != 0;
- bool isShiftKeyDown = (meta_state & AMETA_SHIFT_ON) != 0;
- bool isCtrlKeyDown = key_code < 32;
-
- LOGI("Got key event %d %d", type, key_code);
-
- if (input_handler_->OnKeyEvent(key_event, when, key_code,
- isAltKeyDown, isCtrlKeyDown, isShiftKeyDown,
- repeat) != 0) {
- return false;
- }
- return true;
-}
-
-int32_t EventLoop::ProcessInputEvent(AInputEvent* event) {
- int32_t event_type = AInputEvent_getType(event);
- LOGI("Got input event type %d", event_type);
- switch (event_type) {
- case AINPUT_EVENT_TYPE_MOTION:
- if (AInputEvent_getSource(event) == AINPUT_SOURCE_TOUCHSCREEN) {
- return OnTouchEvent(event);
- }
- break;
- case AINPUT_EVENT_TYPE_KEY:
- return OnKeyEvent(event);
- }
- return 0;
-}
-
-void EventLoop::ActivityCallback(android_app* application, int32_t command) {
- EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData);
- event_loop->ProcessActivityEvent(command);
-}
-
-int32_t EventLoop::InputCallback(android_app* application,
- AInputEvent* event) {
- EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData);
- return event_loop->ProcessInputEvent(event);
-}
-
-void EventLoop::SensorCallback(android_app* application,
- android_poll_source* source) {
- EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData);
- event_loop->ProcessSensorEvent();
-}
-
diff --git a/runtime/embedders/openglui/android/eventloop.h b/runtime/embedders/openglui/android/eventloop.h
deleted file mode 100644
index 031bf69..0000000
--- a/runtime/embedders/openglui/android/eventloop.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_EVENTLOOP_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_EVENTLOOP_H_
-
-#include <android_native_app_glue.h>
-#include <android/sensor.h>
-#include "embedders/openglui/common/events.h"
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/lifecycle_handler.h"
-
-class EventLoop {
- public:
- explicit EventLoop(android_app* application);
- void Run(LifeCycleHandler* activity_handler,
- InputHandler* input_handler);
-
- protected:
- void EnableSensorEvents();
- void DisableSensorEvents();
-
- void ProcessActivityEvent(int32_t command);
- int32_t ProcessInputEvent(AInputEvent* event);
- void ProcessSensorEvent();
-
- bool OnTouchEvent(AInputEvent* event);
- bool OnKeyEvent(AInputEvent* event);
-
- static void ActivityCallback(android_app* application, int32_t command);
- static int32_t InputCallback(android_app* application, AInputEvent* event);
- static void SensorCallback(android_app* application,
- android_poll_source* source);
-
- private:
- friend class Sensor;
-
- bool enabled_, quit_;
- bool isResumed_, hasSurface_, hasFocus_;
- android_app* application_;
- LifeCycleHandler* lifecycle_handler_;
- InputHandler* input_handler_;
- const ASensor* sensor_;
- ASensorManager* sensor_manager_;
- ASensorEventQueue* sensor_event_queue_;
- android_poll_source sensor_poll_source_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_ANDROID_EVENTLOOP_H_
-
diff --git a/runtime/embedders/openglui/android/main.cc b/runtime/embedders/openglui/android/main.cc
deleted file mode 100644
index c0c386b..0000000
--- a/runtime/embedders/openglui/android/main.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.
-
-#include "embedders/openglui/android/android_graphics_handler.h"
-#include "embedders/openglui/android/android_input_handler.h"
-#include "embedders/openglui/android/android_resource.h"
-#include "embedders/openglui/android/android_sound_handler.h"
-#include "embedders/openglui/android/eventloop.h"
-#include "embedders/openglui/common/context.h"
-#include "embedders/openglui/common/dart_host.h"
-#include "embedders/openglui/common/vm_glue.h"
-
-android_app* application_ = NULL;
-
-Resource* MakePlatformResource(const char *path) {
- return new AndroidResource(application_, path);
-}
-
-void android_main(android_app* application) {
- application_ = application;
- app_dummy(); // Link in native_app_glue.
- const char* resource_path = "/data/data/com.google.dartndk/app_dart";
- EventLoop eventLoop(application);
- AndroidGraphicsHandler graphics_handler(application, resource_path);
- VMGlue vm_glue(&graphics_handler, resource_path);
- AndroidInputHandler input_handler(&vm_glue, &graphics_handler);
- AndroidSoundHandler sound_handler(application);
- Timer timer;
- Context app_context;
- app_context.graphics_handler = &graphics_handler;
- app_context.input_handler = &input_handler;
- app_context.sound_handler = &sound_handler;
- app_context.timer = &timer;
- app_context.vm_glue = &vm_glue;
- DartHost host(&app_context);
- eventLoop.Run(&host, &input_handler);
-}
-
diff --git a/runtime/embedders/openglui/android/support_android.cc b/runtime/embedders/openglui/android/support_android.cc
deleted file mode 100644
index 6755f15..0000000
--- a/runtime/embedders/openglui/android/support_android.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-// Provide atexit, not part of Android libc or linker.
-
-extern "C" int atexit(void (*function)(void)) {
- // Return error code.
- return 1;
-}
-
-// Provide __dso_handle, not part of Android libc or linker.
-
-__attribute__((weak)) void *__dso_handle;
-
diff --git a/runtime/embedders/openglui/build_skia.sh b/runtime/embedders/openglui/build_skia.sh
deleted file mode 100755
index 42710a8..0000000
--- a/runtime/embedders/openglui/build_skia.sh
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/bin/bash
-
-function usage {
- echo "usage: $0 [ --help ] [ --android ] [ --arm | --x86] [ --debug ] [--clean] [<Dart directory>]"
- echo
- echo "Sync up Skia and build"
- echo
- echo " --android: Build for Android"
- echo " --x86 : Build for Intel"
- echo " --arm : Cross-compile for ARM (implies --android)"
- echo " --debug : Build a debug version"
- echo
-}
-
-DO_ANDROID=0
-TARGET_ARCH=x86
-CLEAN=0
-BUILD=Release
-DART_DIR=../../..
-
-while [ ! -z "$1" ] ; do
- case $1 in
- "-h"|"-?"|"-help"|"--help")
- usage
- exit 1
- ;;
- "--android")
- DO_ANDROID=1
- ;;
- "--arm")
- TARGET_ARCH=arm
- DO_ANDROID=1
- ;;
- "--x86")
- TARGET_ARCH=x86
- ;;
- "--clean")
- CLEAN=1
- ;;
- "--debug")
- BUILD=Debug
- ;;
- "--release")
- BUILD=Release
- ;;
- *)
- if [ ! -d "$1" ]
- then
- echo "Unrecognized argument: $1"
- usage
- exit 1
- fi
- DART_DIR="$1"
- ;;
- esac
- shift
-done
-
-mkdir -p "${DART_DIR}/third_party/skia"
-pushd "${DART_DIR}/third_party/skia"
-
-if [ ${DO_ANDROID} != 0 ] ; then
- echo "Building for Android ${TARGET_ARCH}"
- curl http://skia.googlecode.com/svn/trunk/platform_tools/android/gclient.config -o .gclient
- gclient sync
-
- export ANDROID_SDK_ROOT=`readlink -f ../android_tools/sdk`
- export GSUTIL_LOCATION=`readlink -f ../gsutil`
-
- cd trunk
-
- echo "Using SDK ${ANDROID_SDK_ROOT}"
- if [ ${CLEAN} != 0 ] ; then
- ./platform_tools/android/bin/android_make -d $TARGET_ARCH -j clean
- else
- echo env -i BUILDTYPE=$BUILD ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" PATH="${PATH}:${GSUTIL_LOCATION}" ../android/bin/android_make BUILDTYPE=$BUILD -d $TARGET_ARCH -j --debug=j
- env -i BUILDTYPE=$BUILD ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" PATH="${PATH}:${GSUTIL_LOCATION}" ./platform_tools/android/bin/android_make BUILDTYPE=$BUILD -d $TARGET_ARCH -j --debug=j
- fi
-
-else
-
- echo "Building for desktop in `pwd`"
- # Desktop build. Requires svn client and Python.
-
- # Note that on Linux these packages should be installed first:
- #
- # libfreetype6
- # libfreetype6-dev
- # libpng12-0, libpng12-dev
- # libglu1-mesa-dev
- # mesa-common-dev
- # freeglut3-dev
-
- SKIA_INSTALLDIR=`pwd`
- svn checkout http://skia.googlecode.com/svn/trunk
- cd trunk
- if [ ${CLEAN} != 0 ] ; then
- echo 'Cleaning'
- make clean
- else
- # Dart sets BUILDTYPE to DebugX64 which breaks Skia build.
- make BUILDTYPE=$BUILD
- fi
- cd ..
-
-fi
-
-popd
-# TODO(gram) We should really propogate the make exit code here.
-exit 0
-
-
diff --git a/runtime/embedders/openglui/common/canvas_context.cc b/runtime/embedders/openglui/common/canvas_context.cc
deleted file mode 100644
index 24c0f7d..0000000
--- a/runtime/embedders/openglui/common/canvas_context.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// 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.
-
-#include "embedders/openglui/common/canvas_context.h"
-
-#include <ctype.h>
-#include <string.h>
-#include "core/SkStream.h"
-#include "embedders/openglui/common/image_cache.h"
-#include "embedders/openglui/common/support.h"
-
-// TODO(gram): this should be dynamic.
-#define MAX_CONTEXTS 256
-CanvasContext* contexts[MAX_CONTEXTS] = { 0 };
-
-CanvasContext* Context2D(int handle) {
- if (handle < 0 || handle >= MAX_CONTEXTS) {
- LOGE("Request for out-of-range handle %d", handle);
- return NULL;
- }
- if (contexts[handle] == NULL) {
- LOGE("Warning: request for context with handle %d returns NULL", handle);
- }
- return contexts[handle];
-}
-
-void FreeContexts() {
- extern CanvasContext* display_context;
- for (int i = 0; i < MAX_CONTEXTS; i++) {
- delete contexts[i];
- contexts[i] = NULL;
- }
- display_context = NULL;
-}
-
-
-CanvasContext::CanvasContext(int handle, int16_t widthp, int16_t heightp)
- : canvas_(NULL),
- width_(widthp),
- height_(heightp),
- imageSmoothingEnabled_(true),
- state_(NULL) {
- if (handle >= MAX_CONTEXTS) {
- LOGE("Max contexts exceeded");
- exit(-1);
- }
- if (handle == 0) {
- canvas_ = graphics->CreateDisplayCanvas();
- } else {
- canvas_ = graphics->CreateBitmapCanvas(widthp, heightp);
- }
- state_ = new CanvasState(canvas_);
- contexts[handle] = this;
- LOGI("Created context with handle %d", handle);
-}
-
-CanvasContext::~CanvasContext() {
- delete state_;
- delete canvas_;
-}
-
-void CanvasContext::Save() {
- state_ = state_->Save();
-}
-
-void CanvasContext::Restore() {
- CanvasState* popped_state = state_;
- state_ = state_->Restore();
- if (state_ == NULL) {
- LOGE("Popping last state!");
- state_ = popped_state;
- }
- if (state_ != popped_state) {
- // Only delete if the pop was successful.
- delete popped_state;
- }
-}
-
-void CanvasContext::DrawImage(const char* src_url,
- int sx, int sy,
- bool has_src_dimensions, int sw, int sh,
- int dx, int dy,
- bool has_dst_dimensions, int dw, int dh) {
- const SkBitmap* bm = ImageCache::GetImage(src_url);
- if (bm == NULL) return;
- if (!has_src_dimensions) {
- sw = bm->width();
- sh = bm->height();
- }
- if (!has_dst_dimensions) {
- dw = bm->width();
- dh = bm->height();
- }
- state_->DrawImage(*bm, sx, sy, sw, sh, dx, dy, dw, dh);
- isDirty_ = true;
-}
-
-void CanvasContext::ClearRect(float left, float top,
- float width, float height) {
- SkPaint paint;
- paint.setStyle(SkPaint::kFill_Style);
- paint.setColor(0xFFFFFFFF);
- canvas_->drawRectCoords(left, top, left + width, top + height, paint);
- isDirty_ = true;
-}
-
diff --git a/runtime/embedders/openglui/common/canvas_context.h b/runtime/embedders/openglui/common/canvas_context.h
deleted file mode 100644
index a45b574..0000000
--- a/runtime/embedders/openglui/common/canvas_context.h
+++ /dev/null
@@ -1,324 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
-#define EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
-
-#include "embedders/openglui/common/canvas_state.h"
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/support.h"
-
-typedef struct ImageData {
- int width;
- int height;
- GLubyte* pixels;
-
- ImageData(int wp, int hp, GLubyte* pp)
- : width(wp), height(hp), pixels(pp) {
- }
- ImageData()
- : width(0), height(0), pixels(NULL) {
- }
-} ImageData;
-
-class CanvasContext {
- protected:
- SkCanvas* canvas_;
- int16_t width_, height_;
- bool imageSmoothingEnabled_;
- bool isDirty_;
- CanvasState* state_;
-
- static inline float Radians2Degrees(float angle) {
- return 180.0 * angle / M_PI;
- }
-
- inline void NotImplemented(const char* method) {
- LOGE("Method CanvasContext::%s is not yet implemented", method);
- }
-
- public:
- CanvasContext(int handle, int16_t width, int16_t height);
- virtual ~CanvasContext();
-
- inline bool isDirty() {
- return isDirty_;
- }
-
- inline void clearDirty() {
- isDirty_ = false;
- }
-
- inline void setGlobalAlpha(float alpha) {
- state_->setGlobalAlpha(alpha);
- }
-
- inline void setFillColor(const char* color) {
- state_->setFillColor(color);
- }
-
- inline void setStrokeColor(const char* color) {
- state_->setStrokeColor(color);
- }
-
- inline void setShadowBlur(float blur) {
- state_->setShadowBlur(blur);
- }
-
- inline void setShadowColor(const char* color) {
- state_->setShadowColor(color);
- }
-
- inline void setShadowOffsetX(float offset) {
- state_->setShadowOffsetX(offset);
- }
-
- inline void setShadowOffsetY(float offset) {
- state_->setShadowOffsetY(offset);
- }
-
- // For now, we don't allow resizing.
- // TODO(gram): fix this or remove these.
- inline int setWidth(int widthp) {
- return width_;
- }
-
- inline int setHeight(int heightp) {
- return height_;
- }
-
- inline bool imageSmoothingEnabled() {
- return imageSmoothingEnabled_;
- }
-
- inline void setImageSmoothingEnabled(bool enabled) {
- // TODO(gram): We're not actually doing anything with this yet.
- imageSmoothingEnabled_ = enabled;
- }
-
- inline void setGlobalCompositeOperation(const char* op) {
- state_->setGlobalCompositeOperation(op);
- }
-
- void Save();
- void Restore();
-
- inline void Rotate(float angle) {
- canvas_->rotate(Radians2Degrees(angle));
- }
-
- inline void Translate(float x, float y) {
- canvas_->translate(x, y);
- }
-
- inline void Scale(float x, float y) {
- canvas_->scale(x, y);
- }
-
- inline void Transform(float a, float b,
- float c, float d,
- float e, float f) {
- SkMatrix t;
- // Our params are for a 3 x 2 matrix in column order:
- //
- // a c e
- // b d f
- //
- // We need to turn this into a 3x3 matrix:
- //
- // a c e
- // b d f
- // 0 0 1
- //
- // and pass the params in row order:
- t.setAll(a, c, e, b, d, f, 0, 0, 1);
- canvas_->concat(t);
- }
-
- inline void setTransform(float a, float b,
- float c, float d,
- float e, float f) {
- SkMatrix t;
- t.setAll(a, c, e, b, d, f, 0, 0, 1);
- canvas_->setMatrix(t);
- }
-
- ImageData* GetImageData(float sx, float sy, float sw, float sh) {
- NotImplemented("GetImageData");
- return NULL;
- }
-
- void PutImageData(ImageData* imageData, float dx, float dy) {
- NotImplemented("PutImageData");
- }
-
- void DrawImage(const char* src_url,
- int sx, int sy, bool has_src_dimensions, int sw, int sh,
- int dx, int dy, bool has_dst_dimensions, int dw, int dh);
-
- inline void Clear() {
- canvas_->drawColor(0xFFFFFFFF);
- isDirty_ = true;
- }
-
- void ClearRect(float left, float top, float width, float height);
-
- inline void FillRect(float left, float top, float width, float height) {
- // Does not affect the path.
- state_->FillRect(left, top, width, height);
- isDirty_ = true;
- }
-
- inline void StrokeRect(float left, float top, float width, float height) {
- // Does not affect the path.
- state_->StrokeRect(left, top, width, height);
- isDirty_ = true;
- }
-
- inline void BeginPath() {
- state_->BeginPath();
- }
-
- inline void Fill() {
- state_->Fill();
- isDirty_ = true;
- }
-
- inline void Stroke() {
- state_->Stroke();
- isDirty_ = true;
- }
-
- inline void ClosePath() {
- state_->ClosePath();
- }
-
- inline void MoveTo(float x, float y) {
- state_->MoveTo(x, y);
- }
-
- inline void LineTo(float x, float y) {
- state_->LineTo(x, y);
- }
-
- inline void QuadraticCurveTo(float cpx, float cpy, float x, float y) {
- state_->QuadraticCurveTo(cpx, cpy, x, y);
- }
-
- inline void BezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y,
- float x, float y) {
- state_->BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
- }
-
- inline void ArcTo(float x1, float y1, float x2, float y2, float radius) {
- state_->ArcTo(x1, y1, x2, y2, radius);
- }
-
- inline void Rect(float x, float y, float w, float h) {
- state_->Rect(x, y, w, h);
- }
-
- inline void Arc(float x, float y, float radius,
- float startAngle, float endAngle,
- bool antiClockwise) {
- state_->Arc(x, y, radius, startAngle, endAngle, antiClockwise);
- }
-
- inline void setLineWidth(double w) {
- state_->setLineWidth(w);
- }
-
- inline void setLineCap(const char* lc) {
- state_->setLineCap(lc);
- }
-
- inline void setLineDash(float* dashes, int len) {
- state_->setLineDash(dashes, len);
- }
-
- inline void setLineDashOffset(float offset) {
- state_->setLineDashOffset(offset);
- }
-
- inline void setLineJoin(const char* lj) {
- state_->setLineJoin(lj);
- }
-
- inline void setMiterLimit(float limit) {
- state_->setMiterLimit(limit);
- }
-
- inline const char* setFont(const char* font) {
- return state_->setFont(font);
- }
-
- inline const char* setTextAlign(const char* align) {
- return state_->setTextAlign(align);
- }
-
- const char* setTextBaseline(const char* baseline) {
- return state_->setTextBaseline(baseline);
- }
-
- inline const char* setDirection(const char* direction) {
- return state_->setTextDirection(direction);
- }
-
- inline void FillText(const char* text, float x, float y,
- float maxWidth = -1) {
- state_->FillText(text, x, y, maxWidth);
- isDirty_ = true;
- }
-
- inline void StrokeText(const char* text, float x, float y,
- float maxWidth = -1) {
- state_->StrokeText(text, x, y, maxWidth);
- isDirty_ = true;
- }
-
- inline float MeasureText(const char *text) {
- return state_->MeasureText(text);
- }
-
- inline void Clip() {
- state_->Clip();
- }
-
- inline void ResetClip() {
- // TODO(gram): Check this. Is it affected by the transform?
- canvas_->clipRect(SkRect::MakeLTRB(0, 0, width_, height_),
- SkRegion::kReplace_Op);
- }
-
- virtual void Flush() {
- canvas_->flush();
- }
-
- inline void SetFillGradient(bool is_radial, double x0, double y0, double r0,
- double x1, double y1, double r1,
- int stops, float* positions, char** colors) {
- state_->SetFillGradient(is_radial, x0, y0, r0, x1, y1, r1,
- stops, positions, colors);
- }
-
- inline void SetStrokeGradient(bool is_radial, double x0, double y0, double r0,
- double x1, double y1, double r1,
- int stops, float* positions, char** colors) {
- state_->SetStrokeGradient(is_radial, x0, y0, r0, x1, y1, r1,
- stops, positions, colors);
- }
-
- inline const SkBitmap* GetBitmap() {
- SkDevice* device = canvas_->getDevice();
- return &device->accessBitmap(false);
- }
-};
-
-CanvasContext* Context2D(int handle);
-void FreeContexts();
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
-
diff --git a/runtime/embedders/openglui/common/canvas_state.cc b/runtime/embedders/openglui/common/canvas_state.cc
deleted file mode 100644
index 8d927c8..0000000
--- a/runtime/embedders/openglui/common/canvas_state.cc
+++ /dev/null
@@ -1,411 +0,0 @@
-// 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.
-
-#include "embedders/openglui/common/canvas_state.h"
-
-#include <ctype.h>
-#include <string.h>
-
-#include "embedders/openglui/common/support.h"
-
-// Float parser. Does not handle exponents. This is
-// used to parse font sizes so it doesn't need to be full-blown.
-float ParseFloat(const char* s, int& pos) {
- int len = strlen(s);
- float rtn = 0.0;
- while (pos < len && s[pos] != '.' && !isdigit(s[pos])) {
- ++pos;
- }
- while (pos < len && isdigit(s[pos])) {
- rtn = rtn * 10.0 + s[pos] - '0';
- ++pos;
- }
- if (pos < len && s[pos] == '.') {
- pos++;
- float div = 1.0;
- while (pos < len && isdigit(s[pos])) {
- rtn = rtn * 10.0 + s[pos] - '0';
- ++pos;
- div *= 10.0;
- }
- rtn /= div;
- }
- return rtn;
-}
-
-int ParseInt(const char* s, int& pos) {
- int len = strlen(s);
- int rtn = 0;
- while (pos < len && !isdigit(s[pos])) {
- ++pos;
- }
- while (pos < len && isdigit(s[pos])) {
- rtn = rtn * 10 + s[pos] - '0';
- ++pos;
- }
- return rtn;
-}
-
-CanvasState* CanvasState::Restore() {
- if (next_ != NULL) {
- // If the state we are popping has a non-empty path,
- // apply the state's transform to the path, then
- // add the path to the previous state's path.
- if (path_->countPoints() > 0) {
- path_->transform(canvas_->getTotalMatrix());
- next_->path_->addPath(*path_);
- }
- canvas_->restore();
- return next_;
- }
- canvas_->restore();
- return next_; // TODO(gram): Should we assert/throw?
-}
-
-void CanvasState::setLineCap(const char* lc) {
- if (strcmp(lc, "round") == 0) {
- paint_.setStrokeCap(SkPaint::kRound_Cap);
- } else if (strcmp(lc, "square") == 0) {
- paint_.setStrokeCap(SkPaint::kSquare_Cap);
- } else {
- paint_.setStrokeCap(SkPaint::kButt_Cap);
- }
-}
-
-void CanvasState::setLineJoin(const char* lj) {
- if (strcmp(lj, "round") == 0) {
- paint_.setStrokeJoin(SkPaint::kRound_Join);
- } else if (strcmp(lj, "bevel") == 0) {
- paint_.setStrokeJoin(SkPaint::kBevel_Join);
- } else {
- paint_.setStrokeJoin(SkPaint::kMiter_Join);
- }
-}
-
-const char* CanvasState::setFont(const char*name, float size) {
- // Font names have the form "<modifier> <size> <family>".
- // Modifiers are "normal", "italic", "bold".
- // Sizes have magnitude and units; e.g. "10pt", "20px".
- const char* rtn = name;
- if (size < 0) {
- int pos = 0;
- // TODO(gram): need to handle these modifiers.
- if (strncmp(name, "normal", 6) == 0) {
- pos = 6;
- } else if (strncmp(name, "italic", 6) == 0) {
- pos = 6;
- } else if (strncmp(name, "bold", 4) == 0) {
- pos = 4;
- }
- size = ParseFloat(name, pos);
- // Font size units: px, etc. For now just px.
- // TODO(gram): Handle other units.
- if (strncmp(name + pos, "px", 2) == 0) {
- pos += 2;
- }
- int len = strlen(name);
- while (pos < len && isspace(name[pos])) {
- ++pos;
- }
- name = name + pos;
- }
- SkTypeface *pTypeface = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
- paint_.setTypeface(pTypeface);
- paint_.setTextSize(size);
- // TODO(gram): Must return a normalized font name incorporating size, so
- // callers can set the Dart canvas font name to an appropriate value.
- // Actually this may not be necessary in which case we can change this
- // method to return void.
- return rtn;
-}
-
-const char* CanvasState::setTextAlign(const char* align) {
- // TODO(gram): What about "start" and "end"?
- // I don't see any an analogs in Skia.
- if (strcmp(align, "left") == 0) {
- paint_.setTextAlign(SkPaint::kLeft_Align);
- } else if (strcmp(align, "right") == 0) {
- paint_.setTextAlign(SkPaint::kRight_Align);
- } else {
- paint_.setTextAlign(SkPaint::kCenter_Align);
- }
- return align;
-}
-
-const char* CanvasState::setTextBaseline(const char* baseline) {
- // TODO(gram): Does skia support this? It doesn't seem like
- // it. Right now we don't use the textBaseline value, but we
- // may have to implement this ourselves, by adjusting the y
- // values passed to StrokeText/FillText using the font metrics.
- if (strcmp(baseline, "top") == 0) {
- } else if (strcmp(baseline, "middle") == 0) {
- } else if (strcmp(baseline, "bottom") == 0) {
- } else if (strcmp(baseline, "hanging") == 0) {
- } else if (strcmp(baseline, "alphabetic") == 0) {
- } else if (strcmp(baseline, "ideographic") == 0) {
- }
- return baseline;
-}
-
-const char* CanvasState::setTextDirection(const char* direction) {
- // TODO(gram): Add support for this if Skia does.
- return direction;
-}
-
-void CanvasState::setMode(SkPaint::Style style, ColorRGBA color,
- SkShader* shader) {
- paint_.setStyle(style);
- paint_.setColor(color.v);
- paint_.setShader(shader);
- uint8_t alpha = static_cast<uint8_t>(
- globalAlpha_ * static_cast<float>(color.alpha()));
- paint_.setAlpha(alpha);
- bool drawShadow = (shadowOffsetX_ != 0 ||
- shadowOffsetY_ != 0 ||
- shadowBlur_ != 0) &&
- shadowColor_.alpha() > 0;
- if (drawShadow) {
- // TODO(gram): should we mult shadowColor by globalAlpha?
- paint_.setLooper(new SkBlurDrawLooper(SkFloatToScalar(shadowBlur_),
- SkFloatToScalar(shadowOffsetX_),
- SkFloatToScalar(shadowOffsetY_),
- shadowColor_.v))->unref();
- } else {
- paint_.setLooper(NULL);
- }
-}
-
-void CanvasState::setGlobalCompositeOperation(const char* op) {
- SkXfermode::Mode mode;
- static const struct CompositOpToXfermodeMode {
- const char* mCompositOp;
- uint8_t m_xfermodeMode;
- } gMapCompositOpsToXfermodeModes[] = {
- { "clear", SkXfermode::kClear_Mode },
- { "copy", SkXfermode::kSrc_Mode },
- { "source-over", SkXfermode::kSrcOver_Mode },
- { "source-in", SkXfermode::kSrcIn_Mode },
- { "source-out", SkXfermode::kSrcOut_Mode },
- { "source-atop", SkXfermode::kSrcATop_Mode },
- { "destination-over", SkXfermode::kDstOver_Mode },
- { "destination-in", SkXfermode::kDstIn_Mode },
- { "destination-out", SkXfermode::kDstOut_Mode },
- { "destination-atop", SkXfermode::kDstATop_Mode },
- { "xor", SkXfermode::kXor_Mode },
- { "darker", SkXfermode::kDarken_Mode },
- { "lighter", SkXfermode::kPlus_Mode }
- };
- for (unsigned i = 0;
- i < SK_ARRAY_COUNT(gMapCompositOpsToXfermodeModes);
- i++) {
- if (strcmp(op, gMapCompositOpsToXfermodeModes[i].mCompositOp) == 0) {
- mode = (SkXfermode::Mode)gMapCompositOpsToXfermodeModes[i].m_xfermodeMode;
- paint_.setXfermodeMode(mode);
- return;
- }
- }
- LOGE("Unknown CompositeOperator %s\n", op);
- paint_.setXfermodeMode(SkXfermode::kSrcOver_Mode); // fall-back
-}
-
-void CanvasState::Arc(float x, float y, float radius,
- float startAngle, float endAngle,
- bool antiClockwise) {
- SkRect rect;
- rect.set(x - radius, y - radius, x + radius, y + radius);
- bool doCircle = false;
-
- static float twoPi = 2 * M_PI;
-
- float sweep = endAngle - startAngle;
- if (sweep >= twoPi || sweep <= -twoPi) {
- doCircle = true;
- }
-
- if (!antiClockwise && endAngle <= startAngle) {
- endAngle += 2 * M_PI;
- } else if (antiClockwise && startAngle <= endAngle) {
- startAngle += 2 * M_PI;
- }
- sweep = endAngle - startAngle;
-
- startAngle = fmodf(startAngle, twoPi);
- float sa = Radians2Degrees(startAngle);
- float ea = Radians2Degrees(sweep);
- path_->arcTo(rect, sa, ea, false);
- if (doCircle) {
- SkPath tmp;
- tmp.addOval(rect);
- tmp.addPath(*path_);
- path_->swap(tmp);
- }
-}
-
-int hexDigit(char c) {
- if (c >= '0' && c <= '9') return c - '0';
- if (c <= 'Z') return c - 'A' + 10;
- return c - 'a' + 10;
-}
-
-// Color parser.
-// See http://www.w3.org/TR/CSS21/syndata.html#color-units.
-// There is also another format: hsl(240,100%,100%) (and hsla)
-// TODO(gram): We probably eventually want to use a table rather
-// than a big if statement; see setGlobalCompositeOperation for
-// an example.
-ColorRGBA CanvasState::GetColor(const char* color) {
- if (color[0] == '#') {
- int r = 0, g = 0, b = 0;
- if (strlen(color) == 7) {
- r = hexDigit(color[1]) * 16 + hexDigit(color[2]);
- g = hexDigit(color[3]) * 16 + hexDigit(color[4]);
- b = hexDigit(color[5]) * 16 + hexDigit(color[6]);
- } else if (strlen(color) == 4) {
- r = hexDigit(color[1]) * 16 + hexDigit(color[1]);
- g = hexDigit(color[2]) * 16 + hexDigit(color[2]);
- b = hexDigit(color[3]) * 16 + hexDigit(color[3]);
- }
- return ColorRGBA(r, g, b);
- } else if (strcmp(color, "maroon") == 0) {
- return ColorRGBA(0x80, 0x00, 0x00);
- } else if (strcmp(color, "red") == 0) {
- return ColorRGBA(0xFF, 0x00, 0x00);
- } else if (strcmp(color, "orange") == 0) {
- return ColorRGBA(0xFF, 0xA5, 0x00);
- } else if (strcmp(color, "yellow") == 0) {
- return ColorRGBA(0xFF, 0xFF, 0x00);
- } else if (strcmp(color, "olive") == 0) {
- return ColorRGBA(0x80, 0x80, 0x00);
- } else if (strcmp(color, "purple") == 0) {
- return ColorRGBA(0x80, 0x00, 0x80);
- } else if (strcmp(color, "fuschia") == 0) {
- return ColorRGBA(0xFF, 0x00, 0xFF);
- } else if (strcmp(color, "white") == 0) {
- return ColorRGBA(0xFF, 0xFF, 0xFF);
- } else if (strcmp(color, "lime") == 0) {
- return ColorRGBA(0x00, 0xFF, 0x00);
- } else if (strcmp(color, "green") == 0) {
- return ColorRGBA(0x00, 0x80, 0x00);
- } else if (strcmp(color, "navy") == 0) {
- return ColorRGBA(0x00, 0x00, 0x80);
- } else if (strcmp(color, "blue") == 0) {
- return ColorRGBA(0x00, 0x00, 0xFF);
- } else if (strcmp(color, "aqua") == 0) {
- return ColorRGBA(0x00, 0xFF, 0xFF);
- } else if (strcmp(color, "teal") == 0) {
- return ColorRGBA(0x00, 0x80, 0x80);
- } else if (strcmp(color, "silver") == 0) {
- return ColorRGBA(0xC0, 0xC0, 0xC0);
- } else if (strcmp(color, "gray") == 0) {
- return ColorRGBA(0x80, 0x80, 0x80);
- } else if (strncmp(color, "rgb(", 4) == 0) {
- int pos = 4;
- int r = ParseInt(color, pos);
- ++pos;
- int g = ParseInt(color, pos);
- ++pos;
- int b = ParseInt(color, pos);
- return ColorRGBA(r, g, b);
- } else if (strncmp(color, "rgba(", 5) == 0) {
- int pos = 5;
- int r = ParseInt(color, pos);
- ++pos;
- int g = ParseInt(color, pos);
- ++pos;
- int b = ParseInt(color, pos);
- ++pos;
- float a = ParseFloat(color, pos);
- return ColorRGBA(r, g, b, static_cast<int>(a * 255.0));
- }
- // Default to black.
- return ColorRGBA(0x00, 0x00, 0x00);
-}
-
-void CanvasState::DrawImage(const SkBitmap& bm,
- int sx, int sy, int sw, int sh,
- int dx, int dy, int dw, int dh) {
- if (sw < 0) sw = bm.width();
- if (dw < 0) dw = bm.width();
- if (sh < 0) sh = bm.height();
- if (dh < 0) dh = bm.height();
- SkIRect src = SkIRect::MakeXYWH(sx, sy, sw, sh);
- SkRect dst = SkRect::MakeXYWH(dx, dy, dw, dh);
- LOGI("DrawImage(_,%d,%d,%d,%d,%d,%d,%d,%d)", sx, sy, sw, sh, dx, dy, dw, dh);
- canvas_->drawBitmapRect(bm, &src, dst);
-}
-
-void CanvasState::SetFillGradient(bool is_radial,
- double x0, double y0, double r0,
- double x1, double y1, double r1,
- int stops, float* positions, char** colors) {
- if (fillShader_ != NULL) {
- fillShader_->unref();
- }
- if (is_radial) {
- fillShader_ = CreateRadialGradient(x0, y0, r0, x1, y1, r1,
- stops, positions, colors);
- } else {
- fillShader_ = CreateLinearGradient(x0, y0, x1, y1,
- stops, positions, colors);
- }
- fillShader_->validate();
-}
-
-void CanvasState::SetStrokeGradient(bool is_radial,
- double x0, double y0, double r0,
- double x1, double y1, double r1,
- int stops, float* positions, char** colors) {
- if (strokeShader_ != NULL) {
- strokeShader_->unref();
- }
- if (is_radial) {
- strokeShader_ = CreateRadialGradient(x0, y0, r0, x1, y1, r1,
- stops, positions, colors);
- } else {
- strokeShader_ = CreateLinearGradient(x0, y0, x1, y1,
- stops, positions, colors);
- }
- strokeShader_->validate();
-}
-
-SkShader* CanvasState::CreateRadialGradient(
- double x0, double y0, double r0,
- double x1, double y1, double r1,
- int stops, float* positions, char** colors) {
- SkScalar* p = new SkScalar[stops];
- SkColor* c = new SkColor[stops];
- for (int i = 0; i < stops; i++) {
- p[i] = positions[i];
- c[i] = GetColor(colors[i]).v;
- }
- LOGI("CreateRadialGradient(%f,%f,%f,%f,%f,%f,%d,[%f,%f],[%s,%s]",
- x0, y0, r0, x1, y1, r1, stops, positions[0], positions[1],
- colors[0], colors[1]);
- SkShader* shader = SkGradientShader::CreateTwoPointRadial(
- SkPoint::Make(x0, y0), r0, SkPoint::Make(x1, y1), r1,
- c, p, stops, SkShader::kClamp_TileMode);
- delete[] c;
- delete[] p;
- return shader;
-}
-
-SkShader* CanvasState::CreateLinearGradient(
- double x0, double y0, double x1, double y1,
- int stops, float* positions, char** colors) {
- SkScalar* p = new SkScalar[stops];
- SkColor* c = new SkColor[stops];
- for (int i = 0; i < stops; i++) {
- p[i] = positions[i];
- c[i] = GetColor(colors[i]).v;
- }
- SkPoint pts[2];
- pts[0] = SkPoint::Make(x0, y0);
- pts[1] = SkPoint::Make(x1, y1);
- SkShader* shader = SkGradientShader::CreateLinear(pts, c, p, stops,
- SkShader::kClamp_TileMode);
- delete[] c;
- delete[] p;
- return shader;
-}
-
diff --git a/runtime/embedders/openglui/common/canvas_state.h b/runtime/embedders/openglui/common/canvas_state.h
deleted file mode 100644
index fc0e095..0000000
--- a/runtime/embedders/openglui/common/canvas_state.h
+++ /dev/null
@@ -1,312 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/support.h"
-
-typedef struct CanvasState {
- SkPaint paint_;
- float globalAlpha_;
- float miterLimit_;
- ColorRGBA fillColor_;
- ColorRGBA strokeColor_;
- ColorRGBA shadowColor_;
- float shadowBlur_;
- float shadowOffsetX_;
- float shadowOffsetY_;
- float* lineDash_;
- int lineDashCount_;
- int lineDashOffset_;
- SkShader* fillShader_;
- SkShader* strokeShader_;
-
- SkPath* path_;
- SkCanvas* canvas_;
- CanvasState* next_; // For stack.
-
- CanvasState(SkCanvas* canvas)
- : paint_(),
- globalAlpha_(1.0),
- miterLimit_(10),
- fillColor_(ColorRGBA(255, 0, 0, 255)),
- strokeColor_(fillColor_),
- shadowColor_(ColorRGBA(0, 0, 0, 0)),
- shadowBlur_(0.0),
- shadowOffsetX_(0.0),
- shadowOffsetY_(0.0),
- lineDash_(NULL),
- lineDashCount_(0),
- lineDashOffset_(0),
- fillShader_(NULL),
- strokeShader_(NULL),
- path_(new SkPath()),
- canvas_(canvas),
- next_(NULL) {
- paint_.setStrokeCap(SkPaint::kButt_Cap);
- paint_.setStrokeJoin(SkPaint::kMiter_Join);
- paint_.setStrokeWidth(1);
- paint_.setTextAlign(SkPaint::kLeft_Align);
- paint_.setAntiAlias(true);
- paint_.setStyle(SkPaint::kStroke_Style);
- setFont("Helvetica", 10);
- }
-
- CanvasState(const CanvasState& state)
- : paint_(state.paint_),
- globalAlpha_(state.globalAlpha_),
- miterLimit_(state.miterLimit_),
- fillColor_(state.fillColor_),
- strokeColor_(state.strokeColor_),
- shadowColor_(state.shadowColor_),
- shadowBlur_(state.shadowBlur_),
- shadowOffsetX_(state.shadowOffsetX_),
- shadowOffsetY_(state.shadowOffsetY_),
- lineDash_(NULL),
- lineDashCount_(state.lineDashCount_),
- lineDashOffset_(state.lineDashOffset_),
- fillShader_(state.fillShader_),
- strokeShader_(state.strokeShader_),
- path_(new SkPath()),
- canvas_(state.canvas_),
- next_(NULL) {
- setLineDash(state.lineDash_, lineDashCount_);
- if (fillShader_ != NULL) fillShader_->ref();
- if (strokeShader_ != NULL) strokeShader_->ref();
- }
-
- ~CanvasState() {
- if (fillShader_ != NULL) fillShader_->unref();
- if (strokeShader_ != NULL) strokeShader_->unref();
- delete path_;
- delete[] lineDash_;
- }
-
- static ColorRGBA GetColor(const char* color);
-
- inline CanvasState* Save() {
- canvas_->save(); // For clip and transform.
- CanvasState *new_state = new CanvasState(*this);
- new_state->next_ = this;
- // If the old state has a non-empty path, use its
- // last point as the new states first point.
- int np = path_->countPoints();
- if (np > 0) {
- new_state->path_->moveTo(path_->getPoint(np-1));
- }
- return new_state;
- }
-
- CanvasState* Restore();
-
- inline float Radians2Degrees(float angle) {
- return 180.0 * angle / M_PI;
- }
-
- inline void setGlobalAlpha(float alpha) {
- globalAlpha_ = alpha;
- }
-
- inline void setFillColor(const char* color) {
- if (fillShader_ != NULL) {
- fillShader_->unref();
- fillShader_ = NULL;
- }
- fillColor_ = GetColor(color);
- }
-
- inline void setStrokeColor(const char* color) {
- if (strokeShader_ != NULL) {
- strokeShader_->unref();
- strokeShader_ = NULL;
- }
- strokeColor_ = GetColor(color);
- }
-
- const char* setFont(const char*name, float size = -1);
- void setLineCap(const char* lc);
- void setLineJoin(const char* lj);
-
- inline void setMiterLimit(float limit) {
- miterLimit_ = limit;
- }
-
- const char* setTextAlign(const char* align);
- const char* setTextBaseline(const char* baseline);
- const char* setTextDirection(const char* direction);
-
- inline void FillText(const char* text, float x, float y, float maxWidth) {
- setFillMode();
- canvas_->drawText(text, strlen(text), x, y, paint_);
- }
-
- inline void StrokeText(const char* text, float x, float y, float maxWidth) {
- setStrokeMode();
- canvas_->drawText(text, strlen(text), x, y, paint_);
- }
-
- inline float MeasureText(const char *text) {
- // TODO(gram): make sure this is not supposed to be affected
- // by the canvas transform.
- return paint_.measureText(text, strlen(text));
- }
-
- inline void setLineWidth(float w) {
- paint_.setStrokeWidth(w);
- }
-
- void setMode(SkPaint::Style style, ColorRGBA color, SkShader* shader);
-
- inline void setLineDashEffect() {
- if (lineDashCount_ > 0) {
- SkDashPathEffect* dashPathEffect =
- new SkDashPathEffect(lineDash_, lineDashCount_, lineDashOffset_);
- paint_.setPathEffect(dashPathEffect)->unref();
- } else {
- paint_.setPathEffect(NULL);
- }
- }
-
- inline void setLineDash(float* dashes, int len) {
- if (len == 0) {
- lineDashCount_ = 0;
- delete[] lineDash_;
- lineDash_ = NULL;
- } else {
- lineDash_ = new float[lineDashCount_ = len];
- for (int i = 0; i < len; i++) {
- lineDash_[i] = dashes[i];
- }
- }
- setLineDashEffect();
- }
-
- inline void setLineDashOffset(int offset) {
- if (offset != lineDashOffset_) {
- lineDashOffset_ = offset;
- setLineDashEffect();
- }
- }
-
- inline void setShadowColor(const char* color) {
- shadowColor_ = GetColor(color);
- }
-
- inline void setShadowBlur(float blur) {
- shadowBlur_ = blur;
- }
-
- inline void setShadowOffsetX(float ox) {
- shadowOffsetX_ = ox;
- }
-
- inline void setShadowOffsetY(float oy) {
- shadowOffsetY_ = oy;
- }
-
- inline void setFillMode() {
- setMode(SkPaint::kFill_Style, fillColor_, fillShader_);
- }
-
- inline void setStrokeMode() {
- setMode(SkPaint::kStroke_Style, strokeColor_, strokeShader_);
- }
-
- inline void FillRect(float left, float top,
- float width, float height) {
- // Does not affect the path.
- setFillMode();
- canvas_->drawRectCoords(left, top, left + width, top + height, paint_);
- }
-
- inline void StrokeRect(float left, float top,
- float width, float height) {
- // Does not affect the path.
- setStrokeMode();
- canvas_->drawRectCoords(left, top, left + width, top + height, paint_);
- }
-
- inline void BeginPath() {
- path_->rewind();
- }
-
- inline void Fill() {
- setFillMode();
- canvas_->drawPath(*path_, paint_);
- }
-
- inline void Stroke() {
- setStrokeMode();
- canvas_->drawPath(*path_, paint_);
- }
-
- inline void ClosePath() {
- path_->close();
- }
-
- inline void MoveTo(float x, float y) {
- path_->moveTo(x, y);
- }
-
- inline void LineTo(float x, float y) {
- path_->lineTo(x, y);
- }
-
- void Arc(float x, float y, float radius, float startAngle, float endAngle,
- bool antiClockwise);
-
- inline void QuadraticCurveTo(float cpx, float cpy, float x, float y) {
- path_->quadTo(cpx, cpy, x, y);
- }
-
- inline void BezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y,
- float x, float y) {
- path_->cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
- }
-
- inline void ArcTo(float x1, float y1, float x2, float y2, float radius) {
- path_->arcTo(x1, y1, x2, y2, radius);
- }
-
- inline void Rect(float x, float y, float w, float h) {
- // TODO(gram): Should we draw this directly? If so, what happens with the
- // path?
- path_->addRect(x, y, x + w, y + h);
- }
-
- void setGlobalCompositeOperation(const char* op);
-
- void DrawImage(const SkBitmap& bm,
- int sx, int sy, int sw, int sh,
- int dx, int dy, int dw, int dh);
-
- inline void Clip() {
- canvas_->clipPath(*path_);
- }
-
- void SetFillGradient(bool is_radial, double x0, double y0, double r0,
- double x1, double y1, double r1,
- int stops, float* positions, char** colors);
-
- void SetStrokeGradient(bool is_radial, double x0, double y0, double r0,
- double x1, double y1, double r1,
- int stops, float* positions, char** colors);
-
- private:
- SkShader* CreateRadialGradient(
- double x0, double y0, double r0,
- double x1, double y1, double r1,
- int stops, float* positions, char** colors);
-
- SkShader* CreateLinearGradient(
- double x0, double y0, double x1, double y1,
- int stops, float* positions, char** colors);
-} CanvasState;
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
-
diff --git a/runtime/embedders/openglui/common/context.h b/runtime/embedders/openglui/common/context.h
deleted file mode 100644
index 54148fc..0000000
--- a/runtime/embedders/openglui/common/context.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_CONTEXT_H_
-#define EMBEDDERS_OPENGLUI_COMMON_CONTEXT_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/sound_handler.h"
-#include "embedders/openglui/common/timer.h"
-#include "embedders/openglui/common/vm_glue.h"
-
-struct Context {
- GraphicsHandler* graphics_handler;
- InputHandler* input_handler;
- SoundHandler* sound_handler;
- Timer* timer;
- VMGlue* vm_glue;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_CONTEXT_H_
-
diff --git a/runtime/embedders/openglui/common/dart_host.cc b/runtime/embedders/openglui/common/dart_host.cc
deleted file mode 100644
index dd2c1cd..0000000
--- a/runtime/embedders/openglui/common/dart_host.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// 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.
-
-#include "embedders/openglui/common/dart_host.h"
-
-#include <math.h>
-#include <unistd.h>
-
-#include "embedders/openglui/common/image_cache.h"
-#include "embedders/openglui/common/log.h"
-
-DartHost::DartHost(Context *context)
- : graphics_handler_(context->graphics_handler),
- input_handler_(context->input_handler),
- sound_handler_(context->sound_handler),
- timer_(context->timer),
- vm_glue_(context->vm_glue),
- has_context_(false),
- started_(false),
- active_(false) {
- ImageCache::Init(graphics_handler_->resource_path());
-}
-
-DartHost::~DartHost() {
-}
-
-int32_t DartHost::OnStart() {
- int result = vm_glue_->StartMainIsolate();
- if (result != 0) {
- LOGE("startMainIsolate returned %d", result);
- return -1;
- }
- started_ = true;
- return 0;
-}
-
-int32_t DartHost::Activate() {
- if (!has_context_) {
- if (graphics_handler_->Start() != 0) {
- return -1;
- }
- if (sound_handler_->Start() != 0) {
- graphics_handler_->Stop();
- return -1;
- }
- if (input_handler_->Start() != 0) {
- sound_handler_->Stop();
- graphics_handler_->Stop();
- return -1;
- }
- int32_t rtn = vm_glue_->CallSetup(true);
- timer_->Reset();
- has_context_ = true;
- return rtn;
- }
- return 0;
-}
-
-void DartHost::Deactivate() {
- Pause();
- if (has_context_) {
- vm_glue_->CallShutdown();
- input_handler_->Stop();
- sound_handler_->Stop();
- graphics_handler_->Stop();
- has_context_ = false;
- }
-}
-
-int32_t DartHost::OnStep() {
- if (active_) {
- timer_->Update();
- if (vm_glue_->CallUpdate() != 0 ||
- graphics_handler_->Update() != 0) {
- return -1;
- }
- }
- return 0;
-}
-
-int32_t DartHost::Resume() {
- if (!active_) {
- if (Activate() == 0) {
- sound_handler_->Resume();
- active_ = true;
- }
- }
- return 0;
-}
-
-void DartHost::Pause() {
- if (active_) {
- active_ = false; // This stops update() calls.
- sound_handler_->Suspend();
- }
-}
-
-void DartHost::FreeAllResources() {
- if (started_) {
- vm_glue_->FinishMainIsolate();
- started_ = false;
- }
-}
-
-void DartHost::OnSaveState(void** data, size_t* size) {
- LOGI("Saving DartHost state");
-}
-
-void DartHost::OnConfigurationChanged() {
- LOGI("DartHost config changed");
-}
-
-void DartHost::OnLowMemory() {
- LOGI("DartHost low on memory");
-}
-
diff --git a/runtime/embedders/openglui/common/dart_host.h b/runtime/embedders/openglui/common/dart_host.h
deleted file mode 100644
index 9233aa2f..0000000
--- a/runtime/embedders/openglui/common/dart_host.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_DART_HOST_H_
-#define EMBEDDERS_OPENGLUI_COMMON_DART_HOST_H_
-
-#include "embedders/openglui/common/context.h"
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/lifecycle_handler.h"
-#include "embedders/openglui/common/sound_handler.h"
-#include "embedders/openglui/common/timer.h"
-#include "embedders/openglui/common/vm_glue.h"
-#include "include/dart_api.h"
-
-class DartHost : public LifeCycleHandler {
- public:
- explicit DartHost(Context* context);
- virtual ~DartHost();
-
- int32_t OnStart();
- void OnSaveState(void** data, size_t* size);
- void OnConfigurationChanged();
- void OnLowMemory();
- int32_t Activate();
- void Deactivate();
- void Pause();
- int32_t Resume();
- void FreeAllResources();
- int32_t OnStep();
-
- private:
- void Clear();
-
- GraphicsHandler* graphics_handler_;
- InputHandler* input_handler_;
- SoundHandler* sound_handler_;
- Timer* timer_;
- VMGlue* vm_glue_;
- bool has_context_;
- bool started_;
- bool active_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_DART_HOST_H_
-
diff --git a/runtime/embedders/openglui/common/events.h b/runtime/embedders/openglui/common/events.h
deleted file mode 100644
index 64c6951..0000000
--- a/runtime/embedders/openglui/common/events.h
+++ /dev/null
@@ -1,39 +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 EMBEDDERS_OPENGLUI_COMMON_EVENTS_H_
-#define EMBEDDERS_OPENGLUI_COMMON_EVENTS_H_
-
-typedef enum {
- kStart,
- kStop,
- kGainedFocus,
- kLostFocus,
- kPause,
- kResume,
- kSaveState,
- kConfigChanged,
- kInitWindow,
- kTermWindow,
- kDestroy
-} LifecycleEvent;
-
-typedef enum {
- kKeyDown,
- kKeyUp,
- kKeyMultiple
-} KeyEvent;
-
-typedef enum {
- kMotionDown,
- kMotionUp,
- kMotionMove,
- kMotionCancel,
- kMotionOutside,
- kMotionPointerDown,
- kMotionPointerUp
-} MotionEvent;
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_EVENTS_H_
-
diff --git a/runtime/embedders/openglui/common/extension.cc b/runtime/embedders/openglui/common/extension.cc
deleted file mode 100644
index 6304c3b..0000000
--- a/runtime/embedders/openglui/common/extension.cc
+++ /dev/null
@@ -1,1737 +0,0 @@
-// 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.
-
-#include "embedders/openglui/common/extension.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "embedders/openglui/common/canvas_context.h"
-#include "embedders/openglui/common/image_cache.h"
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/opengl.h"
-#include "include/dart_api.h"
-#include "include/dart_native_api.h"
-
-Dart_Handle HandleError(Dart_Handle handle) {
- if (Dart_IsError(handle)) Dart_PropagateError(handle);
- return handle;
-}
-
-void CheckGLError(const char *function) {
- int error = glGetError();
- if (error != GL_NO_ERROR) {
- if (error == GL_INVALID_ENUM) {
- LOGE("%s: An unacceptable value is given for an enumerated argument.",
- function);
- } else if (error == GL_INVALID_VALUE) {
- LOGE("%s: A numeric argument is out of range.", function);
- } else if (error == GL_INVALID_OPERATION) {
- LOGE("%s: The specified operation is not allowed in the current state.",
- function);
- } else if (error == GL_INVALID_FRAMEBUFFER_OPERATION) {
- LOGE("%s: The framebuffer object is not complete.", function);
- } else if (error == GL_OUT_OF_MEMORY) {
- LOGE("%s: There is not enough memory left to execute the command.",
- function);
- } else {
- LOGE("ERROR!: %s returns %d", function, error);
- }
- }
-}
-
-const char* GetArgAsString(Dart_NativeArguments arguments, int idx) {
- Dart_Handle handle = HandleError(Dart_GetNativeArgument(arguments, idx));
- uint8_t* str;
- intptr_t length;
- HandleError(Dart_StringLength(handle, &length));
- HandleError(Dart_StringToUTF8(handle, &str, &length));
- str[length] = 0;
- return const_cast<const char*>(reinterpret_cast<char*>(str));
-}
-
-double GetArgAsDouble(Dart_NativeArguments arguments, int index) {
- Dart_Handle handle = HandleError(Dart_GetNativeArgument(arguments, index));
- if (Dart_IsDouble(handle)) {
- double v;
- HandleError(Dart_DoubleValue(handle, &v));
- return v;
- }
- if (Dart_IsInteger(handle)) {
- int64_t v;
- HandleError(Dart_IntegerToInt64(handle, &v));
- return static_cast<double>(v);
- }
- LOGE("Argument at index %d has non-numeric type", index);
- Dart_ThrowException(Dart_NewStringFromCString("Numeric argument expected."));
- return 0;
-}
-
-int64_t GetArgAsInt(Dart_NativeArguments arguments, int index) {
- Dart_Handle handle = HandleError(Dart_GetNativeArgument(arguments, index));
- if (Dart_IsDouble(handle)) {
- double v;
- HandleError(Dart_DoubleValue(handle, &v));
- return static_cast<int64_t>(v);
- }
- if (Dart_IsInteger(handle)) {
- int64_t v;
- HandleError(Dart_IntegerToInt64(handle, &v));
- return v;
- }
- LOGE("Argument at index %d has non-numeric type", index);
- Dart_ThrowException(Dart_NewStringFromCString("Numeric argument expected."));
- return 0;
-}
-
-bool GetArgAsBool(Dart_NativeArguments arguments, int index) {
- Dart_Handle handle = HandleError(Dart_GetNativeArgument(arguments, index));
- if (Dart_IsBoolean(handle)) {
- bool v;
- HandleError(Dart_BooleanValue(handle, &v));
- return v;
- }
- LOGI("Argument at index %d has non-Boolean type", index);
- Dart_ThrowException(Dart_NewStringFromCString("Boolean argument expected."));
- return false;
-}
-
-int GetListLength(Dart_NativeArguments arguments, int index,
- Dart_Handle& argHandle) {
- argHandle = HandleError(Dart_GetNativeArgument(arguments, index));
- if (Dart_IsList(argHandle)) {
- intptr_t len;
- HandleError(Dart_ListLength(argHandle, &len));
- return len;
- }
- LOGI("Argument at index %d has non-List type", index);
- Dart_ThrowException(Dart_NewStringFromCString("List argument expected."));
- return -1;
-}
-
-GLint* GetArgsAsGLintList(Dart_NativeArguments arguments, int index,
- int* len_out) {
- Dart_Handle argHandle;
- int len = GetListLength(arguments, index, argHandle);
- if (len < 0) return NULL;
- GLint* list = new GLint[len];
- for (int i = 0; i < len; i++) {
- Dart_Handle vHandle = Dart_ListGetAt(argHandle, i);
- int64_t v;
- HandleError(Dart_IntegerToInt64(vHandle, &v));
- list[i] = v;
- }
- *len_out = len;
- return list;
-}
-
-GLfloat* GetArgsAsFloatList(Dart_NativeArguments arguments, int index,
- int* len_out) {
- Dart_Handle argHandle;
- int len = GetListLength(arguments, index, argHandle);
- if (len < 0) return NULL;
- GLfloat* list = new GLfloat[len];
- for (int i = 0; i < len; i++) {
- Dart_Handle vHandle = Dart_ListGetAt(argHandle, i);
- double v;
- HandleError(Dart_DoubleValue(vHandle, &v));
- list[i] = v;
- }
- *len_out = len;
- return list;
-}
-
-char** GetArgsAsStringList(Dart_NativeArguments arguments, int index,
- int* len_out) {
- Dart_Handle argHandle;
- int len = GetListLength(arguments, index, argHandle);
- if (len < 0) return NULL;
- char** list = new char*[len];
- for (int i = 0; i < len; i++) {
- Dart_Handle vHandle = Dart_ListGetAt(argHandle, i);
- uint8_t* str;
- intptr_t length;
- HandleError(Dart_StringLength(vHandle, &length));
- HandleError(Dart_StringToUTF8(vHandle, &str, &length));
- str[length] = 0;
- list[i] = reinterpret_cast<char*>(str);
- }
- *len_out = len;
- return list;
-}
-
-void SetBoolReturnValue(Dart_NativeArguments arguments, bool b) {
- Dart_Handle result = HandleError(Dart_NewBoolean(b));
- Dart_SetReturnValue(arguments, result);
-}
-
-void SetIntReturnValue(Dart_NativeArguments arguments, int v) {
- Dart_Handle result = HandleError(Dart_NewInteger(v));
- Dart_SetReturnValue(arguments, result);
-}
-
-void SetDoubleReturnValue(Dart_NativeArguments arguments, double v) {
- Dart_Handle result = HandleError(Dart_NewDouble(v));
- Dart_SetReturnValue(arguments, result);
-}
-
-void SetStringReturnValue(Dart_NativeArguments arguments, const char* s) {
- Dart_Handle result = HandleError(Dart_NewStringFromCString(s));
- Dart_SetReturnValue(arguments, result);
-}
-
-void Log(Dart_NativeArguments arguments) {
- Dart_EnterScope();
- LOGI("%s", GetArgAsString(arguments, 0));
- Dart_ExitScope();
-}
-
-void LogError(Dart_NativeArguments arguments) {
- Dart_EnterScope();
- LOGE("%s", GetArgAsString(arguments, 0));
- Dart_ExitScope();
-}
-
-void SystemRand(Dart_NativeArguments arguments) {
- Dart_EnterScope();
- SetIntReturnValue(arguments, rand());
- Dart_ExitScope();
-}
-
-void SystemSrand(Dart_NativeArguments arguments) {
- Dart_EnterScope();
- bool success = false;
- Dart_Handle seed_object = HandleError(Dart_GetNativeArgument(arguments, 0));
- if (Dart_IsInteger(seed_object)) {
- bool fits;
- HandleError(Dart_IntegerFitsIntoInt64(seed_object, &fits));
- if (fits) {
- int64_t seed;
- HandleError(Dart_IntegerToInt64(seed_object, &seed));
- srand(static_cast<unsigned>(seed));
- success = true;
- }
- }
- SetBoolReturnValue(arguments, success);
- Dart_ExitScope();
-}
-
-void GetDeviceScreenWidth(Dart_NativeArguments arguments) {
- LOGI("GetDeviceScreenWidth");
- Dart_EnterScope();
- SetIntReturnValue(arguments, graphics->width());
- Dart_ExitScope();
-}
-
-void GetDeviceScreenHeight(Dart_NativeArguments arguments) {
- LOGI("GetDeviceScreenHeight");
- Dart_EnterScope();
- SetIntReturnValue(arguments, graphics->height());
- Dart_ExitScope();
-}
-
-void SwapBuffers(Dart_NativeArguments arguments) {
- LOGI("SwapBuffers");
- Dart_EnterScope();
- GLSwapBuffers();
- CheckGLError("GLSwapBuffers");
- Dart_ExitScope();
-}
-
-void GLAttachShader(Dart_NativeArguments arguments) {
- LOGI("GLAttachShader");
- Dart_EnterScope();
-
- int64_t program = GetArgAsInt(arguments, 0);
- int64_t shader = GetArgAsInt(arguments, 1);
-
- glAttachShader(program, shader);
- CheckGLError("glAttachShader");
- Dart_ExitScope();
-}
-
-void GLBindBuffer(Dart_NativeArguments arguments) {
- LOGI("GLBindBuffer");
- Dart_EnterScope();
-
- int64_t target = GetArgAsInt(arguments, 0);
- int64_t buffer = GetArgAsInt(arguments, 1);
-
- glBindBuffer(target, buffer);
- CheckGLError("glBindBuffer");
- Dart_ExitScope();
-}
-
-void GLBufferData(Dart_NativeArguments arguments) {
- LOGI("GLBufferData");
- Dart_EnterScope();
-
- int64_t target = GetArgAsInt(arguments, 0);
-
- Dart_Handle dataHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
- intptr_t size;
- HandleError(Dart_ListLength(dataHandle, &size));
-
- LOGI("Size: %d", static_cast<int>(size));
-
- // TODO(vsm): No guarantee that this is a float!
- float* data = new float[size];
- for (int i = 0; i < size; i++) {
- Dart_Handle elemHandle = HandleError(Dart_ListGetAt(dataHandle, i));
- double value;
- Dart_DoubleValue(elemHandle, &value);
- data[i] = static_cast<float>(value);
- LOGI("Value[%d]: %f", i, data[i]);
- }
-
- Dart_Handle usageHandle = HandleError(Dart_GetNativeArgument(arguments, 2));
- int64_t usage;
- HandleError(Dart_IntegerToInt64(usageHandle, &usage));
-
- glBufferData(target, size * sizeof(data[0]), data, usage);
- CheckGLError("glBufferData");
- delete[] data;
- Dart_ExitScope();
-}
-
-void GLCompileShader(Dart_NativeArguments arguments) {
- LOGI("GLCompileShader");
- Dart_EnterScope();
- int64_t shader = GetArgAsInt(arguments, 0);
- glCompileShader(shader);
- CheckGLError("glCompileShader");
- Dart_ExitScope();
-}
-
-void GLCreateBuffer(Dart_NativeArguments arguments) {
- LOGI("GLCreateBuffer");
- Dart_EnterScope();
- GLuint buffer;
- glGenBuffers(1, &buffer);
- CheckGLError("glGenBuffers");
- SetIntReturnValue(arguments, buffer);
- Dart_ExitScope();
-}
-
-void GLCreateProgram(Dart_NativeArguments arguments) {
- LOGI("GLCreateProgram");
- Dart_EnterScope();
- int64_t program = glCreateProgram();
- CheckGLError("glCreateProgram");
- SetIntReturnValue(arguments, program);
- Dart_ExitScope();
-}
-
-void GLCreateShader(Dart_NativeArguments arguments) {
- LOGI("GLCreateShader");
- Dart_EnterScope();
- int64_t type = GetArgAsInt(arguments, 0);
- int64_t shader = glCreateShader((GLenum)type);
- CheckGLError("glCreateShader");
- SetIntReturnValue(arguments, shader);
- Dart_ExitScope();
-}
-
-void GLDrawArrays(Dart_NativeArguments arguments) {
- LOGI("GLDrawArrays");
- Dart_EnterScope();
-
- int64_t mode = GetArgAsInt(arguments, 0);
- int64_t first = GetArgAsInt(arguments, 1);
- int64_t count = GetArgAsInt(arguments, 2);
-
- glDrawArrays(mode, first, count);
- CheckGLError("glDrawArrays");
- Dart_ExitScope();
- LOGI("Done GLDrawArrays");
-}
-
-void GLEnableVertexAttribArray(Dart_NativeArguments arguments) {
- LOGI("GLEnableVertexAttribArray");
- Dart_EnterScope();
-
- int64_t location = GetArgAsInt(arguments, 0);
-
- glEnableVertexAttribArray(location);
- CheckGLError("glEnableVertexAttribArray");
- Dart_ExitScope();
-}
-
-void GLGetAttribLocation(Dart_NativeArguments arguments) {
- LOGI("GLGetAttribLocation");
- Dart_EnterScope();
-
- int64_t program = GetArgAsInt(arguments, 0);
-
- Dart_Handle nameHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
- intptr_t length;
- HandleError(Dart_StringLength(nameHandle, &length));
- uint8_t* str;
- HandleError(Dart_StringToUTF8(nameHandle, &str, &length));
- str[length] = 0;
-
- int64_t location = glGetAttribLocation(program,
- const_cast<const GLchar*>(reinterpret_cast<GLchar*>(str)));
- CheckGLError("glGetAttribLocation");
- SetIntReturnValue(arguments, location);
- Dart_ExitScope();
-}
-
-void GLGetError(Dart_NativeArguments arguments) {
- LOGI("GLGetError");
- Dart_EnterScope();
- SetIntReturnValue(arguments, glGetError());
- Dart_ExitScope();
-}
-
-void GLGetProgramParameter(Dart_NativeArguments arguments) {
- LOGI("GLGetProgramParameter");
- Dart_EnterScope();
-
- int64_t program = GetArgAsInt(arguments, 0);
- int64_t param = GetArgAsInt(arguments, 1);
-
- GLint value = -1;
- glGetProgramiv(program, param, &value);
- CheckGLError("glGetProgramiv");
-
- SetIntReturnValue(arguments, value);
- Dart_ExitScope();
-}
-
-void GLGetShaderParameter(Dart_NativeArguments arguments) {
- LOGI("GLGetShaderParameter");
- Dart_EnterScope();
-
- int64_t shader = GetArgAsInt(arguments, 0);
- int64_t param = GetArgAsInt(arguments, 1);
-
- GLint value = -1;
- glGetShaderiv((GLuint)shader, (GLenum)param, &value);
- CheckGLError("glGetShaderiv");
-
- SetIntReturnValue(arguments, value);
- Dart_ExitScope();
-}
-
-void GLGetShaderInfoLog(Dart_NativeArguments arguments) {
- LOGI("GLGetShaderInfoLog");
- Dart_EnterScope();
-
- int64_t shader = GetArgAsInt(arguments, 0);
-
- GLint infoLogLength = 0;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
- GLchar* strInfoLog = new GLchar[infoLogLength + 1];
- glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
- strInfoLog[infoLogLength] = 0;
-
- SetStringReturnValue(arguments, strInfoLog);
- Dart_ExitScope();
- delete[] strInfoLog;
-}
-
-void GLGetProgramInfoLog(Dart_NativeArguments arguments) {
- LOGI("GLGetProgramInfoLog");
- Dart_EnterScope();
-
- int64_t program = GetArgAsInt(arguments, 0);
-
- GLint infoLogLength;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
-
- GLchar* strInfoLog = new GLchar[infoLogLength + 1];
- glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
- strInfoLog[infoLogLength] = 0;
-
- SetStringReturnValue(arguments, strInfoLog);
- Dart_ExitScope();
- delete[] strInfoLog;
-}
-
-void GLGetUniformLocation(Dart_NativeArguments arguments) {
- LOGI("GLGetUniformLocation");
- Dart_EnterScope();
-
- int64_t program = GetArgAsInt(arguments, 0);
-
-
- Dart_Handle nameHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
- intptr_t length;
- HandleError(Dart_StringLength(nameHandle, &length));
- uint8_t* str;
- HandleError(Dart_StringToUTF8(nameHandle, &str, &length));
- str[length] = 0;
-
- int64_t location = glGetUniformLocation(program,
- const_cast<const GLchar*>(reinterpret_cast<GLchar*>(str)));
- CheckGLError("glGetUniformLocation");
- SetIntReturnValue(arguments, location);
- Dart_ExitScope();
-}
-
-void GLLinkProgram(Dart_NativeArguments arguments) {
- LOGI("GLLinkProgram");
- Dart_EnterScope();
- int64_t program = GetArgAsInt(arguments, 0);
- glLinkProgram(program);
- CheckGLError("glLinkProgram");
- Dart_ExitScope();
-}
-
-void GLShaderSource(Dart_NativeArguments arguments) {
- LOGI("GLShaderSource");
- Dart_EnterScope();
-
- int64_t shader = GetArgAsInt(arguments, 0);
-
- Dart_Handle sourceHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
- intptr_t length[1];
- HandleError(Dart_StringLength(sourceHandle, length));
- LOGI("Source length is %d", static_cast<int>(length[0]));
- uint8_t* str[1];
- HandleError(Dart_StringToUTF8(sourceHandle, &str[0], length));
- LOGI("Converted length is %d", static_cast<int>(length[0]));
- str[0][*length] = 0;
-
- LOGI("Source: %s",
- const_cast<const GLchar*>(reinterpret_cast<GLchar*>(str[0])));
- glShaderSource(shader, 1,
- const_cast<const GLchar**>(reinterpret_cast<GLchar**>(str)), NULL);
- CheckGLError("glShaderSource");
- Dart_ExitScope();
-}
-
-void GLUseProgram(Dart_NativeArguments arguments) {
- LOGI("GLUseProgram");
- Dart_EnterScope();
- int64_t program = GetArgAsInt(arguments, 0);
- glUseProgram(program);
- CheckGLError("glUseProgram");
- Dart_ExitScope();
-}
-
-void GLUniform1i(Dart_NativeArguments arguments) {
- LOGI("GLUniform1i");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int64_t v0 = GetArgAsInt(arguments, 1);
- glUniform1i(location, v0);
- CheckGLError("glUniform1i");
- Dart_ExitScope();
-}
-
-void GLUniform2i(Dart_NativeArguments arguments) {
- LOGI("GLUniform2i");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int64_t v0 = GetArgAsInt(arguments, 1);
- int64_t v1 = GetArgAsInt(arguments, 2);
- glUniform2i(location, v0, v1);
- CheckGLError("glUniform2i");
- Dart_ExitScope();
-}
-
-void GLUniform3i(Dart_NativeArguments arguments) {
- LOGI("GLUniform3i");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int64_t v0 = GetArgAsInt(arguments, 1);
- int64_t v1 = GetArgAsInt(arguments, 2);
- int64_t v2 = GetArgAsInt(arguments, 3);
- glUniform3i(location, v0, v1, v2);
- CheckGLError("glUniform3i");
- Dart_ExitScope();
-}
-
-void GLUniform4i(Dart_NativeArguments arguments) {
- LOGI("GLUniform4i");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int64_t v0 = GetArgAsInt(arguments, 1);
- int64_t v1 = GetArgAsInt(arguments, 2);
- int64_t v2 = GetArgAsInt(arguments, 3);
- int64_t v3 = GetArgAsInt(arguments, 4);
- glUniform4i(location, v0, v1, v2, v3);
- CheckGLError("glUniform4i");
- Dart_ExitScope();
-}
-
-void GLUniform1f(Dart_NativeArguments arguments) {
- LOGI("GLUniform1f");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- double v0 = GetArgAsDouble(arguments, 1);
- glUniform1f(location, v0);
- CheckGLError("glUniform1f");
- Dart_ExitScope();
-}
-
-void GLUniform2f(Dart_NativeArguments arguments) {
- LOGI("GLUniform2f");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- double v0 = GetArgAsDouble(arguments, 1);
- double v1 = GetArgAsDouble(arguments, 2);
- glUniform2f(location, v0, v1);
- CheckGLError("glUniform2f");
- Dart_ExitScope();
-}
-
-void GLUniform3f(Dart_NativeArguments arguments) {
- LOGI("GLUniform3f");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- double v0 = GetArgAsDouble(arguments, 1);
- double v1 = GetArgAsDouble(arguments, 2);
- double v2 = GetArgAsDouble(arguments, 3);
- glUniform3f(location, v0, v1, v2);
- CheckGLError("glUniform3f");
- Dart_ExitScope();
-}
-
-void GLUniform4f(Dart_NativeArguments arguments) {
- LOGI("GLUniform4f");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- double v0 = GetArgAsDouble(arguments, 1);
- double v1 = GetArgAsDouble(arguments, 2);
- double v2 = GetArgAsDouble(arguments, 3);
- double v3 = GetArgAsDouble(arguments, 4);
- glUniform4f(location, v0, v1, v2, v3);
- CheckGLError("glUniform4f");
- Dart_ExitScope();
-}
-
-void GLUniform1iv(Dart_NativeArguments arguments) {
- LOGI("GLUniform1iv");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int len;
- GLint* list = GetArgsAsGLintList(arguments, 1, &len);
- if (list != NULL) {
- glUniform1iv(location, len, list);
- delete [] list;
- CheckGLError("glUniform1iv");
- }
- Dart_ExitScope();
-}
-
-void GLUniform2iv(Dart_NativeArguments arguments) {
- LOGI("GLUniform2iv");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int len;
- GLint* list = GetArgsAsGLintList(arguments, 1, &len);
- if (list != NULL) {
- glUniform2iv(location, len / 2, list);
- delete [] list;
- CheckGLError("glUniform2iv");
- }
- Dart_ExitScope();
-}
-
-void GLUniform3iv(Dart_NativeArguments arguments) {
- LOGI("GLUniform3iv");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int len;
- GLint* list = GetArgsAsGLintList(arguments, 1, &len);
- if (list != NULL) {
- glUniform3iv(location, len / 3, list);
- delete [] list;
- CheckGLError("glUniform3iv");
- }
- Dart_ExitScope();
-}
-
-void GLUniform4iv(Dart_NativeArguments arguments) {
- LOGI("GLUniform4iv");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int len;
- GLint* list = GetArgsAsGLintList(arguments, 1, &len);
- if (list != NULL) {
- glUniform1iv(location, len / 4, list);
- delete [] list;
- CheckGLError("glUniform4iv");
- }
- Dart_ExitScope();
-}
-
-void GLUniform1fv(Dart_NativeArguments arguments) {
- LOGI("GLUniform1fv");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int len;
- GLfloat* list = GetArgsAsFloatList(arguments, 1, &len);
- if (list != NULL) {
- glUniform1fv(location, len, list);
- delete [] list;
- CheckGLError("glUniform1fv");
- }
- Dart_ExitScope();
-}
-
-void GLUniform2fv(Dart_NativeArguments arguments) {
- LOGI("GLUniform2fv");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int len;
- GLfloat* list = GetArgsAsFloatList(arguments, 1, &len);
- if (list != NULL) {
- glUniform2fv(location, len / 2, list);
- delete [] list;
- CheckGLError("glUniform2fv");
- }
- Dart_ExitScope();
-}
-
-void GLUniform3fv(Dart_NativeArguments arguments) {
- LOGI("GLUniform3fv");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int len;
- GLfloat* list = GetArgsAsFloatList(arguments, 1, &len);
- if (list != NULL) {
- glUniform3fv(location, len / 3, list);
- delete [] list;
- CheckGLError("glUniform3fv");
- }
- Dart_ExitScope();
-}
-
-void GLUniform4fv(Dart_NativeArguments arguments) {
- LOGI("In GLUniform4fv");
- Dart_EnterScope();
- int64_t location = GetArgAsInt(arguments, 0);
- int len;
- GLfloat* list = GetArgsAsFloatList(arguments, 1, &len);
- if (list != NULL) {
- glUniform4fv(location, len / 4, list);
- delete [] list;
- CheckGLError("glUniform4fv");
- }
- Dart_ExitScope();
-}
-
-void GLViewport(Dart_NativeArguments arguments) {
- LOGI("GLViewport");
- Dart_EnterScope();
- int64_t x = GetArgAsInt(arguments, 0);
- int64_t y = GetArgAsInt(arguments, 1);
- int64_t width = GetArgAsInt(arguments, 2);
- int64_t height = GetArgAsInt(arguments, 3);
- glViewport(x, y, width, height);
- CheckGLError("glViewPort");
- Dart_ExitScope();
-}
-
-void GLVertexAttribPointer(Dart_NativeArguments arguments) {
- LOGI("GLVertexAttribPointer");
- Dart_EnterScope();
- int64_t index = GetArgAsInt(arguments, 0);
- int64_t size = GetArgAsInt(arguments, 1);
- int64_t type = GetArgAsInt(arguments, 2);
- bool normalized = GetArgAsBool(arguments, 3);
- int64_t stride = GetArgAsInt(arguments, 4);
-
- Dart_Handle pointerHandle = HandleError(Dart_GetNativeArgument(arguments, 5));
- int64_t pointerValue;
- HandleError(Dart_IntegerToInt64(pointerHandle, &pointerValue));
- const void* pointer;
- pointer = const_cast<const void*>(reinterpret_cast<void*>(pointerValue));
-
- glVertexAttribPointer(index, size, type, normalized, stride, pointer);
- CheckGLError("glVertexAttribPointer");
- Dart_ExitScope();
-}
-
-void GLClearColor(Dart_NativeArguments arguments) {
- LOGI("GLClearColor");
- Dart_EnterScope();
- double red = GetArgAsDouble(arguments, 0);
- double green = GetArgAsDouble(arguments, 1);
- double blue = GetArgAsDouble(arguments, 2);
- double alpha = GetArgAsDouble(arguments, 3);
- glClearColor(red, green, blue, alpha);
- CheckGLError("glClearColor");
- Dart_ExitScope();
-}
-
-void GLClearDepth(Dart_NativeArguments arguments) {
- LOGI("GLClearDepth");
- Dart_EnterScope();
- double depth = GetArgAsDouble(arguments, 0);
-#if defined(__ANDROID__)
- glClearDepthf(depth);
-#else
- glClearDepth(depth);
-#endif
- CheckGLError("glClearDepth");
- Dart_ExitScope();
-}
-
-void GLClear(Dart_NativeArguments arguments) {
- LOGI("GLClear");
- Dart_EnterScope();
- Dart_Handle maskHandle = HandleError(Dart_GetNativeArgument(arguments, 0));
- int64_t mask;
- HandleError(Dart_IntegerToInt64(maskHandle, &mask));
- glClear(mask);
- CheckGLError("glClear");
- Dart_ExitScope();
-}
-
-void ReturnGLIntConstant(Dart_NativeArguments arguments, int c) {
- Dart_EnterScope();
- SetIntReturnValue(arguments, c);
- Dart_ExitScope();
-}
-
-void GLArrayBuffer(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_ARRAY_BUFFER);
-}
-
-void GLColorBufferBit(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_COLOR_BUFFER_BIT);
-}
-
-void GLCompileStatus(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_COMPILE_STATUS);
-}
-
-void GLDeleteStatus(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_DELETE_STATUS);
-}
-
-void GLDepthBufferBit(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_DEPTH_BUFFER_BIT);
-}
-
-void GLFloat(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_FLOAT);
-}
-
-void GLFragmentShader(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_FRAGMENT_SHADER);
-}
-
-void GLLinkStatus(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_LINK_STATUS);
-}
-
-void GLStaticDraw(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_STATIC_DRAW);
-}
-
-void GLTriangleStrip(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_TRIANGLE_STRIP);
-}
-
-void GLTriangles(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_TRIANGLES);
-}
-
-void GLTrue(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_TRUE);
-}
-
-void GLValidateStatus(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_VALIDATE_STATUS);
-}
-
-void GLVertexShader(Dart_NativeArguments arguments) {
- ReturnGLIntConstant(arguments, GL_VERTEX_SHADER);
-}
-
-uint8_t* RandomArray(int seed, int length) {
- if (length <= 0 || length > 10000000) return NULL;
- uint8_t* values = reinterpret_cast<uint8_t*>(malloc(length));
- if (NULL == values) return NULL;
- srand(seed);
- for (int i = 0; i < length; ++i) {
- values[i] = rand() % 256;
- }
- return values;
-}
-
-void WrappedRandomArray(Dart_Port dest_port_id,
- Dart_Port reply_port_id,
- Dart_CObject* message) {
- if (message->type == Dart_CObject_kArray &&
- 2 == message->value.as_array.length) {
- // Use .as_array and .as_int32 to access the data in the Dart_CObject.
- Dart_CObject* param0 = message->value.as_array.values[0];
- Dart_CObject* param1 = message->value.as_array.values[1];
- if (param0->type == Dart_CObject_kInt32 &&
- param1->type == Dart_CObject_kInt32) {
- int length = param0->value.as_int32;
- int seed = param1->value.as_int32;
-
- uint8_t* values = RandomArray(seed, length);
-
- if (values != NULL) {
- Dart_CObject result;
- result.type = Dart_CObject_kTypedData;
- result.value.as_typed_data.type = Dart_TypedData_kUint8;
- result.value.as_typed_data.values = values;
- result.value.as_typed_data.length = length;
- Dart_PostCObject(reply_port_id, &result);
- free(values);
- // It is OK that result is destroyed when function exits.
- // Dart_PostCObject has copied its data.
- return;
- }
- }
- }
- Dart_CObject result;
- result.type = Dart_CObject_kNull;
- Dart_PostCObject(reply_port_id, &result);
-}
-
-void RandomArrayServicePort(Dart_NativeArguments arguments) {
- Dart_EnterScope();
- Dart_SetReturnValue(arguments, Dart_Null());
- Dart_Port service_port =
- Dart_NewNativePort("RandomArrayService", WrappedRandomArray, true);
- if (service_port != ((Dart_Port)0)) {
- Dart_Handle send_port = HandleError(Dart_NewSendPort(service_port));
- Dart_SetReturnValue(arguments, send_port);
- }
- Dart_ExitScope();
-}
-
-void PlayBackground(Dart_NativeArguments arguments) {
- LOGI("PlayBackground");
- Dart_EnterScope();
- const char* what = GetArgAsString(arguments, 0);
- int rtn = PlayBackgroundSound(what);
- SetIntReturnValue(arguments, rtn);
- Dart_ExitScope();
-}
-
-void StopBackground(Dart_NativeArguments arguments) {
- LOGI("StopBackground");
- Dart_EnterScope();
- StopBackgroundSound();
- Dart_ExitScope();
-}
-
-void LoadSample(Dart_NativeArguments arguments) {
- LOGI("LoadSample");
- Dart_EnterScope();
- const char* what = GetArgAsString(arguments, 0);
- int rtn = LoadSoundSample(what);
- SetIntReturnValue(arguments, rtn);
- Dart_ExitScope();
-}
-
-void PlaySample(Dart_NativeArguments arguments) {
- LOGI("PlaySample");
- Dart_EnterScope();
- const char* what = GetArgAsString(arguments, 0);
- int rtn = PlaySoundSample(what);
- SetIntReturnValue(arguments, rtn);
- Dart_ExitScope();
-}
-
-// 2D Canvas.
-
-CanvasContext* display_context = NULL;
-
-void C2DCreateNativeContext(Dart_NativeArguments arguments) {
- LOGI("In C2DCreateNativeContext");
- Dart_EnterScope();
-
- int handle = GetArgAsInt(arguments, 0);
- int width = GetArgAsInt(arguments, 1);
- int height = GetArgAsInt(arguments, 2);
-
- CanvasContext* rtn = new CanvasContext(handle, width, height);
- if (display_context == NULL) {
- LOGI("Created display context");
- display_context = rtn;
- }
- Dart_ExitScope();
- LOGI("Out C2DCreateNativeContext");
-}
-
-void C2DSetWidth(Dart_NativeArguments arguments) {
- LOGI("In C2DSetWidth");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- int width = GetArgAsInt(arguments, 1);
- SetIntReturnValue(arguments, Context2D(handle)->setWidth(width));
- Dart_ExitScope();
- LOGI("Out C2DSetWidth");
-}
-
-void C2DSetHeight(Dart_NativeArguments arguments) {
- LOGI("In C2DSetHeight");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- int height = GetArgAsInt(arguments, 1);
- SetIntReturnValue(arguments, Context2D(handle)->setHeight(height));
- Dart_ExitScope();
- LOGI("Out C2DSetHeight");
-}
-
-void C2DSetGlobalAlpha(Dart_NativeArguments arguments) {
- LOGI("In C2DSetGlobalAlpha");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double alpha = GetArgAsDouble(arguments, 1);
- alpha = MIN(1.0, MAX(alpha, 0.0));
- Context2D(handle)->setGlobalAlpha(alpha);
- SetDoubleReturnValue(arguments, alpha);
- Dart_ExitScope();
- LOGI("Out C2DSetGlobalAlpha");
-}
-
-void C2DSetFillStyle(Dart_NativeArguments arguments) {
- LOGI("In C2DSetFillStyle");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* color = GetArgAsString(arguments, 1);
- Context2D(handle)->setFillColor(color);
- Dart_ExitScope();
- LOGI("Out C2DSetFillStyle");
-}
-
-void C2DSetFont(Dart_NativeArguments arguments) {
- LOGI("In C2DSetFont");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* font = GetArgAsString(arguments, 1);
- SetStringReturnValue(arguments, Context2D(handle)->setFont(font));
- Dart_ExitScope();
- LOGI("Out C2DSetFont");
-}
-
-void C2DSetGlobalCompositeOperation(Dart_NativeArguments arguments) {
- LOGI("In C2DSetGlobalCompositeOperation");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* op = GetArgAsString(arguments, 1);
- Context2D(handle)->setGlobalCompositeOperation(op);
- Dart_ExitScope();
- LOGI("Out C2DSetGlobalCompositeOperation");
-}
-
-void C2DSetLineCap(Dart_NativeArguments arguments) {
- LOGI("In C2DSetLineCap");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* lc = GetArgAsString(arguments, 1);
- Context2D(handle)->setLineCap(lc);
- Dart_ExitScope();
- LOGI("Out C2DSetLineCap");
-}
-
-void C2DSetLineJoin(Dart_NativeArguments arguments) {
- LOGI("In C2DSetLineJoin");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* lj = GetArgAsString(arguments, 1);
- Context2D(handle)->setLineJoin(lj);
- Dart_ExitScope();
- LOGI("Out C2DSetLineJoin");
-}
-
-void C2DSetLineWidth(Dart_NativeArguments arguments) {
- LOGI("In C2DSetLineWidth");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double w = GetArgAsDouble(arguments, 1);
- Context2D(handle)->setLineWidth(w);
- Dart_ExitScope();
- LOGI("Out C2DSetLineWidth");
-}
-
-void C2DSetMiterLimit(Dart_NativeArguments arguments) {
- LOGI("In C2DSetMiterLimit");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double w = GetArgAsDouble(arguments, 1);
- Context2D(handle)->setMiterLimit(w);
- Dart_ExitScope();
- LOGI("Out C2DSetMiterLimit");
-}
-
-void C2DSetShadowBlur(Dart_NativeArguments arguments) {
- LOGI("In C2DSetShadowBlur");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double blur = GetArgAsDouble(arguments, 1);
- Context2D(handle)->setShadowBlur(blur);
- Dart_ExitScope();
- LOGI("Out C2DSetShadowBlur");
-}
-
-void C2DSetShadowColor(Dart_NativeArguments arguments) {
- LOGI("In C2DSetShadowColor");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* color = GetArgAsString(arguments, 1);
- Context2D(handle)->setShadowColor(color);
- Dart_ExitScope();
- LOGI("Out C2DSetShadowColor");
-}
-
-void C2DSetShadowOffsetX(Dart_NativeArguments arguments) {
- LOGI("In C2DSetShadowOffsetX");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double offset = GetArgAsDouble(arguments, 1);
- Context2D(handle)->setShadowOffsetX(offset);
- Dart_ExitScope();
- LOGI("Out C2DSetShadowOffsetX");
-}
-
-void C2DSetShadowOffsetY(Dart_NativeArguments arguments) {
- LOGI("In C2DSetShadowOffsetY");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double offset = GetArgAsDouble(arguments, 1);
- Context2D(handle)->setShadowOffsetY(offset);
- Dart_ExitScope();
- LOGI("Out C2DSetShadowOffsetY");
-}
-
-void C2DSetStrokeStyle(Dart_NativeArguments arguments) {
- LOGI("In C2DSetStrokeStyle");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* color = GetArgAsString(arguments, 1);
- Context2D(handle)->setStrokeColor(color);
- Dart_ExitScope();
- LOGI("Out C2DSetStrokeStyle");
-}
-
-void C2DSetTextAlign(Dart_NativeArguments arguments) {
- LOGI("In C2DSetTextAlign");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* align = GetArgAsString(arguments, 1);
- SetStringReturnValue(arguments, Context2D(handle)->setTextAlign(align));
- Dart_ExitScope();
- LOGI("Out C2DSetTextAlign");
-}
-
-void C2DSetTextBaseline(Dart_NativeArguments arguments) {
- LOGI("In C2DSetTextBaseline");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* baseline = GetArgAsString(arguments, 1);
- SetStringReturnValue(arguments, Context2D(handle)->setTextBaseline(baseline));
- Dart_ExitScope();
- LOGI("Out C2DSetTextBaseline");
-}
-
-void C2DGetImageSmoothingEnabled(Dart_NativeArguments arguments) {
- LOGI("In C2DGetImageSmoothingEnabled");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- SetDoubleReturnValue(arguments, Context2D(handle)->imageSmoothingEnabled());
- Dart_ExitScope();
- LOGI("Out C2DGetImageSmoothingEnabled");
-}
-
-void C2DArc(Dart_NativeArguments arguments) {
- LOGI("In C2DArc");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double x = GetArgAsDouble(arguments, 1);
- double y = GetArgAsDouble(arguments, 2);
- double r = GetArgAsDouble(arguments, 3);
- double a1 = GetArgAsDouble(arguments, 4);
- double a2 = GetArgAsDouble(arguments, 5);
- bool anticlockwise = GetArgAsBool(arguments, 6);
- Context2D(handle)->Arc(x, y, r, a1, a2, anticlockwise);
- Dart_ExitScope();
- LOGI("Out C2DArc");
-}
-
-void C2DArcTo(Dart_NativeArguments arguments) {
- LOGI("In C2DArcTo");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double x1 = GetArgAsDouble(arguments, 1);
- double y1 = GetArgAsDouble(arguments, 2);
- double x2 = GetArgAsDouble(arguments, 3);
- double y2 = GetArgAsDouble(arguments, 4);
- double radius = GetArgAsDouble(arguments, 5);
- Context2D(handle)->ArcTo(x1, y1, x2, y2, radius);
- Dart_ExitScope();
- LOGI("Out C2DArcTo");
-}
-
-void C2DBeginPath(Dart_NativeArguments arguments) {
- LOGI("In C2DBeginPath");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- Context2D(handle)->BeginPath();
- Dart_ExitScope();
- LOGI("Out C2DBeginPath");
-}
-
-void C2DBezierCurveTo(Dart_NativeArguments arguments) {
- LOGI("In C2DBezierCurveTo");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double cp1x = GetArgAsDouble(arguments, 1);
- double cp1y = GetArgAsDouble(arguments, 2);
- double cp2x = GetArgAsDouble(arguments, 3);
- double cp2y = GetArgAsDouble(arguments, 4);
- double x = GetArgAsDouble(arguments, 5);
- double y = GetArgAsDouble(arguments, 6);
- Context2D(handle)->BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
- Dart_ExitScope();
- LOGI("Out C2DBezierCurveTo");
-}
-
-void C2DClearRect(Dart_NativeArguments arguments) {
- LOGI("In C2DClearRect");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double left = GetArgAsDouble(arguments, 1);
- double top = GetArgAsDouble(arguments, 2);
- double width = GetArgAsDouble(arguments, 3);
- double height = GetArgAsDouble(arguments, 4);
- Context2D(handle)->ClearRect(left, top, width, height);
- Dart_ExitScope();
- LOGI("Out C2DClearRect");
-}
-
-void C2DClip(Dart_NativeArguments arguments) {
- LOGI("In C2DClip");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- Context2D(handle)->Clip();
- Dart_ExitScope();
- LOGI("Out C2DClip");
-}
-
-void C2DClosePath(Dart_NativeArguments arguments) {
- LOGI("In C2DClosePath");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- Context2D(handle)->ClosePath();
- Dart_ExitScope();
- LOGI("Out C2DClosePath");
-}
-
-void C2DCreateImageDataFromDimensions(Dart_NativeArguments arguments) {
- LOGI("In C2DCreateImageDataFromDimensions");
- Dart_EnterScope();
- // int handle = GetArgAsInt(arguments, 0);
- // double sw = GetArgAsDouble(arguments, 1);
- // double sh = GetArgAsDouble(arguments, 2);
- // GLubyte* pixels = (GLubyte*)calloc(sw * sh * 4, sizeof(GLubyte));
- // ImageData* imageData = new ImageData(sw, sh, pixels);
- // TODO(gram): How do we create a Dart ImageData object from this?
- Dart_ExitScope();
- LOGI("Out C2DCreateImageDataFromDimensions");
-}
-
-void C2DDrawImage(Dart_NativeArguments arguments) {
- LOGI("In C2DDrawImage");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* src_url = GetArgAsString(arguments, 1);
- int sx = GetArgAsInt(arguments, 2);
- int sy = GetArgAsInt(arguments, 3);
- bool has_src_dimensions = GetArgAsBool(arguments, 4);
- int sw = GetArgAsInt(arguments, 5);
- int sh = GetArgAsInt(arguments, 6);
- int dx = GetArgAsInt(arguments, 7);
- int dy = GetArgAsInt(arguments, 8);
- bool has_dst_dimensions = GetArgAsBool(arguments, 9);
- int dw = GetArgAsInt(arguments, 10);
- int dh = GetArgAsInt(arguments, 11);
- Context2D(handle)->DrawImage(src_url,
- sx, sy, has_src_dimensions, sw, sh,
- dx, dy, has_dst_dimensions, dw, dh);
- Dart_ExitScope();
- LOGI("Out C2DDrawImage");
-}
-
-void C2DFill(Dart_NativeArguments arguments) {
- LOGI("In C2DFill");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- Context2D(handle)->Fill();
- Dart_ExitScope();
- LOGI("Out C2DFill");
-}
-
-void C2DFillRect(Dart_NativeArguments arguments) {
- LOGI("In C2DFillRect");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double left = GetArgAsDouble(arguments, 1);
- double top = GetArgAsDouble(arguments, 2);
- double width = GetArgAsDouble(arguments, 3);
- double height = GetArgAsDouble(arguments, 4);
- Context2D(handle)->FillRect(left, top, width, height);
- Dart_ExitScope();
- LOGI("Out C2DFillRect");
-}
-
-void C2DFillText(Dart_NativeArguments arguments) {
- LOGI("In C2DFillText");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* text = GetArgAsString(arguments, 1);
- double x = GetArgAsDouble(arguments, 2);
- double y = GetArgAsDouble(arguments, 3);
- double maxWidth = GetArgAsDouble(arguments, 4);
- Context2D(handle)->FillText(text, x, y, maxWidth);
- Dart_ExitScope();
- LOGI("Out C2DFillText");
-}
-
-void C2DGetImageData(Dart_NativeArguments arguments) {
- LOGI("In C2DGetImageData");
- Dart_EnterScope();
- // TODO(gram): Complete this.
- // int handle = GetArgAsInt(arguments, 0);
- // double sx = GetArgAsDouble(arguments, 1);
- // double sy = GetArgAsDouble(arguments, 2);
- // double sw = GetArgAsDouble(arguments, 3);
- // double sh = GetArgAsDouble(arguments, 4);
- // ... = Context2D(handle)->GetImageData(text, x, y, maxWidth);
- Dart_ExitScope();
- LOGI("Out C2DGetImageData");
-}
-
-void C2DLineTo(Dart_NativeArguments arguments) {
- LOGI("In C2DLineTo");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double x = GetArgAsDouble(arguments, 1);
- double y = GetArgAsDouble(arguments, 2);
- Context2D(handle)->LineTo(x, y);
- Dart_ExitScope();
- LOGI("Out C2DLineTo");
-}
-
-void C2DMeasureText(Dart_NativeArguments arguments) {
- LOGI("In C2DMeasureText");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* text = GetArgAsString(arguments, 1);
- float width = Context2D(handle)->MeasureText(text);
- SetDoubleReturnValue(arguments, width);
- Dart_ExitScope();
- LOGI("Out C2DMeasureText");
-}
-
-void C2DMoveTo(Dart_NativeArguments arguments) {
- LOGI("IN C2DMoveTo");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double x = GetArgAsDouble(arguments, 1);
- double y = GetArgAsDouble(arguments, 2);
- Context2D(handle)->MoveTo(x, y);
- Dart_ExitScope();
- LOGI("Out C2DMoveTo");
-}
-
-void C2DPutImageData(Dart_NativeArguments arguments) {
- LOGI("IN C2DPutImageData");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- // Get object arguments 2
- // BindingImageData* imageData = GetArgAsObject(arguments, 1);
- double dx = GetArgAsDouble(arguments, 2);
- double dy = GetArgAsDouble(arguments, 3);
- Context2D(handle)->PutImageData(NULL, dx, dy);
- Dart_ExitScope();
- LOGI("Out C2DPutImageData");
-}
-
-void C2DQuadraticCurveTo(Dart_NativeArguments arguments) {
- LOGI("In C2DQuadraticCurveTo");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double cpx = GetArgAsDouble(arguments, 1);
- double cpy = GetArgAsDouble(arguments, 2);
- double x = GetArgAsDouble(arguments, 3);
- double y = GetArgAsDouble(arguments, 4);
- Context2D(handle)->QuadraticCurveTo(cpx, cpy, x, y);
- Dart_ExitScope();
- LOGI("Out C2DQuadraticCurveTo");
-}
-
-void C2DRect(Dart_NativeArguments arguments) {
- LOGI("In C2DRect");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double x = GetArgAsDouble(arguments, 1);
- double y = GetArgAsDouble(arguments, 2);
- double w = GetArgAsDouble(arguments, 3);
- double h = GetArgAsDouble(arguments, 4);
- Context2D(handle)->Rect(x, y, w, h);
- Dart_ExitScope();
- LOGI("Out C2DRect");
-}
-
-void C2DRestore(Dart_NativeArguments arguments) {
- LOGI("In C2DRestore");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- CanvasContext* context = Context2D(handle);
- context->Restore();
- Dart_ExitScope();
- LOGI("Out C2DRestore");
-}
-
-void C2DRotate(Dart_NativeArguments arguments) {
- LOGI("In C2DRotate");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double a = GetArgAsDouble(arguments, 1);
- Context2D(handle)->Rotate(a);
- Dart_ExitScope();
- LOGI("Out C2DRotate");
-}
-
-void C2DSave(Dart_NativeArguments arguments) {
- LOGI("In C2DSave");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- Context2D(handle)->Save();
- Dart_ExitScope();
- LOGI("Out C2DSave");
-}
-
-void C2DScale(Dart_NativeArguments arguments) {
- LOGI("In C2DScale");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double sx = GetArgAsDouble(arguments, 1);
- double sy = GetArgAsDouble(arguments, 2);
- Context2D(handle)->Scale(sx, sy);
- Dart_ExitScope();
- LOGI("Out C2DScale");
-}
-
-void C2DSetLineDash(Dart_NativeArguments arguments) {
- LOGI("In C2DSetLineDash");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- int len;
- float* dash = static_cast<float*>(GetArgsAsFloatList(arguments, 1, &len));
- if (dash != NULL) {
- Context2D(handle)->setLineDash(dash, len);
- delete[] dash;
- }
- Dart_ExitScope();
- LOGI("Out C2DSetLineDash");
-}
-
-void C2DSetLineDashOffset(Dart_NativeArguments arguments) {
- LOGI("In C2DSetLineDashOffset");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double offset = GetArgAsDouble(arguments, 1);
- Context2D(handle)->setLineDashOffset(offset);
- Dart_ExitScope();
- LOGI("Out C2DSetLineDashOffset");
-}
-
-void C2DSetTransform(Dart_NativeArguments arguments) {
- LOGI("In C2DSetTransform");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double m11 = GetArgAsDouble(arguments, 1);
- double m12 = GetArgAsDouble(arguments, 2);
- double m21 = GetArgAsDouble(arguments, 3);
- double m22 = GetArgAsDouble(arguments, 4);
- double dx = GetArgAsDouble(arguments, 5);
- double dy = GetArgAsDouble(arguments, 6);
- Context2D(handle)->setTransform(m11, m12, m21, m22, dx, dy);
- Dart_ExitScope();
- LOGI("Out C2DSetTransform");
-}
-
-void C2DStroke(Dart_NativeArguments arguments) {
- LOGI("In C2DStroke");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- Context2D(handle)->Stroke();
- Dart_ExitScope();
- LOGI("Out C2DStroke");
-}
-
-void C2DStrokeRect(Dart_NativeArguments arguments) {
- LOGI("In C2DStrokeRect");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double left = GetArgAsDouble(arguments, 1);
- double top = GetArgAsDouble(arguments, 2);
- double width = GetArgAsDouble(arguments, 3);
- double height = GetArgAsDouble(arguments, 4);
- Context2D(handle)->StrokeRect(left, top, width, height);
- Dart_ExitScope();
- LOGI("Out C2DStrokeRect");
-}
-
-void C2DStrokeText(Dart_NativeArguments arguments) {
- LOGI("In C2DStrokeText");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- const char* text = GetArgAsString(arguments, 1);
- double x = GetArgAsDouble(arguments, 2);
- double y = GetArgAsDouble(arguments, 3);
- double maxWidth = GetArgAsDouble(arguments, 4);
- Context2D(handle)->StrokeText(text, x, y, maxWidth);
- Dart_ExitScope();
- LOGI("Out C2DStrokeText");
-}
-
-void C2DTransform(Dart_NativeArguments arguments) {
- LOGI("In C2DTransform");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double m11 = GetArgAsDouble(arguments, 1);
- double m12 = GetArgAsDouble(arguments, 2);
- double m21 = GetArgAsDouble(arguments, 3);
- double m22 = GetArgAsDouble(arguments, 4);
- double dx = GetArgAsDouble(arguments, 5);
- double dy = GetArgAsDouble(arguments, 6);
- Context2D(handle)->Transform(m11, m12, m21, m22, dx, dy);
- Dart_ExitScope();
- LOGI("Out C2DTransform");
-}
-
-void C2DTranslate(Dart_NativeArguments arguments) {
- LOGI("In C2DTranslate");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- double x = GetArgAsDouble(arguments, 1);
- double y = GetArgAsDouble(arguments, 2);
- Context2D(handle)->Translate(x, y);
- Dart_ExitScope();
- LOGI("Out C2DTranslate");
-}
-
-void C2DSetFillGradient(Dart_NativeArguments arguments) {
- LOGI("In C2DSetFillGradient");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- bool is_radial = GetArgAsBool(arguments, 1);
- double x0 = GetArgAsDouble(arguments, 2);
- double y0 = GetArgAsDouble(arguments, 3);
- double r0 = GetArgAsDouble(arguments, 4);
- double x1 = GetArgAsDouble(arguments, 5);
- double y1 = GetArgAsDouble(arguments, 6);
- double r1 = GetArgAsDouble(arguments, 7);
- int num_positions, num_colors;
- float* positions = GetArgsAsFloatList(arguments, 8, &num_positions);
- char** colors = GetArgsAsStringList(arguments, 9, &num_colors);
- Context2D(handle)->SetFillGradient(is_radial, x0, y0, r0, x1, y1, r1,
- num_positions, positions, colors);
- Dart_ExitScope();
- LOGI("Out C2DSetFillGradient");
-}
-
-void C2DSetStrokeGradient(Dart_NativeArguments arguments) {
- LOGI("In C2DSetStrokeGradient");
- Dart_EnterScope();
- int handle = GetArgAsInt(arguments, 0);
- bool is_radial = GetArgAsBool(arguments, 1);
- double x0 = GetArgAsDouble(arguments, 2);
- double y0 = GetArgAsDouble(arguments, 3);
- double r0 = GetArgAsDouble(arguments, 4);
- double x1 = GetArgAsDouble(arguments, 5);
- double y1 = GetArgAsDouble(arguments, 6);
- double r1 = GetArgAsDouble(arguments, 7);
- int num_positions, num_colors;
- float* positions = GetArgsAsFloatList(arguments, 8, &num_positions);
- char** colors = GetArgsAsStringList(arguments, 9, &num_colors);
- Context2D(handle)->SetStrokeGradient(is_radial, x0, y0, r0, x1, y1, r1,
- num_positions, positions, colors);
- Dart_ExitScope();
- LOGI("Out C2DSetStrokeGradient");
-}
-
-void C2DGetImageWidth(Dart_NativeArguments arguments) {
- LOGI("In C2DGetImageWidth");
- Dart_EnterScope();
- const char* src_url = GetArgAsString(arguments, 0);
- int w = ImageCache::GetWidth(src_url);
- SetIntReturnValue(arguments, w);
- Dart_ExitScope();
- LOGI("Out C2DGetImageWidth");
-}
-
-void C2DGetImageHeight(Dart_NativeArguments arguments) {
- LOGI("In C2DGetImageHeight");
- Dart_EnterScope();
- const char* src_url = GetArgAsString(arguments, 0);
- int h = ImageCache::GetHeight(src_url);
- SetIntReturnValue(arguments, h);
- Dart_ExitScope();
- LOGI("Out C2DGetImageHeight");
-}
-
-struct FunctionLookup {
- const char* name;
- Dart_NativeFunction function;
-};
-
-FunctionLookup function_list[] = {
- {"Log", Log},
- {"LogError", LogError},
- {"SystemRand", SystemRand},
- {"SystemSrand", SystemSrand},
- {"SwapBuffers", SwapBuffers},
- {"GetDeviceScreenWidth", GetDeviceScreenWidth},
- {"GetDeviceScreenHeight", GetDeviceScreenHeight},
- {"GLAttachShader", GLAttachShader},
- {"GLBindBuffer", GLBindBuffer},
- {"GLBufferData", GLBufferData},
- {"GLClear", GLClear},
- {"GLClearColor", GLClearColor},
- {"GLClearDepth", GLClearDepth},
- {"GLCompileShader", GLCompileShader},
- {"GLCreateBuffer", GLCreateBuffer},
- {"GLCreateProgram", GLCreateProgram},
- {"GLCreateShader", GLCreateShader},
- {"GLDrawArrays", GLDrawArrays},
- {"GLEnableVertexAttribArray", GLEnableVertexAttribArray},
- {"GLGetAttribLocation", GLGetAttribLocation},
- {"GLGetError", GLGetError},
- {"GLGetProgramParameter", GLGetProgramParameter},
- {"GLGetShaderParameter", GLGetShaderParameter},
- {"GLGetUniformLocation", GLGetUniformLocation},
- {"GLLinkProgram", GLLinkProgram},
- {"GLShaderSource", GLShaderSource},
- {"GLUniform1f", GLUniform1f},
- {"GLUniform2f", GLUniform2f},
- {"GLUniform3f", GLUniform3f},
- {"GLUniform4f", GLUniform4f},
- {"GLUniform1i", GLUniform1i},
- {"GLUniform2i", GLUniform2i},
- {"GLUniform3i", GLUniform3i},
- {"GLUniform4i", GLUniform4i},
- {"GLUniform1fv", GLUniform1fv},
- {"GLUniform2fv", GLUniform2fv},
- {"GLUniform3fv", GLUniform3fv},
- {"GLUniform4fv", GLUniform4fv},
- {"GLUniform1iv", GLUniform1iv},
- {"GLUniform2iv", GLUniform2iv},
- {"GLUniform3iv", GLUniform3iv},
- {"GLUniform4iv", GLUniform4iv},
- {"GLUseProgram", GLUseProgram},
- {"GLVertexAttribPointer", GLVertexAttribPointer},
- {"GLViewport", GLViewport},
- {"GLArrayBuffer", GLArrayBuffer},
- {"GLColorBufferBit", GLColorBufferBit},
- {"GLCompileStatus", GLCompileStatus},
- {"GLDeleteStatus", GLDeleteStatus},
- {"GLDepthBufferBit", GLDepthBufferBit},
- {"GLFloat", GLFloat},
- {"GLFragmentShader", GLFragmentShader},
- {"GLLinkStatus", GLLinkStatus},
- {"GLTriangleStrip", GLTriangleStrip},
- {"GLTriangles", GLTriangles},
- {"GLTrue", GLTrue},
- {"GLStaticDraw", GLStaticDraw},
- {"GLValidateStatus", GLValidateStatus},
- {"GLVertexShader", GLVertexShader},
- {"GLGetShaderInfoLog", GLGetShaderInfoLog},
- {"GLGetProgramInfoLog", GLGetProgramInfoLog},
- {"RandomArray_ServicePort", RandomArrayServicePort},
-
- // Audio support.
- {"PlayBackground", PlayBackground},
- {"StopBackground", StopBackground},
- {"LoadSample", LoadSample},
- {"PlaySample", PlaySample},
-
- // 2D Support
-
- { "C2DCreateNativeContext", C2DCreateNativeContext},
-
- // Property getters/setters.
-
- { "C2DSetWidth", C2DSetWidth},
- { "C2DSetHeight", C2DSetHeight},
- { "C2DSetGlobalAlpha", C2DSetGlobalAlpha},
- { "C2DSetFillStyle", C2DSetFillStyle},
- { "C2DSetFont", C2DSetFont},
- { "C2DSetGlobalCompositeOperation", C2DSetGlobalCompositeOperation},
- { "C2DSetLineCap", C2DSetLineCap},
- { "C2DSetLineJoin", C2DSetLineJoin},
- { "C2DSetLineWidth", C2DSetLineWidth},
- { "C2DSetMiterLimit", C2DSetMiterLimit},
- { "C2DSetShadowBlur", C2DSetShadowBlur},
- { "C2DSetShadowColor", C2DSetShadowColor},
- { "C2DSetShadowOffsetX", C2DSetShadowOffsetX},
- { "C2DSetShadowOffsetY", C2DSetShadowOffsetY},
- { "C2DSetStrokeStyle", C2DSetStrokeStyle},
- { "C2DSetTextAlign", C2DSetTextAlign},
- { "C2DSetTextBaseline", C2DSetTextBaseline},
- { "C2DGetImageSmoothingEnabled", C2DGetImageSmoothingEnabled},
-
- // Methods.
- { "C2DArc", C2DArc},
- { "C2DArcTo", C2DArcTo},
- { "C2DBeginPath", C2DBeginPath},
- { "C2DBezierCurveTo", C2DBezierCurveTo},
- { "C2DClearRect", C2DClearRect},
- { "C2DClip", C2DClip},
- { "C2DClosePath", C2DClosePath},
- { "C2DCreateImageDataFromDimensions", C2DCreateImageDataFromDimensions},
- { "C2DDrawImage", C2DDrawImage},
- { "C2DFill", C2DFill},
- { "C2DFillRect", C2DFillRect},
- { "C2DFillText", C2DFillText},
- { "C2DGetImageData", C2DGetImageData},
- { "C2DLineTo", C2DLineTo},
- { "C2DMeasureText", C2DMeasureText},
- { "C2DMoveTo", C2DMoveTo},
- { "C2DPutImageData", C2DPutImageData},
- { "C2DQuadraticCurveTo", C2DQuadraticCurveTo},
- { "C2DRect", C2DRect},
- { "C2DRestore", C2DRestore},
- { "C2DRotate", C2DRotate},
- { "C2DSave", C2DSave},
- { "C2DScale", C2DScale},
- { "C2DSetLineDash", C2DSetLineDash},
- { "C2DSetLineDashOffset", C2DSetLineDashOffset},
- { "C2DSetTransform", C2DSetTransform},
- { "C2DStroke", C2DStroke},
- { "C2DStrokeRect", C2DStrokeRect},
- { "C2DStrokeText", C2DStrokeText},
- { "C2DTransform", C2DTransform},
- { "C2DTranslate", C2DTranslate},
- { "C2DSetFillGradient", C2DSetFillGradient},
- { "C2DSetStrokeGradient", C2DSetStrokeGradient},
- { "C2DGetImageWidth", C2DGetImageWidth},
- { "C2DGetImageHeight", C2DGetImageHeight},
-
- {NULL, NULL}};
-
-Dart_NativeFunction ResolveName(Dart_Handle name, int argc) {
- if (!Dart_IsString(name)) return NULL;
- Dart_NativeFunction result = NULL;
- Dart_EnterScope();
- const char* cname;
- HandleError(Dart_StringToCString(name, &cname));
- for (int i = 0; function_list[i].name != NULL; ++i) {
- if (strcmp(function_list[i].name, cname) == 0) {
- result = function_list[i].function;
- break;
- }
- }
- Dart_ExitScope();
- return result;
-}
diff --git a/runtime/embedders/openglui/common/extension.h b/runtime/embedders/openglui/common/extension.h
deleted file mode 100644
index a13413e..0000000
--- a/runtime/embedders/openglui/common/extension.h
+++ /dev/null
@@ -1,20 +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 EMBEDDERS_OPENGLUI_COMMON_EXTENSION_H_
-#define EMBEDDERS_OPENGLUI_COMMON_EXTENSION_H_
-
-#include "include/dart_api.h"
-
-Dart_NativeFunction ResolveName(Dart_Handle name, int argc);
-
-extern int32_t PlayBackgroundSound(const char* path);
-extern void StopBackgroundSound();
-extern int32_t LoadSoundSample(const char* path);
-extern int32_t PlaySoundSample(const char* path);
-extern int32_t Init2DGraphics();
-
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_EXTENSION_H_
-
diff --git a/runtime/embedders/openglui/common/gl.dart b/runtime/embedders/openglui/common/gl.dart
deleted file mode 100644
index c37c80b..0000000
--- a/runtime/embedders/openglui/common/gl.dart
+++ /dev/null
@@ -1,1211 +0,0 @@
-// 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 android_extension;
-import 'dart:async';
-
-// A VERY simplified DOM.
-
-class BodyElement {
- List _nodes;
- get nodes => _nodes;
- BodyElement() : _nodes = new List();
-}
-
-// The OpenGLUI "equivalent" of Window.
-
-typedef void RequestAnimationFrameCallback(num highResTime);
-
-class Window {
- static int _nextId = 0;
- List _callbacks;
- List _arguments;
-
- Window._internal() : _callbacks = [], _arguments = [];
-
- int _scheduleCallback(callback, [argument]) {
- _callbacks.add(callback);
- _arguments.add(argument);
- return _callbacks.length - 1;
- }
-
- int requestAnimationFrame(RequestAnimationFrameCallback callback) {
- return _scheduleCallback(callback,
- (new DateTime.now()).millisecondsSinceEpoch);
- }
-
- void cancelAnimationFrame(id) {
- _callbacks[id] = null;
- _arguments[id] = null;
- }
-
- get animationFrame {
- // TODO(gram)
- return null;
- }
-
- void _dispatch() {
- // We clear out the callbacks map before calling any callbacks,
- // as they may schedule new callbacks.
- var oldcallbacks = _callbacks;
- var oldarguments = _arguments;
- _callbacks = [];
- _arguments = [];
- for (var i = 0; i < oldcallbacks.length; i++) {
- if (oldcallbacks[i] != null) {
- oldcallbacks[i](oldarguments[i]);
- }
- }
- // We could loop around here to handle any callbacks
- // scheduled in processing the prior ones, but then we
- // need some other mechanism for trying to get requestAnimationFrame
- // callbacks at 60fps.
- }
-
- Map localStorage = {}; // TODO(gram) - Make this persistent.
-}
-
-Window window = new Window._internal();
-
-// The OpenGLUI "equivalent" of HtmlDocument.
-class Document extends Node {
- BodyElement _body;
- get body => _body;
- Document._internal() : _body = new BodyElement();
-}
-
-Document document = new Document._internal();
-
-// TODO(gram): make private and call from within library context.
-update_() {
- log("in update");
- window._dispatch();
-}
-
-// Event handling. This is very kludgy for now, especially the
-// bare-bones Stream stuff!
-
-typedef void EventListener(Event event);
-
-class EventTarget {
- static Map<EventTarget, Map<String, List<EventListener>>>
- _listeners = new Map();
-
- static get listeners => _listeners;
-
- bool dispatchEvent(Event event) {
- var rtn = false;
- if (!_listeners.containsKey(this)) return false;
- var listeners = _listeners[this];
- if (!listeners.containsKey(event.type)) return false;
- var eventListeners = listeners[event.type];
- for (var eventListener in eventListeners) {
- if (eventListener != null) {
- eventListener(event);
- rtn = true;
- }
- }
- return rtn;
- }
-
- void addListener(String eventType, EventListener handler) {
- if (!_listeners.containsKey(this)) {
- _listeners[this] = new Map();
- }
- var listeners = _listeners[this];
- if (!listeners.containsKey(eventType)) {
- listeners[eventType] = new List();
- }
- var event_listeners = listeners[eventType];
- for (var i = 0; i < event_listeners.length; i++) {
- if (event_listeners[i] == null) {
- event_listeners[i] = handler;
- return;
- }
- }
- event_listeners.add(handler);
- }
-
- void removeListener(String eventType, EventListener handler) {
- if (_listeners.containsKey(this)) {
- var listeners = _listeners[this];
- if (listeners.containsKey(eventType)) {
- var event_listeners = listeners[eventType];
- for (var i = 0; i < event_listeners.length; i++) {
- if (event_listeners[i] == handler) {
- event_listeners[i] = null;
- break;
- }
- }
- }
- }
- }
-}
-
-class Event {
- final String type;
- EventTarget target;
- Event(String type) : this.type = type;
- preventDefault() {}
- stopPropagation() {}
-}
-
-class KeyboardEvent extends Event {
- final bool altKey;
- final bool ctrlKey;
- final bool shiftKey;
- final int keyCode;
-
- KeyboardEvent(String type, int keycode, bool alt, bool ctrl, bool shift)
- : super(type),
- keyCode = keycode,
- altKey = alt,
- ctrlKey = ctrl,
- shiftKey = shift {
- }
-}
-
-class MouseEvent extends Event {
- final int screenX, screenY;
- final int clientX, clientY;
-
- MouseEvent(String type, int x, int y)
- : super(type),
- screenX = x,
- screenY = y,
- clientX = x,
- clientY = y {
- }
-}
-
-class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
- int _pauseCount = 0;
- EventTarget _target;
- final String _eventType;
- var _onData;
-
- _EventStreamSubscription(this._target, this._eventType, this._onData) {
- _tryResume();
- }
-
- void cancel() {
- if (_canceled) {
- throw new StateError("Subscription has been canceled.");
- }
-
- _unlisten();
- // Clear out the target to indicate this is complete.
- _target = null;
- _onData = null;
- }
-
- bool get _canceled => _target == null;
-
- void onData(void handleData(T event)) {
- if (_canceled) {
- throw new StateError("Subscription has been canceled.");
- }
- // Remove current event listener.
- _unlisten();
-
- _onData = handleData
- _tryResume();
- }
-
- /// Has no effect.
- void onError(void handleError(Object error)) {}
-
- /// Has no effect.
- void onDone(void handleDone()) {}
-
- void pause([Future resumeSignal]) {
- if (_canceled) {
- throw new StateError("Subscription has been canceled.");
- }
- ++_pauseCount;
- _unlisten();
-
- if (resumeSignal != null) {
- resumeSignal.whenComplete(resume);
- }
- }
-
- bool get _paused => _pauseCount > 0;
-
- void resume() {
- if (_canceled) {
- throw new StateError("Subscription has been canceled.");
- }
- if (!_paused) {
- throw new StateError("Subscription is not paused.");
- }
- --_pauseCount;
- _tryResume();
- }
-
- void _tryResume() {
- if (_onData != null && !_paused) {
- _target.addListener(_eventType, _onData);
- }
- }
-
- void _unlisten() {
- if (_onData != null) {
- _target.removeListener(_eventType, _onData);
- }
- }
-
- Future asFuture([var futureValue]) {
- // We just need a future that will never succeed or fail.
- Completer completer = new Completer();
- return completer.future;
- }
-}
-
-class _EventStream<T extends Event> extends Stream<T> {
- final Object _target;
- final String _eventType;
-
- _EventStream(this._target, this._eventType);
-
- // DOM events are inherently multi-subscribers.
- Stream<T> asBroadcastStream() => this;
- bool get isBroadcast => true;
-
- StreamSubscription<T> listen(void onData(T event),
- { void onError(Object error),
- void onDone(),
- bool cancelOnError}) {
-
- return new _EventStreamSubscription<T>(
- this._target, this._eventType, onData);
- }
-}
-
-class Node extends EventTarget {
- Stream<KeyboardEvent> get onKeyDown => new _EventStream(this, 'keydown');
- Stream<KeyboardEvent> get onKeyUp => new _EventStream(this, 'keyup');
- Stream<MouseEvent> get onMouseDown => new _EventStream(this, 'mousedown');
- Stream<MouseEvent> get onMouseMove => new _EventStream(this, 'mousemove');
- Stream<MouseEvent> get onMouseUp => new _EventStream(this, 'mouseup');
-}
-
-// TODO(gram): If we support more than one on-screen canvas, we will
-// need to filter dispatched mouse and key events by the target Node
-// with more granularity; right now we just iterate through DOM nodes
-// until we find one that handles the event.
-_dispatchEvent(Event event) {
- assert(document.body.nodes.length <= 1);
- for (var target in document.body.nodes) {
- event.target = target;
- if (target.dispatchEvent(event)) {
- return;
- }
- }
- document.dispatchEvent(event);
-}
-
-_dispatchKeyEvent(String type, int keyCode, bool alt, bool ctrl, bool shift) {
- _dispatchEvent(new KeyboardEvent(type, keyCode, alt, ctrl, shift));
-}
-
-_dispatchMouseEvent(String type, double x, double y) {
- _dispatchEvent(new MouseEvent(type, x.toInt(), y.toInt()));
-}
-
-// These next few are called by vmglue.cc.
-onKeyDown_(int when, int keyCode, bool alt, bool ctrl, bool shift, int repeat)
- => _dispatchKeyEvent('keydown', keyCode, alt, ctrl, shift);
-
-onKeyUp_(int when, int keyCode, bool alt, bool ctrl, bool shift, int repeat) =>
- _dispatchKeyEvent('keyup', keyCode, alt, ctrl, shift);
-
-onMouseDown_(int when, double x, double y) =>
- _dispatchMouseEvent('mousedown', x, y);
-
-onMouseMove_(int when, double x, double y) =>
- _dispatchMouseEvent('mousemove', x, y);
-
-onMouseUp_(int when, double x, double y) =>
- _dispatchMouseEvent('mouseup', x, y);
-
-class CanvasElement extends Node {
- int height;
- int width;
-
- CanvasRenderingContext2D _context2d;
- WebGLRenderingContext _context3d;
-
- // For use with drawImage, we want to support a src property
- // like ImageElement, which maps to the context handle in native
- // code.
- get src => "context2d://${_context2d.handle}";
-
- CanvasElement({int width, int height})
- : super() {
- this.width = (width == null) ? getDeviceScreenWidth() : width;
- this.height = (height == null) ? getDeviceScreenHeight() : height;
- getContext('2d');
- }
-
- CanvasRenderingContext getContext(String contextId) {
- if (contextId == "2d") {
- if (_context2d == null) {
- _context2d = new CanvasRenderingContext2D(this, width, height);
- }
- return _context2d;
- } else if (contextId == "webgl" ||
- contextId == "experimental-webgl") {
- if (_context3d == null) {
- _context3d = new WebGLRenderingContext(this);
- }
- return _context3d;
- }
- }
-
- String toDataUrl(String type) {
- // This needs to take the contents of the underlying
- // canvas painted by the 2d context, give that a unique
- // URL, and return that. The canvas element should be
- // reuable afterwards without destroying the previously
- // rendered data associated with this URL.
- assert(_context2d != null);
- var rtn = src;
- _context2d = null;
- return rtn;
- }
-}
-
-class CanvasRenderingContext {
- final CanvasElement canvas;
-
- CanvasRenderingContext(this.canvas);
-}
-
-class AudioElement {
- double volume;
- String _src;
- get src => _src;
- set src(String v) {
- _src = v;
- _loadSample(v);
- }
-
- AudioElement([this._src]);
- void play() {
- _playSample(_src);
- }
-}
-
-// The simplest way to call native code: top-level functions.
-int systemRand() native "SystemRand";
-void systemSrand(int seed) native "SystemSrand";
-void log(String what) native "Log";
-
-int getDeviceScreenWidth() native "GetDeviceScreenWidth";
-int getDeviceScreenHeight() native "GetDeviceScreenHeight";
-
-// EGL functions.
-void glSwapBuffers() native "SwapBuffers";
-
-// GL functions.
-void glAttachShader(int program, int shader) native "GLAttachShader";
-void glBindBuffer(int target, int buffer) native "GLBindBuffer";
-void glBufferData(int target, List data, int usage) native "GLBufferData";
-void glClearColor(num r, num g, num b, num alpha) native "GLClearColor";
-void glClearDepth(num depth) native "GLClearDepth";
-void glClear(int mask) native "GLClear";
-void glCompileShader(int shader) native "GLCompileShader";
-int glCreateBuffer() native "GLCreateBuffer";
-int glCreateProgram() native "GLCreateProgram";
-int glCreateShader(int shaderType) native "GLCreateShader";
-void glDrawArrays(int mode, int first, int count) native "GLDrawArrays";
-void glEnableVertexAttribArray(int index) native "GLEnableVertexAttribArray";
-int glGetAttribLocation(int program, String name) native "GLGetAttribLocation";
-int glGetError() native "GLGetError";
-int glGetProgramParameter(int program, int param)
- native "GLGetProgramParameter";
-int glGetShaderParameter(int shader, int param) native "GLGetShaderParameter";
-int glGetUniformLocation(int program, String name)
- native "GLGetUniformLocation";
-void glLinkProgram(int program) native "GLLinkProgram";
-void glShaderSource(int shader, String source) native "GLShaderSource";
-void glUniform1f(int location, double v0) native "GLUniform1f";
-void glUniform2f(int location, double v0, double v1) native "GLUniform2f";
-void glUniform3f(int location, double v0, double v1, double v2)
- native "GLUniform3f";
-void glUniform4f(int location, double v0, double v1, double v2, double v3)
- native "GLUniform4f";
-void glUniform1i(int location, int v0) native "GLUniform1i";
-void glUniform2i(int location, int v0, int v1) native "GLUniform2i";
-void glUniform3i(int location, int v0, int v1, int v2) native "GLUniform3i";
-void glUniform4i(int location, int v0, int v1, int v2, int v3)
- native "GLUniform4i";
-void glUniform1fv(int location, List values) native "GLUniform1fv";
-void glUniform2fv(int location, List values) native "GLUniform2fv";
-void glUniform3fv(int location, List values) native "GLUniform3fv";
-void glUniform4fv(int location, List values) native "GLUniform4fv";
-void glUniform1iv(int location, List values) native "GLUniform1iv";
-void glUniform2iv(int location, List values) native "GLUniform2iv";
-void glUniform3iv(int location, List values) native "GLUniform3iv";
-void glUniform4iv(int location, List values) native "GLUniform4iv";
-void glUseProgram(int program) native "GLUseProgram";
-void glVertexAttribPointer(int index, int size, int type, bool normalized,
- int stride, int pointer) native "GLVertexAttribPointer";
-void glViewport(int x, int y, int width, int height) native "GLViewport";
-
-int glArrayBuffer() native "GLArrayBuffer";
-int glColorBufferBit() native "GLColorBufferBit";
-int glCompileStatus() native "GLCompileStatus";
-int glDeleteStatus() native "GLDeleteStatus";
-int glDepthBufferBit() native "GLDepthBufferBit";
-int glFloat() native "GLFloat";
-int glFragmentShader() native "GLFragmentShader";
-int glLinkStatus() native "GLLinkStatus";
-int glStaticDraw() native "GLStaticDraw";
-int glTriangleStrip() native "GLTriangleStrip";
-int glTriangles() native "GLTriangles";
-int glTrue() native "GLTrue";
-int glValidateStatus() native "GLValidateStatus";
-int glVertexShader() native "GLVertexShader";
-
-String glGetShaderInfoLog(int shader) native "GLGetShaderInfoLog";
-String glGetProgramInfoLog(int program) native "GLGetProgramInfoLog";
-
-class WebGLRenderingContext extends CanvasRenderingContext {
- WebGLRenderingContext(canvas) : super(canvas);
-
- static get ARRAY_BUFFER => glArrayBuffer();
- static get COLOR_BUFFER_BIT => glColorBufferBit();
- static get COMPILE_STATUS => glCompileStatus();
- static get DELETE_STATUS => glDeleteStatus();
- static get DEPTH_BUFFER_BIT => glDepthBufferBit();
- static get FLOAT => glFloat();
- static get FRAGMENT_SHADER => glFragmentShader();
- static get LINK_STATUS => glLinkStatus();
- static get STATIC_DRAW => glStaticDraw();
- static get TRUE => glTrue();
- static get TRIANGLE_STRIP => glTriangleStrip();
- static get TRIANGLES => glTriangles();
- static get VALIDATE_STATUS => glValidateStatus();
- static get VERTEX_SHADER => glVertexShader();
-
- attachShader(program, shader) => glAttachShader(program, shader);
- bindBuffer(target, buffer) => glBindBuffer(target, buffer);
- bufferData(target, data, usage) => glBufferData(target, data, usage);
- clearColor(r, g, b, alpha) => glClearColor(r, g, b, alpha);
- clearDepth(depth) => glClearDepth(depth);
- clear(mask) => glClear(mask);
- compileShader(shader) => glCompileShader(shader);
- createBuffer() => glCreateBuffer();
- createProgram() => glCreateProgram();
- createShader(shaderType) => glCreateShader(shaderType);
- drawArrays(mode, first, count) => glDrawArrays(mode, first, count);
- enableVertexAttribArray(index) => glEnableVertexAttribArray(index);
- getAttribLocation(program, name) => glGetAttribLocation(program, name);
- getError() => glGetError();
- getProgramParameter(program, name) {
- var rtn = glGetProgramParameter(program, name);
- if (name == DELETE_STATUS ||
- name == LINK_STATUS ||
- name == VALIDATE_STATUS) {
- return (rtn == 0) ? false : true;
- }
- return rtn;
- }
- getShaderParameter(shader, name) {
- var rtn = glGetShaderParameter(shader, name);
- if (name == DELETE_STATUS || name == COMPILE_STATUS) {
- return (rtn == 0) ? false : true;
- }
- return rtn;
- }
- getUniformLocation(program, name) => glGetUniformLocation(program, name);
- linkProgram(program) => glLinkProgram(program);
- shaderSource(shader, source) => glShaderSource(shader, source);
- uniform1f(location, v0) => glUniform1f(location, v0);
- uniform2f(location, v0, v1) => glUniform2f(location, v0, v1);
- uniform3f(location, v0, v1, v2) => glUniform3f(location, v0, v1, v2);
- uniform4f(location, v0, v1, v2, v3) => glUniform4f(location, v0, v1, v2, v3);
- uniform1i(location, v0) => glUniform1i(location, v0);
- uniform2i(location, v0, v1) => glUniform2i(location, v0, v1);
- uniform3i(location, v0, v1, v2) => glUniform3i(location, v0, v1, v2);
- uniform4i(location, v0, v1, v2, v3) => glUniform4i(location, v0, v1, v2, v3);
- uniform1fv(location, values) => glUniform1fv(location, values);
- uniform2fv(location, values) => glUniform2fv(location, values);
- uniform3fv(location, values) => glUniform3fv(location, values);
- uniform4fv(location, values) => glUniform4fv(location, values);
- uniform1iv(location, values) => glUniform1iv(location, values);
- uniform2iv(location, values) => glUniform2iv(location, values);
- uniform3iv(location, values) => glUniform3iv(location, values);
- uniform4iv(location, values) => glUniform4iv(location, values);
- useProgram(program) => glUseProgram(program);
- vertexAttribPointer(index, size, type, normalized, stride, pointer) =>
- glVertexAttribPointer(index, size, type, normalized, stride, pointer);
- viewport(x, y, width, height) => glViewport(x, y, width, height);
- getShaderInfoLog(shader) => glGetShaderInfoLog(shader);
- getProgramInfoLog(program) => glGetProgramInfoLog(program);
-
- // TODO(vsm): Kill.
- noSuchMethod(invocation) {
- throw new Exception('Unimplemented ${invocation.memberName}');
- }
-}
-
-//------------------------------------------------------------------
-// Simple audio support.
-
-void playBackground(String path) native "PlayBackground";
-void stopBackground() native "StopBackground";
-
-//-------------------------------------------------------------------
-// Set up print().
-
-get _printClosure => (s) {
- try {
- log(s);
- } catch (_) {
- throw(s);
- }
-};
-
-//------------------------------------------------------------------
-// Temp hack for compat with WebGL.
-
-class Float32Array extends List<double> {
- Float32Array.fromList(List a) {
- addAll(a);
- }
-}
-
-//------------------------------------------------------------------
-// 2D canvas support
-
-int _SetWidth(int handle, int width)
- native "C2DSetWidth";
-int _SetHeight(int handle, int height)
- native "C2DSetHeight";
-
-double _SetGlobalAlpha(int handle, double globalAlpha)
- native "C2DSetGlobalAlpha";
-void _SetFillStyle(int handle, fs)
- native "C2DSetFillStyle";
-String _SetFont(int handle, String font)
- native "C2DSetFont";
-void _SetGlobalCompositeOperation(int handle, String op)
- native "C2DSetGlobalCompositeOperation";
-_SetLineCap(int handle, String lc)
- native "C2DSetLineCap";
-_SetLineJoin(int handle, String lj)
- native "C2DSetLineJoin";
-_SetLineWidth(int handle, double w)
- native "C2DSetLineWidth";
-_SetMiterLimit(int handle, double limit)
- native "C2DSetMiterLimit";
-_SetShadowBlur(int handle, double blur)
- native "C2DSetShadowBlur";
-_SetShadowColor(int handle, String color)
- native "C2DSetShadowColor";
-_SetShadowOffsetX(int handle, double offset)
- native "C2DSetShadowOffsetX";
-_SetShadowOffsetY(int handle, double offset)
- native "C2DSetShadowOffsetY";
-void _SetStrokeStyle(int handle, ss)
- native "C2DSetStrokeStyle";
-String _SetTextAlign(int handle, String align)
- native "C2DSetTextAlign";
-String _SetTextBaseline(int handle, String baseline)
- native "C2DSetTextBaseline";
-_GetBackingStorePixelRatio(int handle)
- native "C2DGetBackingStorePixelRatio";
-void _SetImageSmoothingEnabled(int handle, bool ise)
- native "C2DSetImageSmoothingEnabled";
-void _SetLineDash(int handle, List v)
- native "C2DSetLineDash";
-_SetLineDashOffset(int handle, int v)
- native "C2DSetLineDashOffset";
-void _Arc(int handle, double x, double y, double radius,
- double startAngle, double endAngle, [bool anticlockwise = false])
- native "C2DArc";
-void _ArcTo(int handle, double x1, double y1,
- double x2, double y2, double radius)
- native "C2DArcTo";
-void _ArcTo2(int handle, double x1, double y1,
- double x2, double y2, double radiusX,
- double radiusY, double rotation)
- native "C2DArcTo2";
-void _BeginPath(int handle)
- native "C2DBeginPath";
-void _BezierCurveTo(int handle, double cp1x, double cp1y,
- double cp2x, double cp2y, double x, double y)
- native "C2DBezierCurveTo";
-void _ClearRect(int handle, double x, double y, double w, double h)
- native "C2DClearRect";
-void _Clip(int handle)
- native "C2DClip";
-void _ClosePath(int handle)
- native "C2DClosePath";
-ImageData _CreateImageDataFromDimensions(int handle, num w, num h)
- native "C2DCreateImageDataFromDimensions";
-void _DrawImage(int handle, String src_url,
- int sx, int sy,
- bool has_src_dimensions, int sw, int sh,
- int dx, int dy,
- bool has_dst_dimensions, int dw, int dh)
- native "C2DDrawImage";
-void _Fill(int handle)
- native "C2DFill";
-void _FillRect(int handle, double x, double y, double w, double h)
- native "C2DFillRect";
-void _FillText(int handle, String text, double x, double y, double maxWidth)
- native "C2DFillText";
-ImageData _GetImageData(num sx, num sy, num sw, num sh)
- native "C2DGetImageData";
-void _LineTo(int handle, double x, double y)
- native "C2DLineTo";
-double _MeasureText(int handle, String text)
- native "C2DMeasureText";
-void _MoveTo(int handle, double x, double y)
- native "C2DMoveTo";
-void _PutImageData(int handle, ImageData imagedata, double dx, double dy)
- native "C2DPutImageData";
-void _QuadraticCurveTo(int handle, double cpx, double cpy,
- double x, double y)
- native "C2DQuadraticCurveTo";
-void _Rect(int handle, double x, double y, double w, double h)
- native "C2DRect";
-void _Restore(int handle)
- native "C2DRestore";
-void _Rotate(int handle, double a)
- native "C2DRotate";
-void _Save(int handle)
- native "C2DSave";
-void _Scale(int handle, double sx, double sy)
- native "C2DScale";
-void _SetTransform(int handle, double m11, double m12,
- double m21, double m22, double dx, double dy)
- native "C2DSetTransform";
-void _Stroke(int handle)
- native "C2DStroke";
-void _StrokeRect(int handle, double x, double y, double w, double h)
- native "C2DStrokeRect";
-void _StrokeText(int handle, String text, double x, double y,
- double maxWidth)
- native "C2DStrokeText";
-void _Transform(int handle, double m11, double m12,
- double m21, double m22, double dx, double dy)
- native "C2DTransform";
-void _Translate(int handle, double x, double y)
- native "C2DTranslate";
-
-void _CreateNativeContext(int handle, int width, int height)
- native "C2DCreateNativeContext";
-
-void _SetFillGradient(int handle, bool isRadial,
- double x0, double y0, double r0,
- double x1, double y1, double r1,
- List<double> positions, List<String> colors)
- native "C2DSetFillGradient";
-
-void _SetStrokeGradient(int handle, bool isRadial,
- double x0, double y0, double r0,
- double x1, double y1, double r1,
- List<double> positions, List<String> colors)
- native "C2DSetStrokeGradient";
-
-int _GetImageWidth(String url)
- native "C2DGetImageWidth";
-
-int _GetImageHeight(String url)
- native "C2DGetImageHeight";
-
-class CanvasGradient {
- num _x0, _y0, _r0 = 0, _x1, _y1, _r1 = 0;
- bool _isRadial;
- List<double> _colorStopPositions = [];
- List<String> _colorStopColors = [];
-
- void addColorStop(num offset, String color) {
- _colorStopPositions.add(offset.toDouble());
- _colorStopColors.add(color);
- }
-
- CanvasGradient.linear(this._x0, this._y0, this._x1, this._y1)
- : _isRadial = false;
-
- CanvasGradient.radial(this._x0, this._y0, this._r0,
- this._x1, this._y1, this._r1)
- : _isRadial = true;
-
- void setAsFillStyle(_handle) {
- _SetFillGradient(_handle, _isRadial,
- _x0.toDouble(), _y0.toDouble(), _r0.toDouble(),
- _x1.toDouble(), _y1.toDouble(), _r1.toDouble(),
- _colorStopPositions, _colorStopColors);
- }
-
- void setAsStrokeStyle(_handle) {
- _SetStrokeGradient(_handle, _isRadial,
- _x0.toDouble(), _y0.toDouble(), _r0.toDouble(),
- _x1.toDouble(), _y1.toDouble(), _r1.toDouble(),
- _colorStopPositions, _colorStopColors);
- }
-}
-
-class ImageElement extends Node {
- Stream<Event> get onLoad => new _EventStream(this, 'load');
-
- String _src;
- int _width;
- int _height;
-
- get src => _src;
-
- set src(String v) {
- log("Set ImageElement src to $v");
- _src = v;
- }
-
- // The onLoad handler may be set after the src, so
- // we hook into that here...
- void addListener(String eventType, EventListener handler) {
- super.addListener(eventType, handler);
- if (eventType == 'load') {
- var e = new Event('load');
- e.target = this;
- window._scheduleCallback(handler, e);
- }
- }
-
- get width => _width == null ? _width = _GetImageWidth(_src) : _width;
- get height => _height == null ? _height = _GetImageHeight(_src) : _height;
- set width(int widthp) => _width = widthp;
- set height(int heightp) => _height = heightp;
-
- ImageElement({String srcp, int widthp, int heightp})
- : _src = srcp,
- _width = widthp,
- _height = heightp {
- if (_src != null) {
- if (_width == null) _width = _GetImageWidth(_src);
- if (_height == null) _height = _GetImageHeight(_src);
- }
- }
-}
-
-class ImageData {
- final Uint8ClampedArray data;
- final int height;
- final int width;
- ImageData(this.height, this.width, this.data);
-}
-
-class TextMetrics {
- final num width;
- TextMetrics(this.width);
-}
-
-void shutdown() {
- CanvasRenderingContext2D.next_handle = 0;
-}
-
-class Rect {
- final num top, left, width, height;
- const Rect(this.left, this.top, this.width, this.height);
-}
-
-class CanvasRenderingContext2D extends CanvasRenderingContext {
- // TODO(gram): We need to support multiple contexts, for cached content
- // prerendered to an offscreen buffer. For this we will use handles, with
- // handle 0 being the physical display.
- static int next_handle = 0;
- int _handle = 0;
- get handle => _handle;
-
- int _width, _height;
- set width(int w) { _width = SetWidth(_handle, w); }
- get width => _width;
- set height(int h) { _height = SetHeight(_handle, h); }
- get height => _height;
-
- CanvasRenderingContext2D(canvas, width, height) : super(canvas) {
- _width = width;
- _height = height;
- _CreateNativeContext(_handle = next_handle++, width, height);
- }
-
- double _alpha = 1.0;
- set globalAlpha(num a) {
- _alpha = _SetGlobalAlpha(_handle, a.toDouble());
- }
- get globalAlpha => _alpha;
-
- // TODO(gram): make sure we support compound assignments like:
- // fillStyle = strokeStyle = "red"
- var _fillStyle = "#000";
- set fillStyle(fs) {
- _fillStyle = fs;
- // TODO(gram): Support for CanvasPattern.
- if (fs is CanvasGradient) {
- fs.setAsFillStyle(_handle);
- } else {
- _SetFillStyle(_handle, fs);
- }
- }
- get fillStyle => _fillStyle;
-
- String _font = "10px sans-serif";
- set font(String f) { _font = _SetFont(_handle, f); }
- get font => _font;
-
- String _globalCompositeOperation = "source-over";
- set globalCompositeOperation(String o) =>
- _SetGlobalCompositeOperation(_handle, _globalCompositeOperation = o);
- get globalCompositeOperation => _globalCompositeOperation;
-
- String _lineCap = "butt"; // "butt", "round", "square"
- get lineCap => _lineCap;
- set lineCap(String lc) => _SetLineCap(_handle, _lineCap = lc);
-
- int _lineDashOffset = 0;
- get lineDashOffset => _lineDashOffset;
- set lineDashOffset(num v) {
- _lineDashOffset = v.toInt();
- _SetLineDashOffset(_handle, _lineDashOffset);
- }
-
- String _lineJoin = "miter"; // "round", "bevel", "miter"
- get lineJoin => _lineJoin;
- set lineJoin(String lj) => _SetLineJoin(_handle, _lineJoin = lj);
-
- num _lineWidth = 1.0;
- get lineWidth => _lineWidth;
- set lineWidth(num w) {
- _SetLineWidth(_handle, w.toDouble());
- _lineWidth = w;
- }
-
- num _miterLimit = 10.0; // (default 10)
- get miterLimit => _miterLimit;
- set miterLimit(num limit) {
- _SetMiterLimit(_handle, limit.toDouble());
- _miterLimit = limit;
- }
-
- num _shadowBlur;
- get shadowBlur => _shadowBlur;
- set shadowBlur(num blur) {
- _shadowBlur = blur;
- _SetShadowBlur(_handle, blur.toDouble());
- }
-
- String _shadowColor;
- get shadowColor => _shadowColor;
- set shadowColor(String color) =>
- _SetShadowColor(_handle, _shadowColor = color);
-
- num _shadowOffsetX;
- get shadowOffsetX => _shadowOffsetX;
- set shadowOffsetX(num offset) {
- _shadowOffsetX = offset;
- _SetShadowOffsetX(_handle, offset.toDouble());
- }
-
- num _shadowOffsetY;
- get shadowOffsetY => _shadowOffsetY;
- set shadowOffsetY(num offset) {
- _shadowOffsetY = offset;
- _SetShadowOffsetY(_handle, offset.toDouble());
- }
-
- var _strokeStyle = "#000";
- get strokeStyle => _strokeStyle;
- set strokeStyle(ss) {
- _strokeStyle = ss;
- // TODO(gram): Support for CanvasPattern.
- if (ss is CanvasGradient) {
- ss.setAsStrokeStyle(_handle);
- } else {
- _SetStrokeStyle(_handle, ss);
- }
- }
-
- String _textAlign = "start";
- get textAlign => _textAlign;
- set textAlign(String a) { _textAlign = _SetTextAlign(_handle, a); }
-
- String _textBaseline = "alphabetic";
- get textBaseline => _textBaseline;
- set textBaseline(String b) { _textBaseline = _SetTextBaseline(_handle, b); }
-
- get webkitBackingStorePixelRatio => _GetBackingStorePixelRatio(_handle);
-
- bool _webkitImageSmoothingEnabled;
- get webkitImageSmoothingEnabled => _webkitImageSmoothingEnabled;
- set webkitImageSmoothingEnabled(bool v) =>
- _SetImageSmoothingEnabled(_webkitImageSmoothingEnabled = v);
-
- get webkitLineDash => lineDash;
- set webkitLineDash(List v) => lineDash = v;
-
- get webkitLineDashOffset => lineDashOffset;
- set webkitLineDashOffset(num v) => lineDashOffset = v;
-
- // Methods
-
- void arc(num x, num y, num radius, num a1, num a2, bool anticlockwise) {
- if (radius < 0) {
- // throw IndexSizeError
- } else {
- _Arc(_handle, x.toDouble(), y.toDouble(), radius.toDouble(),
- a1.toDouble(), a2.toDouble(), anticlockwise);
- }
- }
-
- // Note - looking at the Dart docs it seems Dart doesn't support
- // the second form in the browser.
- void arcTo(num x1, num y1, num x2, num y2,
- num radiusX, [num radiusY, num rotation]) {
- if (radiusY == null) {
- _ArcTo(_handle, x1.toDouble(), y1.toDouble(),
- x2.toDouble(), y2.toDouble(), radiusX.toDouble());
- } else {
- _ArcTo2(_handle, x1.toDouble(), y1.toDouble(),
- x2.toDouble(), y2.toDouble(),
- radiusX.toDouble(), radiusY.toDouble(),
- rotation.toDouble());
- }
- }
-
- void beginPath() => _BeginPath(_handle);
-
- void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y,
- num x, num y) =>
- _BezierCurveTo(_handle, cp1x.toDouble(), cp1y.toDouble(),
- cp2x.toDouble(), cp2y.toDouble(),
- x.toDouble(), y.toDouble());
-
- void clearRect(num x, num y, num w, num h) =>
- _ClearRect(_handle, x.toDouble(), y.toDouble(),
- w.toDouble(), h.toDouble());
-
- void clip() => _Clip(_handle);
-
- void closePath() => _ClosePath(_handle);
-
- ImageData createImageData(var imagedata_OR_sw, [num sh = null]) {
- if (sh == null) {
- throw new Exception('Unimplemented createImageData(imagedata)');
- } else {
- return _CreateImageDataFromDimensions(_handle, imagedata_OR_sw, sh);
- }
- }
-
- CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) {
- return new CanvasGradient.linear(x0, y0, x1, y1);
- }
-
- CanvasPattern createPattern(canvas_OR_image, String repetitionType) {
- throw new Exception('Unimplemented createPattern');
- }
-
- CanvasGradient createRadialGradient(num x0, num y0, num r0,
- num x1, num y1, num r1) {
- return new CanvasGradient.radial(x0, y0, r0, x1, y1, r1);
- }
-
- void _drawImage(element, num x1, num y1,
- [num w1, num h1, num x2, num y2, num w2, num h2]) {
- if (element == null || element.src == null || element.src.length == 0) {
- throw "drawImage called with no valid src";
- } else {
- log("drawImage ${element.src}");
- }
- var w = (element.width == null) ? 0 : element.width;
- var h = (element.height == null) ? 0 : element.height;
- if (!?w1) { // drawImage(element, dx, dy)
- _DrawImage(_handle, element.src, 0, 0, false, w, h,
- x1.toInt(), y1.toInt(), false, 0, 0);
- } else if (!?x2) { // drawImage(element, dx, dy, dw, dh)
- _DrawImage(_handle, element.src, 0, 0, false, w, h,
- x1.toInt(), y1.toInt(), true, w1.toInt(), h1.toInt());
- } else { // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
- _DrawImage(_handle, element.src,
- x1.toInt(), y1.toInt(), true, w1.toInt(), h1.toInt(),
- x2.toInt(), y2.toInt(), true, w2.toInt(), h2.toInt());
- }
- }
-
- void drawImage(source, num destX, num destY) {
- _drawImage(source, destX, destY);
- }
-
- void drawImageScaled(source,
- num destX, num destY, num destWidth, num destHeight) {
- _drawImage(source, destX, destY, destWidth, destHeight);
- }
-
- void drawImageScaledFromSource(source,
- num sourceX, num sourceY, num sourceWidth, num sourceHeight,
- num destX, num destY, num destWidth, num destHeight) {
- _drawImage(source, sourceX, sourceY, sourceWidth, sourceHeight,
- destX, destY, destWidth, destHeight);
- }
-
- void drawImageToRect(source, Rect dest, {Rect sourceRect}) {
- if (sourceRect == null) {
- _drawImage(source, dest.left, dest.top, dest.width, dest.height);
- } else {
- _drawImage(source,
- sourceRect.left, sourceRect.top, sourceRect.width, sourceRect.height,
- dest.left, dest.top, dest.width, dest.height);
- }
- }
-
- void fill() => _Fill(_handle);
-
- void fillRect(num x, num y, num w, num h) =>
- _FillRect(_handle, x.toDouble(), y.toDouble(),
- w.toDouble(), h.toDouble());
-
- void fillText(String text, num x, num y, [num maxWidth = -1]) =>
- _FillText(_handle, text, x.toDouble(), y.toDouble(),
- maxWidth.toDouble());
-
- ImageData getImageData(num sx, num sy, num sw, num sh) =>
- _GetImageData(sx, sy, sw, sh);
-
- List<double> _lineDash = null;
- List<num> getLineDash() {
- if (_lineDash == null) return [];
- return _lineDash; // TODO(gram): should we return a copy?
- }
-
- bool isPointInPath(num x, num y) {
- throw new Exception('Unimplemented isPointInPath');
- }
-
- void lineTo(num x, num y) {
- _LineTo(_handle, x.toDouble(), y.toDouble());
- }
-
- TextMetrics measureText(String text) {
- double w = _MeasureText(_handle, text);
- return new TextMetrics(w);
- }
-
- void moveTo(num x, num y) =>
- _MoveTo(_handle, x.toDouble(), y.toDouble());
-
- void putImageData(ImageData imagedata, num dx, num dy,
- [num dirtyX, num dirtyY, num dirtyWidth, num dirtyHeight]) {
- if (dirtyX != null || dirtyY != null) {
- throw new Exception('Unimplemented putImageData');
- } else {
- _PutImageData(_handle, imagedata, dx, dy);
- }
- }
-
- void quadraticCurveTo(num cpx, num cpy, num x, num y) =>
- _QuadraticCurveTo(_handle, cpx.toDouble(), cpy.toDouble(),
- x.toDouble(), y.toDouble());
-
- void rect(num x, num y, num w, num h) =>
- _Rect(_handle, x.toDouble(), y.toDouble(), w.toDouble(), h.toDouble());
-
- void restore() => _Restore(_handle);
-
- void rotate(num angle) => _Rotate(_handle, angle.toDouble());
-
- void save() => _Save(_handle);
-
- void scale(num x, num y) => _Scale(_handle, x.toDouble(), y.toDouble());
-
- void setFillColorHsl(int h, num s, num l, [num a = 1]) {
- throw new Exception('Unimplemented setFillColorHsl');
- }
-
- void setFillColorRgb(int r, int g, int b, [num a = 1]) {
- throw new Exception('Unimplemented setFillColorRgb');
- }
-
- void setLineDash(List<num> dash) {
- var valid = true;
- var new_dash;
- if (dash.length % 2 == 1) {
- new_dash = new List<double>(2 * dash.length);
- for (int i = 0; i < dash.length; i++) {
- double v = dash[i].toDouble();
- if (v < 0) {
- valid = false;
- break;
- }
- new_dash[i] = new_dash[i + dash.length] = v;
- }
- } else {
- new_dash = new List<double>(dash.length);
- for (int i = 0; i < dash.length; i++) {
- double v = dash[i].toDouble();
- if (v < 0) {
- valid = false;
- break;
- }
- new_dash[i] = v;
- }
- }
- if (valid) {
- _SetLineDash(_handle, _lineDash = new_dash);
- }
- }
-
- void setStrokeColorHsl(int h, num s, num l, [num a = 1]) {
- throw new Exception('Unimplemented setStrokeColorHsl');
- }
-
- void setStrokeColorRgb(int r, int g, int b, [num a = 1]) {
- throw new Exception('Unimplemented setStrokeColorRgb');
- }
-
- void setTransform(num m11, num m12, num m21, num m22, num dx, num dy) =>
- _SetTransform(_handle, m11.toDouble(), m12.toDouble(),
- m21.toDouble(), m22.toDouble(),
- dx.toDouble(), dy.toDouble());
-
- void stroke() => _Stroke(_handle);
-
- void strokeRect(num x, num y, num w, num h, [num lineWidth]) =>
- _StrokeRect(_handle, x.toDouble(), y.toDouble(),
- w.toDouble(), h.toDouble());
-
- void strokeText(String text, num x, num y, [num maxWidth = -1]) =>
- _StrokeText(_handle, text, x.toDouble(), y.toDouble(),
- maxWidth.toDouble());
-
- void transform(num m11, num m12, num m21, num m22, num dx, num dy) =>
- _Transform(_handle, m11.toDouble(), m12.toDouble(),
- m21.toDouble(), m22.toDouble(),
- dx.toDouble(), dy.toDouble());
-
- void translate(num x, num y) =>
- _Translate(_handle, x.toDouble(), y.toDouble());
-
- ImageData webkitGetImageDataHD(num sx, num sy, num sw, num sh) {
- throw new Exception('Unimplemented webkitGetImageDataHD');
- }
-
- void webkitPutImageDataHD(ImageData imagedata, num dx, num dy,
- [num dirtyX, num dirtyY,
- num dirtyWidth, num dirtyHeight]) {
- throw new Exception('Unimplemented webkitGetImageDataHD');
- }
-
- // TODO(vsm): Kill.
- noSuchMethod(invocation) {
- throw new Exception('Unimplemented/unknown ${invocation.memberName}');
- }
-}
-
-var sfx_extension = 'raw';
-int _loadSample(String s) native "LoadSample";
-int _playSample(String s) native "PlaySample";
diff --git a/runtime/embedders/openglui/common/graphics_handler.cc b/runtime/embedders/openglui/common/graphics_handler.cc
deleted file mode 100644
index 449facb..0000000
--- a/runtime/embedders/openglui/common/graphics_handler.cc
+++ /dev/null
@@ -1,123 +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 "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/canvas_context.h"
-#include "embedders/openglui/common/log.h"
-
-extern void CheckGLError(const char *function);
-
-GraphicsHandler* graphics;
-extern CanvasContext* display_context;
-
-GraphicsHandler::GraphicsHandler(const char* resource_path)
- : resource_path_(resource_path),
- ag(),
- grcontext(NULL),
- width_(0),
- height_(0) {
- graphics = this;
- DecoderHack(0, NULL);
-}
-
-void GraphicsHandler::DecoderHack(int x, SkStream* s) {
- if (x) { // hack to keep the linker from throwing these out
- extern SkImageDecoder* sk_libpng_dfactory(SkStream* s);
- sk_libpng_dfactory(s);
-
- // TODO(gram): For some reason I get linker errors on these, even though
- // they are defined in libskia_images. Figure out why...
- /*
- extern SkImageDecoder* sk_libjpeg_dfactory(SkStream* s);
- extern SkImageDecoder* sk_libbmp_dfactory(SkStream* s);
- extern SkImageDecoder* sk_libgif_dfactory(SkStream* s);
- extern SkImageDecoder* sk_libico_dfactory(SkStream* s);
- extern SkImageDecoder* sk_libwbmp_dfactory(SkStream* s);
- sk_libjpeg_dfactory(s);
- sk_libbmp_dfactory(s);
- sk_libgif_dfactory(s);
- sk_libico_dfactory(s);
- sk_libwbmp_dfactory(s);
- */
- }
-}
-
-// Kludge to get around an issue with Android emulator, which returns
-// NULL for the shader language version, causing Skia to blow up.
-const GrGLubyte* myGLGetString(GLenum name) {
- const GrGLubyte* str = glGetString(name);
- if (NULL == str && GL_SHADING_LANGUAGE_VERSION == name) {
- return reinterpret_cast<GrGLubyte*>(
- const_cast<char*>("OpenGL ES GLSL ES 1.0"));
- } else {
- return str;
- }
-}
-
-int32_t GraphicsHandler::Start() {
- GrGLInterface* fGL = const_cast<GrGLInterface*>(GrGLCreateNativeInterface());
- LOGI("Created native interface %s\n", fGL ? "succeeded" : "failed");
- fGL->fGetString = myGLGetString;
- grcontext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fGL);
- LOGI("Created GrContext %s\n", grcontext ? "succeeded" : "failed");
- return 0;
-}
-
-void GraphicsHandler::Stop() {
- LOGI("Releasing display context");
- FreeContexts();
- grcontext->unref();
- grcontext = NULL;
-}
-
-SkCanvas* GraphicsHandler::CreateDisplayCanvas() {
- GrBackendRenderTargetDesc desc;
- desc.fWidth = width_;
- desc.fHeight = height_;
- desc.fConfig = kSkia8888_GrPixelConfig;
- desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
- glGetIntegerv(GL_SAMPLES, &desc.fSampleCnt);
- glGetIntegerv(GL_STENCIL_BITS, &desc.fStencilBits);
- LOGI("Creating %dx%d display canvas, samples %d, stencil bits %d",
- width_, height_, desc.fSampleCnt, desc.fStencilBits);
- GrGLint buffer;
- glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer);
- desc.fRenderTargetHandle = buffer;
- GrRenderTarget* fGrRenderTarget = grcontext->wrapBackendRenderTarget(desc);
- SkGpuDevice* device = new SkGpuDevice(grcontext, fGrRenderTarget);
-// fGrRenderTarget->unref(); // TODO(gram): determine if we need this.
- SkCanvas* canvas = new SkCanvas(device);
- device->unref();
- return canvas;
-}
-
-SkCanvas* GraphicsHandler::CreateBitmapCanvas(int width, int height) {
- LOGI("Creating %dx%d bitmap canvas", width, height);
- SkDevice* rasterDevice =
- new SkDevice(SkBitmap::kARGB_8888_Config, width, height);
- SkCanvas* canvas = new SkCanvas(rasterDevice);
- rasterDevice->unref();
- return canvas;
-}
-
-void GraphicsHandler::SetViewport(int left, int top, int width, int height) {
- width_ = width;
- height_ = height;
- glViewport(left, top, width, height);
- CheckGLError("glViewPort");
-}
-
-int32_t GraphicsHandler::Update() {
- LOGI("In GraphicsHandler::Update, display_context dirty %s",
- (display_context == NULL ? "NULL" :
- (display_context->isDirty() ? "yes":"no")));
- if (display_context != NULL && display_context->isDirty()) {
- LOGI("Flushing display context\n");
- display_context->Flush();
- SwapBuffers();
- display_context->clearDirty();
- }
- return 0;
-}
-
diff --git a/runtime/embedders/openglui/common/graphics_handler.h b/runtime/embedders/openglui/common/graphics_handler.h
deleted file mode 100644
index 77f57ec..0000000
--- a/runtime/embedders/openglui/common/graphics_handler.h
+++ /dev/null
@@ -1,62 +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 EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
-
-#include "embedders/openglui/common/isized.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/support.h"
-#include "embedders/openglui/common/timer.h"
-
-class GraphicsHandler : public ISized {
- private:
- void DecoderHack(int x, SkStream* s);
-
- public:
- explicit GraphicsHandler(const char* resource_path);
-
- const int32_t& height() {
- return height_;
- }
-
- const int32_t& width() {
- return width_;
- }
-
- void ApplyOrtho(float maxX, float maxY) const;
- void ApplyRotation(float degrees) const;
-
- virtual int32_t Start();
- virtual void Stop();
-
- void SwapBuffers() {
- GLSwapBuffers();
- }
-
- virtual int32_t Update();
-
- void SetViewport(int left, int top, int width, int height);
-
- SkCanvas* CreateDisplayCanvas();
- SkCanvas* CreateBitmapCanvas(int width, int height);
-
- inline const char* resource_path() {
- return resource_path_;
- }
-
- virtual ~GraphicsHandler() {
- }
-
- protected:
- const char* resource_path_;
- SkAutoGraphics ag;
- GrContext* grcontext;
- int32_t width_, height_;
-};
-
-extern GraphicsHandler* graphics;
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/image_cache.cc b/runtime/embedders/openglui/common/image_cache.cc
deleted file mode 100644
index 957f7ea..0000000
--- a/runtime/embedders/openglui/common/image_cache.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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.
-
-#include "embedders/openglui/common/image_cache.h"
-
-#include <ctype.h>
-#include <string.h>
-#include "core/SkStream.h"
-#include "embedders/openglui/common/canvas_context.h"
-
-ImageCache* ImageCache::instance_ = NULL;
-
-extern CanvasContext* Context2D(int handle);
-
-ImageCache::ImageCache(const char* resource_path)
- : images(), resource_path_(resource_path) {
-}
-
-const SkBitmap* ImageCache::GetImage_(const char* src_url) {
- if (strncmp(src_url, "context2d://", 12) == 0) {
- int handle = atoi(src_url + 12);
- CanvasContext* otherContext = Context2D(handle);
- return otherContext->GetBitmap();
- } else if (images.find(src_url) == images.end()) {
- SkBitmap* bm = Load(src_url);
- if (bm != NULL) {
- images[src_url] = bm;
- }
- return bm;
- } else {
- return images[src_url];
- }
-}
-
-int ImageCache::GetWidth_(const char* src_url) {
- const SkBitmap* image = GetImage(src_url);
- if (image == NULL) return 0;
- return image->width();
-}
-
-int ImageCache::GetHeight_(const char* src_url) {
- const SkBitmap* image = GetImage(src_url);
- if (image == NULL) return 0;
- return image->height();
-}
-
-SkBitmap* ImageCache::Load(const char* src_url) {
- SkBitmap *bm = NULL;
- const char* filepath;
- if (strncmp(src_url, "file://", 7) == 0) {
- filepath = src_url + 7;
- } else {
- // TODO(gram): We need a way to remap URLs to local file names.
- // For now I am just using the characters after the last '/'.
- // Note also that if we want to support URLs and network fetches,
- // then we introduce more complexity; this can't just be an URL.
- int pos = strlen(src_url);
- while (--pos >= 0 && src_url[pos] != '/');
- filepath = src_url + pos + 1;
- }
- char* path;
- if (filepath[0] == '/') {
- path = const_cast<char*>(filepath);
- } else {
- size_t len1 = strlen(resource_path_);
- size_t len2 = strlen(filepath);
- path = new char[len1 + 1 + len2 + 1];
- strncpy(path, resource_path_, len1+1);
- strncat(path, "/", 1);
- strncat(path, filepath, len2);
- }
-
- SkFILEStream stream(path);
- if (stream.isValid()) {
- // We could use DecodeFile and pass the path, but by creating the
- // SkStream here we can produce better error log messages.
- bm = new SkBitmap();
- if (!SkImageDecoder::DecodeStream(&stream, bm)) {
- LOGI("Image decode of %s failed", path);
- return NULL;
- } else {
- LOGI("Decode image %s: width=%d,height=%d",
- path, bm->width(), bm->height());
- }
- } else {
- LOGI("Path %s is invalid", path);
- }
-
- if (path != filepath) {
- delete[] path;
- }
- return bm;
-}
-
diff --git a/runtime/embedders/openglui/common/image_cache.h b/runtime/embedders/openglui/common/image_cache.h
deleted file mode 100644
index 4aa22f8..0000000
--- a/runtime/embedders/openglui/common/image_cache.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_IMAGE_CACHE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_IMAGE_CACHE_H_
-
-#include <map>
-#include <string>
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/support.h"
-
-class ImageCache {
- public:
- static void Init(const char *resource_path) {
- if (instance_ == NULL) {
- instance_ = new ImageCache(resource_path);
- }
- }
-
- inline static const SkBitmap* GetImage(const char* src_url) {
- if (instance_ == NULL) {
- fprintf(stderr, "GetImage called with no instance_\n");
- return NULL;
- }
- return instance_->GetImage_(src_url);
- }
-
- inline static int GetWidth(const char* src_url) {
- if (instance_ == NULL) {
- fprintf(stderr, "GetWidth called with no instance_\n");
- return NULL;
- }
- return instance_->GetWidth_(src_url);
- }
-
- inline static int GetHeight(const char* src_url) {
- if (instance_ == NULL) {
- fprintf(stderr, "GetHeight called with no instance_\n");
- return NULL;
- }
- return instance_->GetHeight_(src_url);
- }
-
- private:
- explicit ImageCache(const char* resource_path);
- SkBitmap* Load(const char* src_url);
- const SkBitmap* GetImage_(const char* src_url);
- int GetWidth_(const char* src_url);
- int GetHeight_(const char* src_url);
-
- std::map<std::string, SkBitmap*> images;
- const char* resource_path_;
- static ImageCache* instance_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_IMAGE_CACHE_H_
diff --git a/runtime/embedders/openglui/common/input_handler.cc b/runtime/embedders/openglui/common/input_handler.cc
deleted file mode 100644
index 7c4c3d2..0000000
--- a/runtime/embedders/openglui/common/input_handler.cc
+++ /dev/null
@@ -1,76 +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 "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/log.h"
-
-InputHandler::InputHandler(VMGlue* vm_glue)
- : vm_glue_(vm_glue) {
-}
-
-int InputHandler::OnMotionEvent(MotionEvent event,
- int64_t when,
- float x,
- float y) {
- const char *function = NULL;
- // For now we just keep this simple. There are
- // no click events or mouseover events.
- switch (event) {
- case kMotionDown:
- function = "onMouseDown_";
- break;
- case kMotionUp:
- function = "onMouseUp_";
- break;
- case kMotionMove:
- function = "onMouseMove_";
- break;
- case kMotionCancel:
- break;
- case kMotionOutside:
- break;
- case kMotionPointerDown:
- break;
- case kMotionPointerUp:
- break;
- default:
- return -1;
- }
- if (function == NULL) {
- return 0;
- } else {
- return vm_glue_->OnMotionEvent(function, when, x, y);
- }
-}
-
-int InputHandler::OnKeyEvent(KeyEvent event,
- int64_t when,
- int32_t key_code,
- bool isAltKeyDown,
- bool isCtrlKeyDown,
- bool isShiftKeyDown,
- int32_t repeat) {
- const char *function = NULL;
- switch (event) {
- case kKeyDown:
- function = "onKeyDown_";
- break;
- case kKeyUp:
- function = "onKeyUp_";
- break;
- case kKeyMultiple:
- return -1; // TODO(gram): handle this.
- break;
- default:
- return -1;
- }
- return vm_glue_->OnKeyEvent(function, when, key_code,
- isAltKeyDown, isCtrlKeyDown, isShiftKeyDown,
- repeat);
-}
-
-void InputHandler::OnAccelerometerEvent(float x, float y, float z) {
- vm_glue_->OnAccelerometerEvent(x, y, z);
-}
-
diff --git a/runtime/embedders/openglui/common/input_handler.h b/runtime/embedders/openglui/common/input_handler.h
deleted file mode 100644
index 06d6d0f..0000000
--- a/runtime/embedders/openglui/common/input_handler.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_INPUT_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_INPUT_HANDLER_H_
-
-#include "embedders/openglui/common/events.h"
-#include "embedders/openglui/common/vm_glue.h"
-
-class InputHandler {
- public:
- explicit InputHandler(VMGlue* vm_glue);
- virtual int32_t Start() { return 0; }
- virtual void Stop() { }
- virtual int OnMotionEvent(MotionEvent event, int64_t when,
- float move_x, float move_y);
- virtual int OnKeyEvent(KeyEvent event, int64_t when, int32_t key_code,
- bool isAltKeyDown, bool isCtrlKeyDown,
- bool isShiftKeyDown, int32_t repeat);
- virtual void OnAccelerometerEvent(float x, float y, float z);
-
- virtual ~InputHandler() {}
-
- protected:
- VMGlue* vm_glue_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_INPUT_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/isized.h b/runtime/embedders/openglui/common/isized.h
deleted file mode 100644
index b84dde2..0000000
--- a/runtime/embedders/openglui/common/isized.h
+++ /dev/null
@@ -1,21 +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 EMBEDDERS_OPENGLUI_COMMON_ISIZED_H_
-#define EMBEDDERS_OPENGLUI_COMMON_ISIZED_H_
-
-#include <stdint.h>
-
-// An interface for objects that have a size. VMGlue needs the window
-// size when calling setup() (and eventually resize()) but it does not
-// need to know anything else about the window, so we use this interface.
-class ISized {
- public:
- virtual const int32_t& height() = 0;
- virtual const int32_t& width() = 0;
- virtual ~ISized() {}
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_ISIZED_H_
-
diff --git a/runtime/embedders/openglui/common/lifecycle_handler.h b/runtime/embedders/openglui/common/lifecycle_handler.h
deleted file mode 100644
index cc1a659..0000000
--- a/runtime/embedders/openglui/common/lifecycle_handler.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_LIFECYCLE_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_LIFECYCLE_HANDLER_H_
-
-class LifeCycleHandler {
- public:
- virtual int32_t OnStart() = 0;
- virtual int32_t Activate() = 0;
- virtual void Deactivate() = 0;
- virtual int32_t OnStep() = 0;
- virtual void Pause() {}
- virtual int32_t Resume() {
- return 0;
- }
- virtual void FreeAllResources() {}
- virtual void OnSaveState(void** data, size_t* size) {}
- virtual void OnConfigurationChanged() {}
- virtual void OnLowMemory() {}
- virtual ~LifeCycleHandler() {}
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_LIFECYCLE_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/log.h b/runtime/embedders/openglui/common/log.h
deleted file mode 100644
index d74e0f5..0000000
--- a/runtime/embedders/openglui/common/log.h
+++ /dev/null
@@ -1,30 +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 EMBEDDERS_OPENGLUI_COMMON_LOG_H_
-#define EMBEDDERS_OPENGLUI_COMMON_LOG_H_
-
-#ifndef ANDROID
-#include <stdio.h>
-#define LOGI(...) do {\
- fprintf(stdout, __VA_ARGS__);\
- fprintf(stdout, "\n");\
- fflush(stdout);\
- } while (0)
-#define LOGE(...) do { \
- fprintf(stderr, __VA_ARGS__);\
- fprintf(stderr, "\n");\
- fflush(stderr);\
- } while (0)
-#else
-#include "embedders/openglui/android/android_log.h"
-#endif
-
-#ifndef DEBUG
-#undef LOGI
-#define LOGI(...)
-#endif
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_LOG_H_
-
diff --git a/runtime/embedders/openglui/common/opengl.h b/runtime/embedders/openglui/common/opengl.h
deleted file mode 100644
index 3a41415..0000000
--- a/runtime/embedders/openglui/common/opengl.h
+++ /dev/null
@@ -1,57 +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.
-
-// A semi-generic header file that can be used to isolate platform differences
-// for OpenGL headers.
-#ifndef EMBEDDERS_OPENGLUI_COMMON_OPENGL_H_
-#define EMBEDDERS_OPENGLUI_COMMON_OPENGL_H_
-
-#if defined(__APPLE__)
-# ifdef GL_ES_VERSION_2_0
-# include <OpenGLES/ES2/gl.h>
-# else
-# include <Glut/glut.h>
-# include <OpenGL/gl.h>
-# endif
-# define GLSwapBuffers() glutSwapBuffers()
-#elif defined(_WIN32) || defined(_WIN64)
-# include <GL/glew.h>
-# include <GL/wglew.h>
-# include <GLUT/glut.h>
-# include <Windows.h>
-# define GLSwapBuffers() glutSwapBuffers()
-#elif defined(__ANDROID__)
-# include <EGL/egl.h>
-# include <GLES2/gl2.h>
-# include <GLES2/gl2ext.h>
-# define GLSwapBuffers() \
- do {\
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); \
- EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); \
- eglSwapBuffers(display, surface); \
- } while (0);
-#else // Linux.
-# define GL_GLEXT_PROTOTYPES 1
-# include <GL/gl.h>
-# include <GL/glext.h>
-# include <GL/glut.h>
-# define GLSwapBuffers() glutSwapBuffers()
-#endif
-
-#include "core/SkCanvas.h"
-#include "core/SkGraphics.h"
-#include "core/SkPaint.h"
-#include "core/SkTypeface.h"
-#include "effects/SkBlurDrawLooper.h"
-#include "effects/SkDashPathEffect.h"
-#include "effects/SkGradientShader.h"
-#include "gpu/SkGpuDevice.h"
-#include "gpu/GrContext.h"
-#include "gpu/GrRenderTarget.h"
-#include "gpu/gl/GrGLInterface.h"
-#include "gpu/gl/SkNativeGLContext.h"
-#include "images/SkImageDecoder.h"
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_OPENGL_H_
-
diff --git a/runtime/embedders/openglui/common/resource.h b/runtime/embedders/openglui/common/resource.h
deleted file mode 100644
index dd07a68..0000000
--- a/runtime/embedders/openglui/common/resource.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_RESOURCE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_RESOURCE_H_
-
-#include <stdlib.h>
-#include <string.h>
-
-class Resource {
- public:
- explicit Resource(const char* path)
- : descriptor_(-1),
- start_(0),
- length_(-1) {
- path_ = strdup(path);
- }
-
- const char* path() {
- return path_;
- }
-
- virtual int32_t descriptor() {
- return descriptor_;
- }
-
- virtual off_t start() {
- return start_;
- }
-
- virtual off_t length() {
- return length_;
- }
-
- virtual int32_t Open() {
- return -1;
- }
-
- virtual void Close() {
- }
-
- virtual int32_t Read(void* buffer, size_t count) {
- return -1;
- }
-
- virtual ~Resource() {
- free(path_);
- }
-
- protected:
- char* path_;
- int32_t descriptor_;
- off_t start_;
- off_t length_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_RESOURCE_H_
-
diff --git a/runtime/embedders/openglui/common/sample.h b/runtime/embedders/openglui/common/sample.h
deleted file mode 100644
index 5fc4239..0000000
--- a/runtime/embedders/openglui/common/sample.h
+++ /dev/null
@@ -1,63 +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 EMBEDDERS_OPENGLUI_COMMON_SAMPLE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_SAMPLE_H_
-
-#include "embedders/openglui/common/resource.h"
-
-extern Resource* MakePlatformResource(const char *path);
-
-class Sample {
- public:
- explicit Sample(const char* path)
- : buffer_(NULL),
- length_(0) {
- resource_ = MakePlatformResource(path);
- }
-
- ~Sample() {
- Unload();
- delete resource_;
- }
-
- const char* path() {
- return resource_->path();
- }
-
- uint8_t* buffer() {
- return buffer_;
- }
-
- off_t length() {
- return length_;
- }
-
- int32_t Load() {
- int32_t rtn = -1;
- if (resource_->Open() == 0) {
- buffer_ = new uint8_t[length_ = resource_->length()];
- rtn = resource_->Read(buffer_, length_);
- resource_->Close();
- }
- return rtn;
- }
-
- void Unload() {
- if (buffer_ != NULL) {
- delete[] buffer_;
- buffer_ = NULL;
- }
- length_ = 0;
- }
-
- private:
- friend class SoundService;
- Resource* resource_;
- uint8_t* buffer_;
- off_t length_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_SAMPLE_H_
-
diff --git a/runtime/embedders/openglui/common/sound_handler.cc b/runtime/embedders/openglui/common/sound_handler.cc
deleted file mode 100644
index 8af2379..0000000
--- a/runtime/embedders/openglui/common/sound_handler.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-#include "embedders/openglui/common/sound_handler.h"
-
-#include <string.h>
-
-#include "embedders/openglui/common/log.h"
-
-// TODO(gram): Clean up this instance pointer; either make the class
-// a proper singleton or provide a cleaner way for the static functions
-// at the end to access it (those functions are the hooks into the Dart
-// native extension).
-SoundHandler* instance_ = NULL;
-
-SoundHandler::SoundHandler()
- : samples_() {
- instance_ = this;
-}
-
-Sample* SoundHandler::GetSample(const char* path) {
- for (samples_t::iterator sp = samples_.begin();
- sp != samples_.end();
- ++sp) {
- Sample* sample = (*sp);
- if (strcmp(sample->path(), path) == 0) {
- LOGI("Returning cached sample %s", path);
- return sample;
- }
- }
- Sample* sample = new Sample(path);
- if (sample->Load() != 0) {
- LOGI("Failed to load sample %s", path);
- delete sample;
- return NULL;
- }
- samples_.push_back(sample);
- LOGI("Adding sample %s to cache", path);
- return sample;
-}
-
-int32_t PlayBackgroundSound(const char* path) {
- return instance_->PlayBackground(path);
-}
-
-void StopBackgroundSound() {
- instance_->StopBackground();
-}
-
-int32_t LoadSoundSample(const char* path) {
- return instance_->LoadSample(path);
-}
-
-int32_t PlaySoundSample(const char* path) {
- return instance_->PlaySample(path);
-}
-
diff --git a/runtime/embedders/openglui/common/sound_handler.h b/runtime/embedders/openglui/common/sound_handler.h
deleted file mode 100644
index 61090a7..0000000
--- a/runtime/embedders/openglui/common/sound_handler.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_SOUND_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_SOUND_HANDLER_H_
-
-#include <stdint.h>
-#include <vector>
-
-#include "embedders/openglui/common/sample.h"
-
-class SoundHandler {
- public:
- SoundHandler();
-
- virtual ~SoundHandler() {
- }
-
- virtual int32_t Start() {
- return 0;
- }
-
- virtual void Stop() {
- }
-
- virtual int32_t Suspend() {
- return 0;
- }
-
- virtual int32_t Resume() {
- return 0;
- }
-
- virtual int32_t PlayBackground(const char* path) {
- return 0;
- }
-
- virtual void StopBackground() {
- }
-
- // Optional, for preloading.
- int32_t LoadSample(const char* path) {
- return (GetSample(path) == NULL) ? -1 : 0;
- }
-
- virtual int32_t PlaySample(const char* path) {
- // Just do a load so we can get logging.
- return (GetSample(path) == NULL) ? -1 : 0;
- }
-
- protected:
- typedef std::vector<Sample*> samples_t;
-
- Sample* GetSample(const char* path);
-
- samples_t samples_;
-};
-
-int32_t PlayBackgroundSound(const char* path);
-void StopBackgroundSound();
-int32_t LoadSoundSample(const char* path);
-int32_t PlaySoundSample(const char* path);
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_SOUND_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/support.h b/runtime/embedders/openglui/common/support.h
deleted file mode 100644
index 143c9a9..0000000
--- a/runtime/embedders/openglui/common/support.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
-#define EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
-
-#include "embedders/openglui/common/opengl.h"
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-// Colors as used by canvas.
-typedef struct ColorRGBA {
- // We store Skia-compatible values. Skia uses
- // the form AARRGGBB.
- uint32_t v;
-
- inline ColorRGBA(char rp, char gp, char bp, char ap = 255) {
- v = ((static_cast<uint32_t>(rp) & 0xFF) << 16) |
- ((static_cast<uint32_t>(gp) & 0xFF) << 8) |
- ((static_cast<uint32_t>(bp) & 0xFF) << 0) |
- ((static_cast<uint32_t>(ap) & 0xFF) << 24);
- }
- inline ColorRGBA(uint32_t vp)
- : v(vp) {
- }
- inline uint8_t alpha() {
- return (v >> 24) & 0xFF;
- }
-} ColorRGBA;
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
diff --git a/runtime/embedders/openglui/common/timer.cc b/runtime/embedders/openglui/common/timer.cc
deleted file mode 100644
index 9a0e2af..0000000
--- a/runtime/embedders/openglui/common/timer.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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.
-
-#include "embedders/openglui/common/timer.h"
-
-#define NANO (+1.0E-9)
-
-#ifdef __MACH__
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-#include <sys/time.h>
-
-#define GIGA UINT64_C(1000000000)
-
-#define CLOCK_REALTIME 0
-#define CLOCK_MONOTONIC 1
-
-double timebase = 0.0;
-uint64_t timestart = 0;
-
-void clock_gettime(int type, timespec* t) {
- if (!timestart) {
- mach_timebase_info_data_t tb = { 0, 1 };
- mach_timebase_info(&tb);
- timebase = tb.numer;
- timebase /= tb.denom;
- timestart = mach_absolute_time();
- }
- if (type == CLOCK_MONOTONIC) {
- double diff = (mach_absolute_time() - timestart) * timebase;
- t->tv_sec = diff * NANO;
- t->tv_nsec = diff - (t->tv_sec * GIGA);
- } else { // type == CLOCK_REALTIME
- struct timeval now;
- gettimeofday(&now, NULL);
- t->tv_sec = now.tv_sec;
- t->tv_nsec = now.tv_usec * 1000;
- }
-}
-#endif
-
-Timer::Timer() : elapsed_(0.0f), last_time_(0.0) {
-}
-
-void Timer::Reset() {
- elapsed_ = 0.0f;
- last_time_ = Now();
-}
-
-void Timer::Update() {
- double current = Now();
- elapsed_ = (current - last_time_);
- last_time_ = current;
-}
-
-double Timer::Now() {
- timespec timeval;
- clock_gettime(CLOCK_MONOTONIC, &timeval);
- return timeval.tv_sec + (timeval.tv_nsec * NANO);
-}
-
-float Timer::Elapsed() {
- return elapsed_;
-}
-
diff --git a/runtime/embedders/openglui/common/timer.h b/runtime/embedders/openglui/common/timer.h
deleted file mode 100644
index d2f3d67..0000000
--- a/runtime/embedders/openglui/common/timer.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_TIMER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_TIMER_H_
-
-#include <time.h>
-
-class Timer {
- public:
- Timer();
- void Reset();
- void Update();
- double Now();
- float Elapsed();
-
- private:
- float elapsed_;
- double last_time_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_TIMER_H_
-
diff --git a/runtime/embedders/openglui/common/types.h b/runtime/embedders/openglui/common/types.h
deleted file mode 100644
index 8acbe8c..0000000
--- a/runtime/embedders/openglui/common/types.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_TYPES_H_
-#define EMBEDDERS_OPENGLUI_COMMON_TYPES_H_
-
-struct Location {
- Location() : pos_x_(0), pos_y_(0) {
- };
- void setPosition(float pos_x, float pos_y) {
- pos_x_ = pos_x;
- pos_y_ = pos_y;
- }
- void translate(float amount_x, float amount_y) {
- pos_x_ += amount_x;
- pos_y_ += amount_y;
- }
-
- float pos_x_, pos_y_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_TYPES_H_
-
diff --git a/runtime/embedders/openglui/common/vm_glue.cc b/runtime/embedders/openglui/common/vm_glue.cc
deleted file mode 100644
index 91a26db..0000000
--- a/runtime/embedders/openglui/common/vm_glue.cc
+++ /dev/null
@@ -1,398 +0,0 @@
-// 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.
-
-#include <math.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "embedders/openglui/common/extension.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/vm_glue.h"
-#include "include/dart_api.h"
-
-char* VMGlue::extension_script_ = NULL;
-bool VMGlue::initialized_vm_ = false;
-
-// snapshot_buffer points to a snapshot if we link in a snapshot otherwise
-// it is initialized to NULL.
-
-VMGlue::VMGlue(ISized* surface,
- const char* script_path,
- const char* extension_script,
- const char* main_script,
- int setup_flag)
- : surface_(surface),
- isolate_(NULL),
- initialized_script_(false),
- x_(0.0),
- y_(0.0),
- z_(0.0),
- accelerometer_changed_(false),
- setup_flag_(setup_flag) {
- LOGI("Creating VMGlue");
- if (main_script == NULL) {
- main_script = "main.dart";
- }
- if (extension_script == NULL) {
- extension_script = "gl.dart";
- }
- size_t len = strlen(script_path) + strlen(main_script) + 2;
- main_script_ = new char[len];
- snprintf(main_script_, len, "%s/%s", script_path, main_script);
- len = strlen(script_path) + strlen(extension_script) + 2;
- extension_script_ = new char[len];
- snprintf(extension_script_, len, "%s/%s", script_path, extension_script);
-}
-
-Dart_Handle VMGlue::CheckError(Dart_Handle handle) {
- if (Dart_IsError(handle)) {
- LOGE("Unexpected Error Handle: %s", Dart_GetError(handle));
- Dart_PropagateError(handle);
- }
- return handle;
-}
-
-#define CHECK_RESULT(result) \
- if (Dart_IsError(result)) { \
- *error = strdup(Dart_GetError(result)); \
- LOGE("%s", *error); \
- Dart_ExitScope(); \
- Dart_ShutdownIsolate(); \
- return false; \
- }
-
-Dart_Handle VMGlue::LibraryTagHandler(Dart_LibraryTag tag,
- Dart_Handle library,
- Dart_Handle urlHandle) {
- const char* url;
- Dart_StringToCString(urlHandle, &url);
- if (tag == kCanonicalizeUrl) {
- return urlHandle;
- }
- // TODO(vsm): Split this up into separate libraries for 3D, 2D,
- // Touch, Audio, etc. All builtin libraries should be handled here
- // (or moved into a snapshot).
- if (strcmp(url, "gl.dart") == 0) {
- Dart_Handle source =
- VMGlue::LoadSourceFromFile(extension_script_);
- Dart_Handle library = CheckError(Dart_LoadLibrary(urlHandle, source));
- CheckError(Dart_SetNativeResolver(library, ResolveName));
- return library;
- }
- LOGE("UNIMPLEMENTED: load library %s\n", url);
- return NULL;
-}
-
-// Returns true on success, false on failure.
-Dart_Isolate VMGlue::CreateIsolateAndSetupHelper(const char* script_uri,
- const char* main,
- void* data,
- char** error) {
- LOGI("Creating isolate %s, %s", script_uri, main);
- Dart_Isolate isolate =
- Dart_CreateIsolate(script_uri, main, NULL, data, error);
- if (isolate == NULL) {
- LOGE("Couldn't create isolate: %s", *error);
- return NULL;
- }
-
- LOGI("Entering scope");
- Dart_EnterScope();
-
- // Set up the library tag handler for this isolate.
- LOGI("Setting up library tag handler");
- Dart_Handle result = CheckError(Dart_SetLibraryTagHandler(LibraryTagHandler));
- CHECK_RESULT(result);
-
- Dart_ExitScope();
- return isolate;
-}
-
-Dart_Isolate VMGlue::CreateIsolateAndSetup(const char* script_uri,
- const char* main,
- void* data, char** error) {
- return CreateIsolateAndSetupHelper(script_uri,
- main,
- data,
- error);
-}
-
-const char* VM_FLAGS[] = {
- "--enable_type_checks", // TODO(gram): This should be an option!
- // "--trace_isolates",
- // "--trace_natives",
- // "--trace_compiler",
-};
-
-static void* openFileCallback(const char* name, bool write) {
- return fopen(name, write ? "w" : "r");
-}
-
-static void readFileCallback(const uint8_t** data, intptr_t* fileLength,
- void* stream) {
- if (!stream) {
- *data = 0;
- *fileLength = 0;
- } else {
- FILE* file = reinterpret_cast<FILE*>(stream);
-
- // Get the file size.
- fseek(file, 0, SEEK_END);
- *fileLength = ftell(file);
- rewind(file);
-
- // Allocate data buffer.
- *data = new uint8_t[*fileLength];
- *fileLength = fread(const_cast<uint8_t*>(*data), 1, *fileLength, file);
- }
-}
-
-static void writeFileCallback(const void* data, intptr_t length, void* file) {
- fwrite(data, 1, length, reinterpret_cast<FILE*>(file));
-}
-
-static void closeFileCallback(void* file) {
- fclose(reinterpret_cast<FILE*>(file));
-}
-
-int VMGlue::InitializeVM() {
- // We need the next call to get Dart_Initialize not to bail early.
- LOGI("Setting VM Options");
- Dart_SetVMFlags(sizeof(VM_FLAGS) / sizeof(VM_FLAGS[0]), VM_FLAGS);
-
- // Initialize the Dart VM, providing the callbacks to use for
- // creating and shutting down isolates.
- LOGI("Initializing Dart");
- if (!Dart_Initialize(CreateIsolateAndSetup,
- 0,
- 0,
- 0,
- openFileCallback,
- readFileCallback,
- writeFileCallback,
- closeFileCallback)) {
- LOGE("VM initialization failed\n");
- return -1;
- }
- initialized_vm_ = true;
-
- return 0;
-}
-
-Dart_Handle VMGlue::LoadSourceFromFile(const char* url) {
- FILE* file = fopen(url, "r");
- if (file == NULL) {
- LOGE("Main script not found at: %s\n", url);
- return NULL;
- }
-
- struct stat sb;
- int fd = fileno(file);
- fstat(fd, &sb);
- int length = sb.st_size;
- LOGI("Entry file %s is %d bytes.\n", url, length);
-
- char* buffer = new char[length+1];
- if (read(fd, buffer, length) < 0) {
- LOGE("Could not read script %s.\n", url);
- return NULL;
- }
- buffer[length] = 0;
- fclose(file);
-
- Dart_Handle contents = CheckError(Dart_NewStringFromCString(buffer));
- delete[] buffer;
- return contents;
-}
-
-int VMGlue::StartMainIsolate() {
- if (!initialized_vm_) {
- int rtn = InitializeVM();
- if (rtn != 0) return rtn;
- }
-
- // Create an isolate and loads up the application script.
- char* error = NULL;
- if (!CreateIsolateAndSetup(main_script_, "main", NULL, &error)) {
- LOGE("CreateIsolateAndSetup: %s\n", error);
- free(error);
- return -1;
- }
- LOGI("Created isolate");
- isolate_ = Dart_CurrentIsolate();
- Dart_EnterScope();
-
- Dart_Handle url = CheckError(Dart_NewStringFromCString(main_script_));
- Dart_Handle source = LoadSourceFromFile(main_script_);
- CheckError(Dart_LoadScript(url, source, 0, 0));
-
- Dart_ExitScope();
- Dart_ExitIsolate();
- return 0;
-}
-
-int VMGlue::CallSetup(bool force) {
- // TODO(gram): See if we actually need this flag guard here, or if
- // we can eliminate it along with the need for the force parameter.
- if (!initialized_script_ || force) {
- initialized_script_ = true;
- LOGI("Invoking setup(null, %d,%d,%d)",
- surface_->width(), surface_->height(), setup_flag_);
- Dart_EnterIsolate(isolate_);
- Dart_EnterScope();
- Dart_Handle args[4];
- args[0] = CheckError(Dart_Null());
- args[1] = CheckError(Dart_NewInteger(surface_->width()));
- args[2] = CheckError(Dart_NewInteger(surface_->height()));
- args[3] = CheckError(Dart_NewInteger(setup_flag_));
- int rtn = Invoke("setup", 4, args);
-
- if (rtn == 0) {
- // Plug in the print handler. It would be nice if we could do this
- // before calling setup, but the call to GetField blows up if we
- // haven't run anything yet.
- Dart_Handle library = CheckError(Dart_LookupLibrary(
- Dart_NewStringFromCString("gl.dart")));
- Dart_Handle print = CheckError(
- Dart_GetField(library, Dart_NewStringFromCString("_printClosure")));
- Dart_Handle corelib = CheckError(Dart_LookupLibrary(
- Dart_NewStringFromCString("dart:core")));
- CheckError(Dart_SetField(corelib,
- Dart_NewStringFromCString("_printClosure"), print));
- }
- Dart_ExitScope();
- Dart_ExitIsolate();
- LOGI("Done setup");
- return rtn;
- }
- return 0;
-}
-
-int VMGlue::CallUpdate() {
- if (initialized_script_) {
- // If the accelerometer has changed, first do that
- // event.
- Dart_EnterIsolate(isolate_);
- if (accelerometer_changed_) {
- Dart_Handle args[3];
- LOGI("Invoking onAccelerometer(%f,%f,%f)", x_, y_, z_);
- Dart_EnterScope();
- args[0] = CheckError(Dart_NewDouble(x_));
- args[1] = CheckError(Dart_NewDouble(y_));
- args[2] = CheckError(Dart_NewDouble(z_));
- Invoke("onAccelerometer", 3, args, false);
- Dart_ExitScope();
- accelerometer_changed_ = false;
- }
- Dart_EnterScope();
- int rtn = Invoke("update_", 0, 0);
- Dart_ExitScope();
- Dart_ExitIsolate();
- LOGI("Invoke update_ returns %d", rtn);
- return rtn;
- }
- return -1;
-}
-
-int VMGlue::CallShutdown() {
- if (initialized_script_) {
- Dart_EnterIsolate(isolate_);
- Dart_EnterScope();
- int rtn = Invoke("shutdown", 0, 0);
- Dart_ExitScope();
- Dart_ExitIsolate();
- return rtn;
- }
- return -1;
-}
-
-int VMGlue::OnMotionEvent(const char* pFunction, int64_t pWhen,
- float pMoveX, float pMoveY) {
- if (initialized_script_) {
- LOGI("Invoking %s", pFunction);
- Dart_EnterIsolate(isolate_);
- Dart_EnterScope();
- Dart_Handle args[3];
- args[0] = CheckError(Dart_NewInteger(pWhen));
- args[1] = CheckError(Dart_NewDouble(pMoveX));
- args[2] = CheckError(Dart_NewDouble(pMoveY));
- int rtn = Invoke(pFunction, 3, args, false);
- Dart_ExitScope();
- Dart_ExitIsolate();
- LOGI("Done %s", pFunction);
- return rtn;
- }
- return -1;
-}
-
-int VMGlue::OnKeyEvent(const char* function, int64_t when, int32_t key_code,
- bool isAltKeyDown, bool isCtrlKeyDown,
- bool isShiftKeyDown, int32_t repeat) {
- if (initialized_script_) {
- LOGI("Invoking %s(_,%d,...)", function, key_code);
- Dart_EnterIsolate(isolate_);
- Dart_EnterScope();
- Dart_Handle args[6];
- args[0] = CheckError(Dart_NewInteger(when));
- args[1] = CheckError(Dart_NewInteger(key_code));
- args[2] = CheckError(Dart_NewBoolean(isAltKeyDown));
- args[3] = CheckError(Dart_NewBoolean(isCtrlKeyDown));
- args[4] = CheckError(Dart_NewBoolean(isShiftKeyDown));
- args[5] = CheckError(Dart_NewInteger(repeat));
- int rtn = Invoke(function, 6, args, false);
- Dart_ExitScope();
- Dart_ExitIsolate();
- LOGI("Done %s", function);
- return rtn;
- }
- return -1;
-}
-
-int VMGlue::Invoke(const char* function,
- int argc,
- Dart_Handle* args,
- bool failIfNotDefined) {
- // Lookup the library of the root script.
- Dart_Handle library = Dart_RootLibrary();
- if (Dart_IsNull(library)) {
- LOGE("Unable to find root library\n");
- return -1;
- }
-
- Dart_Handle nameHandle = Dart_NewStringFromCString(function);
-
- Dart_Handle result = Dart_Invoke(library, nameHandle, argc, args);
-
- if (Dart_IsError(result)) {
- const char* error = Dart_GetError(result);
- LOGE("Invoke %s failed: %s", function, error);
- if (failIfNotDefined) {
- return -1;
- }
- }
-
- // TODO(vsm): I don't think we need this.
- // Keep handling messages until the last active receive port is closed.
- result = Dart_RunLoop();
- if (Dart_IsError(result)) {
- LOGE("Dart_RunLoop: %s\n", Dart_GetError(result));
- return -1;
- }
-
- return 0;
-}
-
-void VMGlue::FinishMainIsolate() {
- LOGI("Finish main isolate");
- Dart_EnterIsolate(isolate_);
- // Shutdown the isolate.
- Dart_ShutdownIsolate();
- isolate_ = NULL;
- initialized_script_ = false;
-}
-
diff --git a/runtime/embedders/openglui/common/vm_glue.h b/runtime/embedders/openglui/common/vm_glue.h
deleted file mode 100644
index 8f84377..0000000
--- a/runtime/embedders/openglui/common/vm_glue.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_VM_GLUE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_VM_GLUE_H_
-
-#include <stdlib.h>
-
-#include "embedders/openglui/common/events.h"
-#include "embedders/openglui/common/isized.h"
-#include "include/dart_api.h"
-
-class VMGlue {
- public:
- explicit VMGlue(ISized* surface,
- const char* script_path,
- const char* extension_script = NULL,
- const char* main_script = NULL,
- int setup_flag = 0);
- ~VMGlue() {
- delete[] main_script_;
- delete[] extension_script_;
- }
-
- int InitializeVM();
- int StartMainIsolate();
- int CallSetup(bool force = false);
- int CallUpdate();
- int CallShutdown();
- int OnMotionEvent(const char* funtion, int64_t when,
- float move_x, float move_y);
- int OnKeyEvent(const char* funtion, int64_t when, int32_t key_code,
- bool isAltKeyDown, bool isCtrlKeyDown, bool isShiftKeyDown,
- int32_t repeat);
- inline void OnAccelerometerEvent(float x, float y, float z) {
- if (x != x_ || y != y_ || z != z_) {
- x_ = x;
- y_ = y;
- z_ = z;
- accelerometer_changed_ = true;
- }
- }
-
- void FinishMainIsolate();
-
- private:
- int Invoke(const char *function, int argc, Dart_Handle* args,
- bool failIfNotDefined = true);
-
- static Dart_Handle CheckError(Dart_Handle);
-
- static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
- const char* main,
- void* data,
- char** error);
- static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
- const char* main,
- void* data, char** error);
- static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
- Dart_Handle library,
- Dart_Handle urlHandle);
- static Dart_Handle LoadSourceFromFile(const char* url);
- static void ShutdownIsolate(void* callback_data);
-
- static bool initialized_vm_;
- static char* extension_script_;
- ISized* surface_;
- Dart_Isolate isolate_;
- bool initialized_script_;
- char* main_script_;
- float x_, y_, z_; // Last values from accelerometer.
- bool accelerometer_changed_;
- int setup_flag_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_COMMON_VM_GLUE_H_
-
diff --git a/runtime/embedders/openglui/emulator/emulator_embedder.cc b/runtime/embedders/openglui/emulator/emulator_embedder.cc
deleted file mode 100644
index de01870..0000000
--- a/runtime/embedders/openglui/emulator/emulator_embedder.cc
+++ /dev/null
@@ -1,132 +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 "embedders/openglui/emulator/emulator_embedder.h"
-
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-#include "embedders/openglui/common/canvas_context.h"
-#include "embedders/openglui/common/context.h"
-#include "embedders/openglui/common/dart_host.h"
-#include "embedders/openglui/common/events.h"
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/sound_handler.h"
-#include "embedders/openglui/common/vm_glue.h"
-#include "embedders/openglui/emulator/emulator_graphics_handler.h"
-#include "embedders/openglui/emulator/emulator_resource.h"
-
-InputHandler* input_handler_ptr;
-LifeCycleHandler* lifecycle_handler_ptr;
-
-struct timeval tvStart;
-void tick(int data);
-
-Resource* MakePlatformResource(const char *path) {
- return new EmulatorResource(path);
-}
-
-void display() {
- // Get number of msecs since last call.
- struct timeval tvEnd;
- gettimeofday(&tvEnd, NULL);
- uint64_t now = (tvEnd.tv_usec + 1000000 * tvEnd.tv_sec);
-
- if (lifecycle_handler_ptr->OnStep() != 0) {
- exit(-1);
- }
- // Schedule next call, trying to aim for 60fps.
- uint64_t elapsed = now - (tvStart.tv_usec + 1000000 * tvStart.tv_sec);
- int delay = 1000 / 60 - (elapsed / 1000);
- if (delay < 0) delay = 0;
- tvStart = tvEnd;
- glutTimerFunc(delay, tick, 0);
-}
-
-void tick(int data) {
- display();
-}
-
-void reshape(int width, int height) {
- glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, width, 0, height, -1, 1);
- glMatrixMode(GL_MODELVIEW);
- glutPostRedisplay();
-}
-
-void keyboard(unsigned char key, int x, int y) {
- input_handler_ptr->OnKeyEvent(kKeyDown, time(0), key, false, false, false, 0);
- input_handler_ptr->OnKeyEvent(kKeyUp, time(0), key, false, false, false, 0);
- if (key == 'Q') {
- lifecycle_handler_ptr->Pause();
- lifecycle_handler_ptr->Deactivate();
- lifecycle_handler_ptr->FreeAllResources();
- exit(0);
- } else if (key == 'S') {
- LOGI("Simulating suspend");
- lifecycle_handler_ptr->Pause();
- lifecycle_handler_ptr->Deactivate();
- } else if (key == 'R') {
- LOGI("Simulating resume");
- lifecycle_handler_ptr->Activate();
- lifecycle_handler_ptr->Resume();
- } else if (key == '+') {
- LOGI("Simulating focus gain");
- lifecycle_handler_ptr->Resume();
- } else if (key == '-') {
- LOGI("Simulating focus loss");
- lifecycle_handler_ptr->Pause();
- }
-}
-
-void mouse(int button, int state, int x, int y) {
- if (state == GLUT_UP) {
- input_handler_ptr->OnMotionEvent(kMotionUp, time(0), x, y);
- } else if (state == GLUT_DOWN) {
- input_handler_ptr->OnMotionEvent(kMotionDown, time(0), x, y);
- }
-}
-
-void motion(int x, int y) {
- input_handler_ptr->OnMotionEvent(kMotionMove, time(0), x, y);
-}
-
-DART_EXPORT void emulator_main(int argc, char** argv, const char* script) {
- EmulatorGraphicsHandler graphics_handler(argc, argv);
- if (argc > 0) {
- int i = argc - 1;
- size_t len = strlen(argv[i]);
- if (len > 5 && strcmp(".dart", argv[i] + len - 5) == 0) {
- script = argv[i];
- }
- }
- VMGlue vm_glue(&graphics_handler, ".", "gl.dart", script, 1);
- InputHandler input_handler(&vm_glue);
- input_handler_ptr = &input_handler;
- SoundHandler sound_handler;
- Timer timer;
- Context app_context;
- app_context.graphics_handler = &graphics_handler;
- app_context.input_handler = &input_handler;
- app_context.sound_handler = &sound_handler;
- app_context.timer = &timer;
- app_context.vm_glue = &vm_glue;
- DartHost host(&app_context);
- lifecycle_handler_ptr = &host;
- glutReshapeFunc(reshape);
- glutDisplayFunc(display);
- glutKeyboardFunc(keyboard);
- glutMouseFunc(mouse);
- glutMotionFunc(motion);
- lifecycle_handler_ptr->OnStart();
- lifecycle_handler_ptr->Activate();
- lifecycle_handler_ptr->Resume();
- gettimeofday(&tvStart, NULL);
- glutTimerFunc(1, tick, 0);
- glutMainLoop();
-}
-
diff --git a/runtime/embedders/openglui/emulator/emulator_embedder.h b/runtime/embedders/openglui/emulator/emulator_embedder.h
deleted file mode 100644
index f0f0638..0000000
--- a/runtime/embedders/openglui/emulator/emulator_embedder.h
+++ /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.
-
-#ifndef EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_EMBEDDER_H_
-#define EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_EMBEDDER_H_
-
-#include "include/dart_api.h"
-
-DART_EXPORT void emulator_main(int argc, char** argv,
- const char* script);
-
-#endif // EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_EMBEDDER_H_
-
diff --git a/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc b/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc
deleted file mode 100644
index 606dc76..0000000
--- a/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc
+++ /dev/null
@@ -1,39 +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 "embedders/openglui/emulator/emulator_graphics_handler.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-EmulatorGraphicsHandler::EmulatorGraphicsHandler(int argc,
- char** argv)
- : GraphicsHandler(".") {
- glutInit(&argc, argv);
- width_ = 800;
- height_ = 480;
- for (int i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- int next_arg = i + 1;
- if (next_arg < argc && strcmp(argv[i], "-w") == 0) {
- width_ = static_cast<size_t>(atoi(argv[i = next_arg]));
- } else if (next_arg < argc && strcmp(argv[i], "-h") == 0) {
- height_ = static_cast<size_t>(atoi(argv[i = next_arg]));
- }
- }
- }
- SetViewport(0, 0, width_, height_);
- glutInitWindowSize(width_, height_);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL);
- glutCreateWindow("Dart");
-}
-
-int32_t EmulatorGraphicsHandler::Start() {
- return GraphicsHandler::Start();
-}
-
-void EmulatorGraphicsHandler::Stop() {
- GraphicsHandler::Stop();
-}
-
diff --git a/runtime/embedders/openglui/emulator/emulator_graphics_handler.h b/runtime/embedders/openglui/emulator/emulator_graphics_handler.h
deleted file mode 100644
index 4a29270..0000000
--- a/runtime/embedders/openglui/emulator/emulator_graphics_handler.h
+++ /dev/null
@@ -1,19 +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 EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_GRAPHICS_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_GRAPHICS_HANDLER_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-
-class EmulatorGraphicsHandler : public GraphicsHandler {
- public:
- EmulatorGraphicsHandler(int argc, char** argv);
-
- int32_t Start();
- void Stop();
-};
-
-#endif // EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_GRAPHICS_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/emulator/emulator_resource.h b/runtime/embedders/openglui/emulator/emulator_resource.h
deleted file mode 100644
index fc54f8a..0000000
--- a/runtime/embedders/openglui/emulator/emulator_resource.h
+++ /dev/null
@@ -1,64 +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 EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_RESOURCE_H_
-#define EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_RESOURCE_H_
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/resource.h"
-
-class EmulatorResource : public Resource {
- public:
- explicit EmulatorResource(const char* path)
- : Resource(path),
- fd_(-1) {
- }
-
- int32_t descriptor() {
- if (fd_ < 0) {
- Open();
- }
- return fd_;
- }
-
- off_t length() {
- if (length_ < 0) {
- length_ = lseek(fd_, 0, SEEK_END);
- lseek(fd_, 0, SEEK_SET);
- }
- return length_;
- }
-
- int32_t Open() {
- fd_ = open(path_, 0);
- if (fd_ >= 0) {
- return 0;
- }
- LOGE("Could not open asset %s", path_);
- return -1;
- }
-
- void Close() {
- if (fd_ >= 0) {
- close(fd_);
- fd_ = -1;
- }
- }
-
- int32_t Read(void* buffer, size_t count) {
- size_t actual = read(fd_, buffer, count);
- return (actual == count) ? 0 : -1;
- }
-
- private:
- int fd_;
-};
-
-#endif // EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_RESOURCE_H_
-
diff --git a/runtime/embedders/openglui/openglui_embedder.gypi b/runtime/embedders/openglui/openglui_embedder.gypi
deleted file mode 100644
index 4b058cc..0000000
--- a/runtime/embedders/openglui/openglui_embedder.gypi
+++ /dev/null
@@ -1,310 +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.
-
-{
- # TODO(gram) : figure out how to make this be autoconfigured.
- # I've tried a bunch of things with no success yet.
- 'variables': {
- 'skia_build_flag' : '--release',
- 'skia_libs_location_android': '-Lthird_party/skia/trunk/out/config/android-x86/Release/obj.target/gyp',
- 'skia_libs_location_desktop': '-Lthird_party/skia/trunk/out/Release',
- },
- 'conditions': [
- ['OS=="android"',
- {
- 'targets': [
- {
- # Dart shared library for Android.
- 'target_name': 'android_embedder',
- 'type': 'shared_library',
- 'dependencies': [
- 'skia-android',
- 'libdart_lib_withcore',
- 'libdart_vm',
- 'libjscre',
- 'libdouble_conversion',
- 'generate_version_cc_file#host',
- ],
- 'include_dirs': [
- '../..',
- '../../../third_party/android_tools/ndk/sources/android/native_app_glue',
- '../../../third_party/skia/trunk/include',
- '../../../third_party/skia/trunk/include/config',
- '../../../third_party/skia/trunk/include/core',
- '../../../third_party/skia/trunk/include/gpu',
- '../../../third_party/skia/trunk/include/lazy',
- '../../../third_party/skia/trunk/include/utils',
- ],
- 'defines': [
- 'DART_SHARED_LIB',
- '__ANDROID__',
- 'SK_BUILD_FOR_ANDROID',
- 'SK_BUILD_FOR_ANDROID_NDK',
- ],
- 'sources': [
- '../../include/dart_api.h',
- '../../include/dart_debugger_api.h',
- '../../vm/dart_api_impl.cc',
- '../../vm/debugger_api_impl.cc',
- '../../vm/version.h',
- '../../../third_party/android_tools/ndk/sources/android/native_app_glue/android_native_app_glue.h',
- '../../../third_party/android_tools/ndk/sources/android/native_app_glue/android_native_app_glue.c',
- '../../../third_party/skia/trunk/src/core/SkPaintOptionsAndroid.cpp',
- 'android/android_graphics_handler.cc',
- 'android/android_graphics_handler.h',
- 'android/android_input_handler.h',
- 'android/android_resource.h',
- 'android/android_sound_handler.cc',
- 'android/android_sound_handler.h',
- 'android/eventloop.cc',
- 'android/eventloop.h',
- 'android/log.h',
- 'android/main.cc',
- 'android/support_android.cc',
- 'common/canvas_context.cc',
- 'common/canvas_context.h',
- 'common/canvas_state.cc',
- 'common/canvas_state.h',
- 'common/context.h',
- 'common/dart_host.cc',
- 'common/dart_host.h',
- 'common/events.h',
- 'common/extension.cc',
- 'common/extension.h',
- 'common/graphics_handler.cc',
- 'common/graphics_handler.h',
- 'common/image_cache.cc',
- 'common/image_cache.h',
- 'common/input_handler.cc',
- 'common/input_handler.h',
- 'common/isized.h',
- 'common/life_cycle_handler.h',
- 'common/log.h',
- 'common/opengl.h',
- 'common/resource.h',
- 'common/sample.h',
- 'common/sound_handler.cc',
- 'common/sound_handler.h',
- 'common/support.h',
- 'common/timer.cc',
- 'common/timer.h',
- 'common/types.h',
- 'common/vm_glue.cc',
- 'common/vm_glue.h',
- '<(version_cc_file)',
- ],
- 'link_settings': {
- 'ldflags': [
- # The libraries we need should all be in
- # Lthird_party/skia/trunk/out/config/android-x86/Debug but
- # As I (gram) want to avoid patching the Skia gyp files to build
- # real libraries we'll just point to the location of the 'thin'
- # libraries used by the Skia build for now.
- # TODO(gram): We need to support debug vs release modes.
- '<(skia_libs_location_android)',
- '-z',
- 'muldefs',
- ],
- 'ldflags!': [
- '-Wl,--exclude-libs=ALL,-shared',
- ],
- 'libraries': [
- '-Wl,--start-group',
- '-lexpat',
- '-lfreetype',
- '-lgif',
- '-ljpeg',
- '-lpng',
- '-lwebp_dec',
- '-lwebp_utils',
- '-lwebp_dsp',
- '-lwebp_enc',
- '-lskia_core',
- '-lskia_effects',
- '-lskia_gr',
- '-lskia_images',
- '-lskia_opts',
- '-lskia_pdf',
- '-lskia_ports',
- '-lskia_sfnt',
- '-lskia_skgr',
- '-lskia_utils',
- '-lskia_views',
- '-lskia_xml',
- '-lzlib',
- '-Wl,--end-group',
- '-llog',
- '-lc',
- '-lz',
- '-landroid',
- '-lEGL',
- '-lGLESv2',
- '-lOpenSLES',
- '-landroid',
- ],
- },
- },
- {
- 'target_name': 'skia-android',
- 'type': 'none',
- 'actions': [
- {
- 'action_name': 'build_skia',
- 'inputs': [
- 'build_skia.sh'
- ],
- 'outputs': [
- 'dummy' # To force re-execution every time.
- ],
- # For now we drive the build from a shell
- # script, to get us going. Eventually we will
- # want to either fork Skia or incorporate its
- # gclient settings into ours, and include its
- # gyp files within ours, so that it gets built
- # as part of our tree.
- 'action': [
- 'embedders/openglui/build_skia.sh',
- '--android',
- '<(skia_build_flag)',
- '..'
- ],
- 'message': 'Building Skia.'
- }
- ]
- }
- ],
- },
- ],
- ['OS=="mac" or OS=="linux"',
- {
- 'targets': [
- {
- 'target_name': 'emulator_embedder',
- 'type': 'static_library',
- 'dependencies': [
- 'skia-desktop',
- 'libdart_lib_withcore',
- 'libdart_vm',
- 'libjscre',
- 'libdouble_conversion',
- 'generate_version_cc_file',
- ],
- 'include_dirs': [
- '../..',
- '/usr/X11/include',
- '../../../third_party/skia/trunk/include',
- '../../../third_party/skia/trunk/include/config',
- '../../../third_party/skia/trunk/include/core',
- '../../../third_party/skia/trunk/include/gpu',
- '../../../third_party/skia/trunk/include/lazy',
- '../../../third_party/skia/trunk/include/utils',
- ],
- 'defines': [
- 'DART_SHARED_LIB'
- ],
- 'sources': [
- '../../include/dart_api.h',
- '../../include/dart_debugger_api.h',
- '../../vm/dart_api_impl.cc',
- '../../vm/debugger_api_impl.cc',
- '../../vm/version.h',
- 'common/canvas_context.cc',
- 'common/canvas_context.h',
- 'common/canvas_state.cc',
- 'common/canvas_state.h',
- 'common/context.h',
- 'common/dart_host.cc',
- 'common/dart_host.h',
- 'common/events.h',
- 'common/extension.cc',
- 'common/extension.h',
- 'common/graphics_handler.cc',
- 'common/graphics_handler.h',
- 'common/image_cache.cc',
- 'common/image_cache.h',
- 'common/input_handler.cc',
- 'common/input_handler.h',
- 'common/isized.h',
- 'common/life_cycle_handler.h',
- 'common/log.h',
- 'common/opengl.h',
- 'common/resource.h',
- 'common/sample.h',
- 'common/sound_handler.cc',
- 'common/sound_handler.h',
- 'common/support.h',
- 'common/support.h',
- 'common/timer.cc',
- 'common/timer.h',
- 'common/types.h',
- 'common/vm_glue.cc',
- 'common/vm_glue.h',
- 'emulator/emulator_embedder.cc',
- 'emulator/emulator_embedder.h',
- 'emulator/emulator_graphics_handler.cc',
- 'emulator/emulator_graphics_handler.h',
- 'emulator/emulator_resource.h',
- '<(version_cc_file)',
- ],
- 'link_settings': {
- 'ldflags': [
- '-Wall',
- '<(skia_libs_location_desktop)',
- '-Wl,--start-group',
- '-lskia_core',
- '-lskia_effects',
- '-lskia_gr',
- '-lskia_images',
- '-lskia_opts',
- '-lskia_opts_ssse3',
- '-lskia_ports',
- '-lskia_sfnt',
- '-lskia_skgr',
- '-lskia_utils',
- '-Wl,--end-group',
- '-lfreetype',
- ],
- 'libraries': [
- '-lGL',
- '-lglut',
- '-lGLU',
- '-lm',
- '-lwebp'
- ],
- },
- 'conditions': [
- ['OS=="mac"', {
- 'xcode_settings' : {
- 'OTHER_LDFLAGS': [ '-framework OpenGL', '-framework GLUT', '-L /usr/X11/lib' ]
- },
- }],
- ]
- },
- {
- 'target_name': 'skia-desktop',
- 'type': 'none',
- 'actions': [
- {
- 'action_name': 'build_skia',
- 'inputs': [
- 'build_skia.sh'
- ],
- 'outputs': [
- 'dummy' # To force re-execution every time.
- ],
- 'action': [
- 'embedders/openglui/build_skia.sh',
- '<(skia_build_flag)',
- '..'
- ],
- 'message': 'Building Skia.'
- }
- ]
- }
- ],
- },
- ],
- ],
-}
-
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index a09f212..9f4969e 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -185,9 +185,13 @@
* can be used to store objects across scopes. Persistent handles have
* the lifetime of the current isolate unless they are explicitly
* deallocated (see Dart_DeletePersistentHandle).
+ * The type Dart_Handle represents a handle (both local and persistent).
+ * The type Dart_PersistentHandle is a Dart_Handle and it is used to
+ * document that a persistent handle is expected as a parameter to a call
+ * or the return value from a call is a persistent handle.
*/
typedef struct _Dart_Handle* Dart_Handle;
-typedef struct _Dart_PersistentHandle* Dart_PersistentHandle;
+typedef Dart_Handle Dart_PersistentHandle;
typedef struct _Dart_WeakPersistentHandle* Dart_WeakPersistentHandle;
typedef void (*Dart_WeakPersistentHandleFinalizer)(
@@ -2241,9 +2245,9 @@
* \param url A url identifying the origin of the patch source
* \param source A string of Dart patch source
*/
-DART_EXPORT Dart_Handle Dart_LoadPatch(Dart_Handle library,
- Dart_Handle url,
- Dart_Handle patch_source);
+DART_EXPORT Dart_Handle Dart_LibraryLoadPatch(Dart_Handle library,
+ Dart_Handle url,
+ Dart_Handle patch_source);
/*
diff --git a/runtime/lib/array.cc b/runtime/lib/array.cc
index 7116f5b..c81aef2 100644
--- a/runtime/lib/array.cc
+++ b/runtime/lib/array.cc
@@ -12,7 +12,7 @@
namespace dart {
-DEFINE_NATIVE_ENTRY(ObjectArray_allocate, 2) {
+DEFINE_NATIVE_ENTRY(List_allocate, 2) {
const AbstractTypeArguments& type_arguments =
AbstractTypeArguments::CheckedHandle(isolate, arguments->NativeArgAt(0));
const Instance& length = Instance::CheckedHandle(
@@ -21,18 +21,14 @@
const String& error = String::Handle(String::NewFormatted(
"Length must be an integer in the range [0..%" Pd "].",
Array::kMaxElements));
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, error);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(error);
}
intptr_t len = Smi::Cast(length).Value();
if (len < 0 || len > Array::kMaxElements) {
const String& error = String::Handle(String::NewFormatted(
"Length (%" Pd ") must be an integer in the range [0..%" Pd "].",
len, Array::kMaxElements));
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, error);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(error);
}
const Array& new_array = Array::Handle(Array::New(len));
new_array.SetTypeArguments(type_arguments);
@@ -40,7 +36,7 @@
}
-DEFINE_NATIVE_ENTRY(ObjectArray_getIndexed, 2) {
+DEFINE_NATIVE_ENTRY(List_getIndexed, 2) {
const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
if ((index.Value() < 0) || (index.Value() >= array.Length())) {
@@ -52,7 +48,7 @@
}
-DEFINE_NATIVE_ENTRY(ObjectArray_setIndexed, 3) {
+DEFINE_NATIVE_ENTRY(List_setIndexed, 3) {
const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(2));
@@ -66,14 +62,14 @@
}
-DEFINE_NATIVE_ENTRY(ObjectArray_getLength, 1) {
+DEFINE_NATIVE_ENTRY(List_getLength, 1) {
const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
return Smi::New(array.Length());
}
// ObjectArray src, int srcStart, int dstStart, int count.
-DEFINE_NATIVE_ENTRY(ObjectArray_copyFromObjectArray, 5) {
+DEFINE_NATIVE_ENTRY(List_copyFromObjectArray, 5) {
const Array& dest = Array::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Array, source, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, src_start, arguments->NativeArgAt(2));
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index e16cbef..89ddce5 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -4,26 +4,26 @@
// TODO(srdjan): Use shared array implementation.
-class _ObjectArray<E> implements List<E> {
- static final int _classId = (new _ObjectArray(0))._cid;
+class _List<E> implements List<E> {
+ static final int _classId = (new _List(0))._cid;
- factory _ObjectArray(length) native "ObjectArray_allocate";
+ factory _List(length) native "List_allocate";
- E operator [](int index) native "ObjectArray_getIndexed";
+ E operator [](int index) native "List_getIndexed";
- void operator []=(int index, E value) native "ObjectArray_setIndexed";
+ void operator []=(int index, E value) native "List_setIndexed";
String toString() {
return IterableMixinWorkaround.toStringIterable(this,'[' , ']');
}
- int get length native "ObjectArray_getLength";
+ int get length native "List_getLength";
- void _copyFromObjectArray(_ObjectArray src,
+ void _copyFromObjectArray(_List src,
int srcStart,
int dstStart,
int count)
- native "ObjectArray_copyFromObjectArray";
+ native "List_copyFromObjectArray";
void insert(int index, E element) {
throw new UnsupportedError(
@@ -74,7 +74,7 @@
int length = end - start;
if (length == 0) return;
- if (iterable is _ObjectArray) {
+ if (iterable is _List) {
_copyFromObjectArray(iterable, skipCount, start, length);
} else {
List otherList;
@@ -110,7 +110,7 @@
if (end == null) end = this.length;
int length = end - start;
if (start == end) return [];
- List list = new _GrowableObjectArray<E>.withCapacity(length);
+ List list = new _GrowableList<E>.withCapacity(length);
list.length = length;
Arrays.copy(this, start, list, 0, length);
return list;
@@ -270,29 +270,29 @@
}
-// This is essentially the same class as _ObjectArray, but it does not
+// This is essentially the same class as _List, but it does not
// permit any modification of array elements from Dart code. We use
// this class for arrays constructed from Dart array literals.
// TODO(hausner): We should consider the trade-offs between two
// classes (and inline cache misses) versus a field in the native
// implementation (checks when modifying). We should keep watching
// the inline cache misses.
-class _ImmutableArray<E> implements List<E> {
+class _ImmutableList<E> implements List<E> {
static final int _classId = (const [])._cid;
- factory _ImmutableArray._uninstantiable() {
+ factory _ImmutableList._uninstantiable() {
throw new UnsupportedError(
"ImmutableArray can only be allocated by the VM");
}
- E operator [](int index) native "ObjectArray_getIndexed";
+ E operator [](int index) native "List_getIndexed";
void operator []=(int index, E value) {
throw new UnsupportedError(
"Cannot modify an immutable array");
}
- int get length native "ObjectArray_getLength";
+ int get length native "List_getLength";
void insert(int index, E element) {
throw new UnsupportedError(
@@ -537,7 +537,7 @@
_FixedSizeArrayIterator(List array)
: _array = array, _length = array.length, _position = -1 {
- assert(array is _ObjectArray || array is _ImmutableArray);
+ assert(array is _List || array is _ImmutableList);
}
bool moveNext() {
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index 386e8ac..cb9ca76 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -13,17 +13,17 @@
patch class List<E> {
/* patch */ factory List([int length = _GROWABLE_ARRAY_MARKER]) {
if (identical(length, _GROWABLE_ARRAY_MARKER)) {
- return new _GrowableObjectArray<E>(0);
+ return new _GrowableList<E>(0);
}
// All error handling on the length parameter is done at the implementation
- // of new _ObjectArray.
- return new _ObjectArray<E>(length);
+ // of new _List.
+ return new _List<E>(length);
}
/* patch */ factory List.filled(int length, E fill) {
// All error handling on the length parameter is done at the implementation
- // of new _ObjectArray.
- var result = new _ObjectArray<E>(length);
+ // of new _List.
+ var result = new _List<E>(length);
if (fill != null) {
for (int i = 0; i < length; i++) {
result[i] = fill;
@@ -36,9 +36,9 @@
// [elements] contains elements that are already type checked.
factory List._fromLiteral(List elements) {
if (elements.isEmpty) {
- return new _GrowableObjectArray<E>(0);
+ return new _GrowableList<E>(0);
}
- var result = new _GrowableObjectArray<E>.withData(elements);
+ var result = new _GrowableList<E>.withData(elements);
result._setLength(elements.length);
return result;
}
diff --git a/runtime/lib/date.cc b/runtime/lib/date.cc
index 154f1fe..f1b0298 100644
--- a/runtime/lib/date.cc
+++ b/runtime/lib/date.cc
@@ -20,9 +20,7 @@
Integer, dart_seconds, arguments->NativeArgAt(0));
int64_t seconds = dart_seconds.AsInt64Value();
if (seconds < 0 || seconds > kMaxAllowedSeconds) {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, dart_seconds);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(dart_seconds);
}
const char* name = OS::GetTimeZoneName(seconds);
return String::New(name);
@@ -34,9 +32,7 @@
Integer, dart_seconds, arguments->NativeArgAt(0));
int64_t seconds = dart_seconds.AsInt64Value();
if (seconds < 0 || seconds > kMaxAllowedSeconds) {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, dart_seconds);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(dart_seconds);
}
int offset = OS::GetTimeZoneOffsetInSeconds(seconds);
return Integer::New(offset);
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index b37c526..1cadbdb 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -219,10 +219,8 @@
&& kLowerBoundary < d && d < kUpperBoundary) {
return DoubleToStringAsFixed(d, static_cast<int>(fraction_digits_value));
} else {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, String::Handle(
+ Exceptions::ThrowArgumentError(String::Handle(
String::New("Illegal arguments to double.toStringAsFixed")));
- Exceptions::ThrowByType(Exceptions::kArgument, args);
return Object::null();
}
}
@@ -237,10 +235,8 @@
return DoubleToStringAsExponential(
d, static_cast<int>(fraction_digits_value));
} else {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, String::Handle(
+ Exceptions::ThrowArgumentError(String::Handle(
String::New("Illegal arguments to double.toStringAsExponential")));
- Exceptions::ThrowByType(Exceptions::kArgument, args);
return Object::null();
}
}
@@ -254,10 +250,8 @@
if (1 <= precision_value && precision_value <= 21) {
return DoubleToStringAsPrecision(d, static_cast<int>(precision_value));
} else {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, String::Handle(
+ Exceptions::ThrowArgumentError(String::Handle(
String::New("Illegal arguments to double.toStringAsPrecision")));
- Exceptions::ThrowByType(Exceptions::kArgument, args);
return Object::null();
}
}
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 8c41892..82e6df1 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -33,6 +33,7 @@
isolate, arguments->NativeArgAt(0));
ASSERT(receiver.IsClosure());
GET_NATIVE_ARGUMENT(Instance, other, arguments->NativeArgAt(1));
+ ASSERT(!other.IsNull());
if (receiver.raw() == other.raw()) return Bool::True().raw();
if (other.IsClosure()) {
const Function& func_a = Function::Handle(Closure::function(receiver));
diff --git a/runtime/lib/growable_array.cc b/runtime/lib/growable_array.cc
index a080325..34f60a0 100644
--- a/runtime/lib/growable_array.cc
+++ b/runtime/lib/growable_array.cc
@@ -12,7 +12,7 @@
namespace dart {
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_allocate, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_allocate, 2) {
const AbstractTypeArguments& type_arguments =
AbstractTypeArguments::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Array, data, arguments->NativeArgAt(1));
@@ -29,7 +29,7 @@
}
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_getIndexed, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_getIndexed, 2) {
const GrowableObjectArray& array =
GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
@@ -43,7 +43,7 @@
}
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_setIndexed, 3) {
+DEFINE_NATIVE_ENTRY(GrowableList_setIndexed, 3) {
const GrowableObjectArray& array =
GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
@@ -58,21 +58,21 @@
}
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_getLength, 1) {
+DEFINE_NATIVE_ENTRY(GrowableList_getLength, 1) {
const GrowableObjectArray& array =
GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
return Smi::New(array.Length());
}
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_getCapacity, 1) {
+DEFINE_NATIVE_ENTRY(GrowableList_getCapacity, 1) {
const GrowableObjectArray& array =
GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
return Smi::New(array.Capacity());
}
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_setLength, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_setLength, 2) {
const GrowableObjectArray& array =
GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));
@@ -82,7 +82,7 @@
}
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_setData, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_setData, 2) {
const GrowableObjectArray& array =
GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Array, data, arguments->NativeArgAt(1));
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 812a71a..b1f1ccb 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -2,8 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-class _GrowableObjectArray<T> implements List<T> {
- static final int _classId = (new _GrowableObjectArray(0))._cid;
+class _GrowableList<T> implements List<T> {
+ static final int _classId = (new _GrowableList(0))._cid;
void insert(int index, T element) {
if (index < 0 || index > length) {
@@ -117,38 +117,38 @@
if (end == null) end = length;
int length = end - start;
if (start == end) return <T>[];
- List list = new _GrowableObjectArray<T>.withCapacity(length);
+ List list = new _GrowableList<T>.withCapacity(length);
list.length = length;
Arrays.copy(this, start, list, 0, length);
return list;
}
- factory _GrowableObjectArray(int length) {
- var data = new _ObjectArray((length == 0) ? 4 : length);
- var result = new _GrowableObjectArray<T>.withData(data);
+ factory _GrowableList(int length) {
+ var data = new _List((length == 0) ? 4 : length);
+ var result = new _GrowableList<T>.withData(data);
if (length > 0) {
result._setLength(length);
}
return result;
}
- factory _GrowableObjectArray.withCapacity(int capacity) {
- var data = new _ObjectArray((capacity == 0)? 4 : capacity);
- return new _GrowableObjectArray<T>.withData(data);
+ factory _GrowableList.withCapacity(int capacity) {
+ var data = new _List((capacity == 0)? 4 : capacity);
+ return new _GrowableList<T>.withData(data);
}
- factory _GrowableObjectArray.from(Iterable<T> other) {
- List<T> result = new _GrowableObjectArray<T>();
+ factory _GrowableList.from(Iterable<T> other) {
+ List<T> result = new _GrowableList<T>();
result.addAll(other);
return result;
}
- factory _GrowableObjectArray.withData(_ObjectArray data)
- native "GrowableObjectArray_allocate";
+ factory _GrowableList.withData(_List data)
+ native "GrowableList_allocate";
- int get length native "GrowableObjectArray_getLength";
+ int get length native "GrowableList_getLength";
- int get _capacity native "GrowableObjectArray_getCapacity";
+ int get _capacity native "GrowableList_getCapacity";
void set length(int new_length) {
if (new_length > _capacity) {
@@ -161,13 +161,13 @@
_setLength(new_length);
}
- void _setLength(int new_length) native "GrowableObjectArray_setLength";
+ void _setLength(int new_length) native "GrowableList_setLength";
- void _setData(_ObjectArray array) native "GrowableObjectArray_setData";
+ void _setData(_List array) native "GrowableList_setData";
- T operator [](int index) native "GrowableObjectArray_getIndexed";
+ T operator [](int index) native "GrowableList_getIndexed";
- void operator []=(int index, T value) native "GrowableObjectArray_setIndexed";
+ void operator []=(int index, T value) native "GrowableList_setIndexed";
// The length of this growable array. It is always less than or equal to the
// length of the object array, which itself is always greater than 0, so that
@@ -221,7 +221,7 @@
}
void _grow(int new_length) {
- var new_data = new _ObjectArray(new_length);
+ var new_data = new _List(new_length);
for (int i = 0; i < length; i++) {
new_data[i] = this[i];
}
diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart
index 65db0c9..475051f 100644
--- a/runtime/lib/immutable_map.dart
+++ b/runtime/lib/immutable_map.dart
@@ -4,9 +4,9 @@
// Immutable map class for compiler generated map literals.
class ImmutableMap<K, V> implements Map<K, V> {
- final _ImmutableArray _kvPairs;
+ final _ImmutableList _kvPairs;
- const ImmutableMap._create(_ImmutableArray keyValuePairs)
+ const ImmutableMap._create(_ImmutableList keyValuePairs)
: _kvPairs = keyValuePairs;
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index 84dc9d6..dedb88d 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -232,9 +232,7 @@
const Smi& amount,
const bool silent = false) {
if (amount.Value() < 0) {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, amount);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(amount);
}
if (value.IsSmi()) {
const Smi& smi_value = Smi::Cast(value);
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index cec9518..50a3ab0 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -187,31 +187,53 @@
return this.toDouble().toStringAsPrecision(precision);
}
+ static const _digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+
String toRadixString(int radix) {
- final table = const ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
- "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
- "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
- "u", "v", "w", "x", "y", "z"];
if (radix is! int || radix < 2 || radix > 36) {
throw new ArgumentError(radix);
}
+ if (radix & (radix - 1) == 0) {
+ return _toPow2String(this, radix);
+ }
+ if (radix == 10) return this.toString();
final bool isNegative = this < 0;
int value = isNegative ? -this : this;
List temp = new List();
- while (value > 0) {
+ do {
int digit = value % radix;
value ~/= radix;
- temp.add(digit);
+ temp.add(_digits.codeUnitAt(digit));
+ } while (value > 0);
+ if (isNegative) temp.add(0x2d); // '-'.
+
+ _OneByteString string = _OneByteString._allocate(temp.length);
+ for (int i = 0, j = temp.length; j > 0; i++) {
+ string._setAt(i, temp[--j]);
}
- if (temp.isEmpty) {
- return "0";
+ return string;
+ }
+
+ static String _toPow2String(value, radix) {
+ if (value == 0) return "0";
+ assert(radix & (radix - 1) == 0);
+ var negative = value < 0;
+ var bitsPerDigit = radix.bitLength - 1;
+ var length = 0;
+ if (negative) {
+ value = -value;
+ length = 1;
}
- StringBuffer buffer = new StringBuffer();
- if (isNegative) buffer.write("-");
- for (int i = temp.length - 1; i >= 0; i--) {
- buffer.write(table[temp[i]]);
- }
- return buffer.toString();
+ // Integer division, rounding up, to find number of _digits.
+ length += (value.bitLength + bitsPerDigit - 1) ~/ bitsPerDigit;
+ _OneByteString string = _OneByteString._allocate(length);
+ string._setAt(0, 0x2d); // '-'. Is overwritten if not negative.
+ var mask = radix - 1;
+ do {
+ string._setAt(--length, _digits.codeUnitAt(value & mask));
+ value >>= bitsPerDigit;
+ } while (value > 0);
+ return string;
}
_leftShiftWithMask32(count, mask) native "Integer_leftShiftWithMask32";
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 8880d2306..9cfcddf 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -114,13 +114,6 @@
}
-static void ThrowIllegalArgException(const String& message) {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, message);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
-}
-
-
static void ThrowIsolateSpawnException(const String& message) {
const Array& args = Array::Handle(Array::New(1));
args.SetAt(0, message);
@@ -239,7 +232,7 @@
const String& msg = String::Handle(String::New(
"spawnFunction expects to be passed a closure to a top-level static "
"function"));
- ThrowIllegalArgException(msg);
+ Exceptions::ThrowArgumentError(msg);
}
GET_NATIVE_ARGUMENT(Instance, callback, arguments->NativeArgAt(1));
@@ -258,7 +251,7 @@
const String& msg = String::Handle(String::New(
"spawnFunction expects to be passed either a unhandled exception "
"callback to a top-level static function, or null"));
- ThrowIllegalArgException(msg);
+ Exceptions::ThrowArgumentError(msg);
}
#if defined(DEBUG)
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 8e71843..754aa5f 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -742,9 +742,7 @@
const Class& cls = Class::Handle(type.type_class());
ASSERT(!cls.IsNull());
if (cls.IsDynamicClass() || cls.IsVoidClass()) {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, type);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(type);
UNREACHABLE();
}
const Type& stripped_type = Type::Handle(cls.RareType());
@@ -1410,11 +1408,31 @@
UNREACHABLE();
}
+ ASSERT(!type.IsNull());
+ AbstractTypeArguments& type_arguments =
+ AbstractTypeArguments::Handle(type.arguments());
+
Class& redirected_klass = Class::Handle(klass.raw());
Function& redirected_constructor = Function::Handle(lookup_constructor.raw());
if (lookup_constructor.IsRedirectingFactory()) {
ClassFinalizer::ResolveRedirectingFactory(klass, lookup_constructor);
- Type& type = Type::Handle(lookup_constructor.RedirectionType());
+ Type& redirect_type = Type::Handle(lookup_constructor.RedirectionType());
+
+ if (!redirect_type.IsInstantiated()) {
+ // The type arguments of the redirection type are instantiated from the
+ // type arguments of the type reflected by the class mirror.
+ Error& malformed_error = Error::Handle();
+ redirect_type ^= redirect_type.InstantiateFrom(type_arguments,
+ &malformed_error);
+ if (!malformed_error.IsNull()) {
+ ThrowInvokeError(malformed_error);
+ UNREACHABLE();
+ }
+ }
+
+ type = redirect_type.raw();
+ type_arguments = redirect_type.arguments();
+
redirected_constructor = lookup_constructor.RedirectionTarget();
ASSERT(!redirected_constructor.IsNull());
redirected_klass = type.type_class();
@@ -1451,10 +1469,6 @@
UNREACHABLE();
}
- ASSERT(!type.IsNull());
- const AbstractTypeArguments& type_arguments =
- AbstractTypeArguments::Handle(type.arguments());
-
Instance& new_object = Instance::Handle();
if (redirected_constructor.IsConstructor()) {
// Constructors get the uninitialized object and a constructor phase. Note
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 0127c15..bab0aba 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -15,9 +15,7 @@
DEFINE_NATIVE_ENTRY(StringBase_createFromCodePoints, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(Instance, list, arguments->NativeArgAt(0));
if (!list.IsGrowableObjectArray() && !list.IsArray()) {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, list);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(list);
}
Array& a = Array::Handle();
@@ -37,13 +35,11 @@
bool is_one_byte_string = true;
intptr_t utf16_len = array_len;
int32_t* utf32_array = zone->Alloc<int32_t>(array_len);
- Object& index_object = Object::Handle(isolate);
+ Instance& index_object = Instance::Handle(isolate);
for (intptr_t i = 0; i < array_len; i++) {
- index_object = a.At(i);
+ index_object ^= a.At(i);
if (!index_object.IsSmi()) {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, index_object);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(index_object);
}
intptr_t value = Smi::Cast(index_object).Value();
if (Utf::IsOutOfRange(value)) {
@@ -214,20 +210,39 @@
}
-DEFINE_NATIVE_ENTRY(Strings_concatAll, 1) {
- GET_NON_NULL_NATIVE_ARGUMENT(Array, strings, arguments->NativeArgAt(0));
- ASSERT(!strings.IsNull());
+DEFINE_NATIVE_ENTRY(Strings_concatAll, 3) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, argument, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Smi, start, arguments->NativeArgAt(1));
+ GET_NON_NULL_NATIVE_ARGUMENT(Smi, end, arguments->NativeArgAt(2));
+ const intptr_t start_ix = start.Value();
+ const intptr_t end_ix = end.Value();
+ if (start_ix < 0) {
+ Exceptions::ThrowArgumentError(start);
+ }
+ Array& strings = Array::Handle();
+ intptr_t length = -1;
+ if (argument.IsArray()) {
+ strings ^= argument.raw();
+ length = strings.Length();
+ } else if (argument.IsGrowableObjectArray()) {
+ const GrowableObjectArray& g_array = GrowableObjectArray::Cast(argument);
+ strings = g_array.data();
+ length = g_array.Length();
+ } else {
+ Exceptions::ThrowArgumentError(argument);
+ }
+ if (end_ix > length) {
+ Exceptions::ThrowArgumentError(end);
+ }
+#if defined(DEBUG)
// Check that the array contains strings.
Instance& elem = Instance::Handle();
- for (intptr_t i = 0; i < strings.Length(); i++) {
+ for (intptr_t i = start_ix; i < end_ix; i++) {
elem ^= strings.At(i);
- if (!elem.IsString()) {
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, elem);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
- }
+ ASSERT(elem.IsString());
}
- return String::ConcatAll(strings);
+#endif
+ return String::ConcatAllRange(strings, start_ix, end_ix, Heap::kNew);
}
diff --git a/runtime/lib/string_buffer_patch.dart b/runtime/lib/string_buffer_patch.dart
index 9a22647..72ec095 100644
--- a/runtime/lib/string_buffer_patch.dart
+++ b/runtime/lib/string_buffer_patch.dart
@@ -11,7 +11,7 @@
* When strings are written to the string buffer, we add them to a
* list of string parts.
*/
- List _parts = null;
+ List<String> _parts = null;
/**
* Total number of code units in the string parts. Does not include
@@ -28,11 +28,10 @@
*/
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
+ * used when writing short strings or individual char codes to the
* buffer. The buffer is allocated on demand.
*/
Uint16List _buffer = null;
@@ -101,15 +100,9 @@
/** Returns the contents of buffer as a string. */
/* patch */ String toString() {
_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);
+ return (_partsCodeUnits == 0) ?
+ "" :
+ _StringBase._concatAllNative(_parts, 0, _parts.length);
}
/** Ensures that the buffer has enough capacity to add n code units. */
@@ -160,18 +153,13 @@
*/
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);
+ String compacted = _StringBase._concatAllNative(
+ _parts,
+ _partsCompactionIndex, // Start
+ _partsCompactionIndex + _PARTS_TO_COMPACT // End
+ );
_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/string_patch.dart b/runtime/lib/string_patch.dart
index e4f959e..d3285b2 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -30,9 +30,9 @@
if (charCodes != null) {
// TODO(srdjan): Also skip copying of typed arrays.
final ccid = charCodes._cid;
- if ((ccid != _ObjectArray._classId) &&
- (ccid != _GrowableObjectArray._classId) &&
- (ccid != _ImmutableArray._classId)) {
+ if ((ccid != _List._classId) &&
+ (ccid != _GrowableList._classId) &&
+ (ccid != _ImmutableList._classId)) {
charCodes = new List<int>.from(charCodes, growable: false);
}
@@ -395,9 +395,9 @@
* Convert all objects in [values] to strings and concat them
* into a result string.
*/
- static String _interpolate(List values) {
+ static String _interpolate(List<String> values) {
final int numValues = values.length;
- _ObjectArray stringList = new List(numValues);
+ _List stringList = new List<String>(numValues);
bool isOneByteString = true;
int totalLength = 0;
for (int i = 0; i < numValues; i++) {
@@ -406,13 +406,16 @@
totalLength += s.length;
} else {
isOneByteString = false;
+ if (s is! String) {
+ throw new ArgumentError(s);
+ }
}
stringList[i] = s;
}
if (isOneByteString) {
return _OneByteString._concatAll(stringList, totalLength);
}
- return _concatAllNative(stringList);
+ return _concatAllNative(stringList, 0, stringList.length);
}
Iterable<Match> allMatches(String str) {
@@ -497,8 +500,9 @@
String toLowerCase() native "String_toLowerCase";
- // Call this method if not all list elements are OneByteString-s.
- static String _concatAllNative(_ObjectArray<String> strings)
+ // Call this method if not all list elements are known to be OneByteString(s).
+ // 'strings' must be an _List or _GrowableList.
+ static String _concatAllNative(List<String> strings, int start, int end)
native "Strings_concatAll";
}
@@ -531,11 +535,11 @@
}
// All element of 'strings' must be OneByteStrings.
- static _concatAll(_ObjectArray<String> strings, int totalLength) {
+ static _concatAll(_List<String> strings, int totalLength) {
// TODO(srdjan): Improve code below and raise or eliminate the limit.
if (totalLength > 128) {
// Native is quicker.
- return _StringBase._concatAllNative(strings);
+ return _StringBase._concatAllNative(strings, 0, strings.length);
}
var res = _OneByteString._allocate(totalLength);
final stringsLength = strings.length;
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index 6690085..ff4d00b 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -38,9 +38,7 @@
const String& error = String::Handle(String::NewFormatted(
"Length (%" Pd ") of object must be in range [0..%" Pd "]",
len, max));
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, error);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(error);
}
}
@@ -63,9 +61,7 @@
}
const String& error = String::Handle(String::NewFormatted(
"Expected a TypedData object but found %s", instance.ToCString()));
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, error);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(error);
return Integer::null();
}
@@ -107,9 +103,7 @@
if (length.Value() < 0) {
const String& error = String::Handle(String::NewFormatted(
"length (%" Pd ") must be non-negative", length.Value()));
- const Array& args = Array::Handle(Array::New(1));
- args.SetAt(0, error);
- Exceptions::ThrowByType(Exceptions::kArgument, args);
+ Exceptions::ThrowArgumentError(error);
}
if (dst.IsTypedData()) {
if (src.IsTypedData()) {
@@ -193,9 +187,7 @@
} \
const String& error = String::Handle(String::NewFormatted( \
"Expected a TypedData object but found %s", instance.ToCString())); \
- const Array& args = Array::Handle(Array::New(1)); \
- args.SetAt(0, error); \
- Exceptions::ThrowByType(Exceptions::kArgument, args); \
+ Exceptions::ThrowArgumentError(error); \
return object::null(); \
} \
@@ -218,9 +210,7 @@
} else { \
const String& error = String::Handle(String::NewFormatted( \
"Expected a TypedData object but found %s", instance.ToCString())); \
- const Array& args = Array::Handle(Array::New(1)); \
- args.SetAt(0, error); \
- Exceptions::ThrowByType(Exceptions::kArgument, args); \
+ Exceptions::ThrowArgumentError(error); \
} \
return Object::null(); \
}
@@ -242,9 +232,7 @@
} else { \
const String& error = String::Handle(String::NewFormatted( \
"Expected a TypedData object but found %s", instance.ToCString())); \
- const Array& args = Array::Handle(Array::New(1)); \
- args.SetAt(0, error); \
- Exceptions::ThrowByType(Exceptions::kArgument, args); \
+ Exceptions::ThrowArgumentError(error); \
} \
return Integer::NewFromUint64(value); \
} \
@@ -277,9 +265,7 @@
} else { \
const String& error = String::Handle(String::NewFormatted( \
"Expected a TypedData object but found %s", instance.ToCString())); \
- const Array& args = Array::Handle(Array::New(1)); \
- args.SetAt(0, error); \
- Exceptions::ThrowByType(Exceptions::kArgument, args); \
+ Exceptions::ThrowArgumentError(error); \
} \
return Object::null(); \
}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 744aa61..445dd40 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -66,3 +66,6 @@
[ $compiler == dart2analyzer ]
# has compilation error, as designed
dart/isolate_mirror_local_test: fail
+
+[ $compiler == none && $runtime == dartium ]
+dart/isolate_mirror_local_test: Fail # Issue 13719: Please triage this failure.
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index f7b0ea3..cc93724 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -204,6 +204,16 @@
}
+void Assembler::PushImmediate(const Immediate& imm, Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ LoadImmediate(TMP, imm, pp);
+ pushq(TMP);
+ } else {
+ pushq(imm);
+ }
+}
+
+
void Assembler::popq(Register reg) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitRegisterREX(reg, REX_NONE);
@@ -813,7 +823,8 @@
uint32_t d;
} float_not_constant =
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)));
+ LoadImmediate(
+ TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)), PP);
xorps(dst, Address(TMP, 0));
}
@@ -826,7 +837,8 @@
uint32_t d;
} float_negate_constant =
{ 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
- movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)));
+ LoadImmediate(
+ TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)), PP);
xorps(dst, Address(TMP, 0));
}
@@ -839,7 +851,8 @@
uint32_t d;
} float_absolute_constant =
{ 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
- movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)));
+ LoadImmediate(
+ TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)), PP);
andps(dst, Address(TMP, 0));
}
@@ -852,7 +865,8 @@
uint32_t d;
} float_zerow_constant =
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 };
- movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)));
+ LoadImmediate(
+ TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)), PP);
andps(dst, Address(TMP, 0));
}
@@ -1342,6 +1356,28 @@
}
+void Assembler::CompareImmediate(Register reg, const Immediate& imm,
+ Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ LoadImmediate(TMP, imm, pp);
+ cmpq(reg, TMP);
+ } else {
+ cmpq(reg, imm);
+ }
+}
+
+
+void Assembler::CompareImmediate(const Address& address, const Immediate& imm,
+ Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ LoadImmediate(TMP, imm, pp);
+ cmpq(address, TMP);
+ } else {
+ cmpq(address, imm);
+ }
+}
+
+
void Assembler::testl(Register reg1, Register reg2) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Operand operand(reg2);
@@ -1492,6 +1528,17 @@
}
+void Assembler::AndImmediate(Register dst, const Immediate& imm, Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ ASSERT(dst != TMP);
+ LoadImmediate(TMP, imm, pp);
+ andq(dst, TMP);
+ } else {
+ andq(dst, imm);
+ }
+}
+
+
void Assembler::orq(Register dst, Register src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Operand operand(src);
@@ -1521,6 +1568,17 @@
}
+void Assembler::OrImmediate(Register dst, const Immediate& imm, Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ ASSERT(dst != TMP);
+ LoadImmediate(TMP, imm, pp);
+ orq(dst, TMP);
+ } else {
+ orq(dst, imm);
+ }
+}
+
+
void Assembler::xorq(Register dst, Register src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Operand operand(src);
@@ -1558,6 +1616,17 @@
}
+void Assembler::XorImmediate(Register dst, const Immediate& imm, Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ ASSERT(dst != TMP);
+ LoadImmediate(TMP, imm, pp);
+ xorq(dst, TMP);
+ } else {
+ xorq(dst, imm);
+ }
+}
+
+
void Assembler::addl(Register dst, Register src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
Operand operand(src);
@@ -1602,9 +1671,14 @@
void Assembler::addq(const Address& address, const Immediate& imm) {
- // TODO(srdjan): Implement shorter version for imm32.
- movq(TMP, imm);
- addq(address, TMP);
+ if (imm.is_int32()) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOperandREX(0, address, REX_W);
+ EmitComplex(0, Operand(address), imm);
+ } else {
+ movq(TMP, imm);
+ addq(address, TMP);
+ }
}
@@ -1708,6 +1782,17 @@
}
+void Assembler::MulImmediate(Register reg, const Immediate& imm, Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ ASSERT(reg != TMP);
+ LoadImmediate(TMP, imm, pp);
+ imulq(reg, TMP);
+ } else {
+ imulq(reg, imm);
+ }
+}
+
+
void Assembler::imulq(Register dst, const Address& address) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitOperandREX(dst, address, REX_W);
@@ -1746,6 +1831,26 @@
}
+void Assembler::subq(const Address& address, Register reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOperandREX(reg, address, REX_W);
+ EmitUint8(0x29);
+ EmitOperand(reg & 7, address);
+}
+
+
+void Assembler::subq(const Address& address, const Immediate& imm) {
+ if (imm.is_int32()) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOperandREX(0, address, REX_W);
+ EmitComplex(5, Operand(address), imm);
+ } else {
+ movq(TMP, imm);
+ subq(address, TMP);
+ }
+}
+
+
void Assembler::shll(Register reg, const Immediate& imm) {
EmitGenericShift(false, 4, reg, imm);
}
@@ -2138,20 +2243,64 @@
}
-void Assembler::AddImmediate(Register reg, const Immediate& imm) {
+void Assembler::AddImmediate(Register reg, const Immediate& imm, Register pp) {
int64_t value = imm.value();
if (value > 0) {
if (value == 1) {
incq(reg);
} else if (value != 0) {
- addq(reg, imm);
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ ASSERT(reg != TMP);
+ LoadImmediate(TMP, imm, pp);
+ addq(reg, TMP);
+ } else {
+ addq(reg, imm);
+ }
}
} else if (value < 0) {
value = -value;
if (value == 1) {
decq(reg);
} else if (value != 0) {
- subq(reg, Immediate(value));
+ const Immediate& s = Immediate(value);
+ if (CanLoadImmediateFromPool(s, pp)) {
+ ASSERT(reg != TMP);
+ LoadImmediate(TMP, s, pp);
+ subq(reg, TMP);
+ } else {
+ subq(reg, Immediate(value));
+ }
+ }
+ }
+}
+
+
+void Assembler::AddImmediate(const Address& address, const Immediate& imm,
+ Register pp) {
+ int64_t value = imm.value();
+ if (value > 0) {
+ if (value == 1) {
+ incq(address);
+ } else if (value != 0) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ LoadImmediate(TMP, imm, pp);
+ addq(address, TMP);
+ } else {
+ addq(address, imm);
+ }
+ }
+ } else if (value < 0) {
+ value = -value;
+ if (value == 1) {
+ decq(address);
+ } else if (value != 0) {
+ const Immediate& s = Immediate(value);
+ if (CanLoadImmediateFromPool(s, pp)) {
+ LoadImmediate(TMP, s, pp);
+ subq(address, TMP);
+ } else {
+ subq(address, s);
+ }
}
}
}
@@ -2261,38 +2410,86 @@
ASSERT((Isolate::Current() == Dart::vm_isolate()) ||
object.IsSmi() ||
object.InVMHeap());
- movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
+ LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
}
}
-void Assembler::StoreObject(const Address& dst, const Object& object) {
+void Assembler::StoreObject(const Address& dst, const Object& object,
+ Register pp) {
if (CanLoadFromObjectPool(object)) {
- LoadObject(TMP, object, PP);
+ LoadObject(TMP, object, pp);
movq(dst, TMP);
} else {
- movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
+ LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
}
}
-void Assembler::PushObject(const Object& object) {
+void Assembler::PushObject(const Object& object, Register pp) {
if (CanLoadFromObjectPool(object)) {
- LoadObject(TMP, object, PP);
+ LoadObject(TMP, object, pp);
pushq(TMP);
} else {
- pushq(Immediate(reinterpret_cast<int64_t>(object.raw())));
+ PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
}
}
-void Assembler::CompareObject(Register reg, const Object& object) {
+void Assembler::CompareObject(Register reg, const Object& object, Register pp) {
if (CanLoadFromObjectPool(object)) {
ASSERT(reg != TMP);
- LoadObject(TMP, object, PP);
+ LoadObject(TMP, object, pp);
cmpq(reg, TMP);
} else {
- cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
+ CompareImmediate(
+ reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
+ }
+}
+
+
+intptr_t Assembler::FindImmediate(int64_t imm) {
+ ASSERT(Isolate::Current() != Dart::vm_isolate());
+ ASSERT(!object_pool_.IsNull());
+ const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm));
+ return FindObject(smi, kNotPatchable);
+}
+
+
+bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) {
+ return !imm.is_int32() &&
+ (pp != kNoRegister) &&
+ (Isolate::Current() != Dart::vm_isolate());
+}
+
+
+void Assembler::LoadImmediate(Register reg, const Immediate& imm, Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ // It's a 64-bit constant and we're not in the VM isolate, so load from
+ // object pool.
+ int64_t val = imm.value();
+ // Save the bits that must be masked-off for the SmiTag
+ int64_t val_smi_tag = val & kSmiTagMask;
+ val &= ~kSmiTagMask; // Mask off the tag bits.
+ const int32_t offset = Array::element_offset(FindImmediate(val));
+ LoadWordFromPoolOffset(reg, pp, offset - kHeapObjectTag);
+ if (val_smi_tag != 0) {
+ // Add back the tag bits.
+ orq(reg, Immediate(val_smi_tag));
+ }
+ } else {
+ movq(reg, imm);
+ }
+}
+
+
+void Assembler::LoadImmediate(const Address& dst, const Immediate& imm,
+ Register pp) {
+ if (CanLoadImmediateFromPool(imm, pp)) {
+ LoadImmediate(TMP, imm, pp);
+ movq(dst, TMP);
+ } else {
+ movq(dst, imm);
}
}
@@ -2383,7 +2580,8 @@
uint64_t b;
} double_negate_constant =
{0x8000000000000000LL, 0x8000000000000000LL};
- movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)));
+ LoadImmediate(
+ TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP);
xorpd(d, Address(TMP, 0));
}
@@ -2394,7 +2592,8 @@
uint64_t b;
} double_abs_constant =
{0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
- movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)));
+ LoadImmediate(TMP,
+ Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)), PP);
andpd(reg, Address(TMP, 0));
}
@@ -2404,7 +2603,7 @@
if (FLAG_print_stop_message) {
pushq(TMP); // Preserve TMP register.
pushq(RDI); // Preserve RDI register.
- movq(RDI, Immediate(message_address));
+ LoadImmediate(RDI, Immediate(message_address), PP);
call(&StubCode::PrintStopMessageLabel());
popq(RDI); // Restore RDI register.
popq(TMP); // Restore TMP register.
@@ -2477,7 +2676,9 @@
void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
// Reserve space for arguments and align frame before entering
// the C++ world.
- AddImmediate(RSP, Immediate(-frame_space));
+ if (frame_space != 0) {
+ subq(RSP, Immediate(frame_space));
+ }
if (OS::ActivationFrameAlignment() > 1) {
andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
}
@@ -2667,29 +2868,31 @@
void Assembler::TryAllocate(const Class& cls,
Label* failure,
bool near_jump,
- Register instance_reg) {
+ Register instance_reg,
+ Register pp) {
ASSERT(failure != NULL);
if (FLAG_inline_alloc) {
Heap* heap = Isolate::Current()->heap();
const intptr_t instance_size = cls.instance_size();
- movq(TMP, Immediate(heap->TopAddress()));
+ LoadImmediate(TMP, Immediate(heap->TopAddress()), pp);
movq(instance_reg, Address(TMP, 0));
- addq(instance_reg, Immediate(instance_size));
+ AddImmediate(instance_reg, Immediate(instance_size), pp);
// instance_reg: potential next object start.
- movq(TMP, Immediate(heap->EndAddress()));
+ LoadImmediate(TMP, Immediate(heap->EndAddress()), pp);
cmpq(instance_reg, Address(TMP, 0));
j(ABOVE_EQUAL, failure, near_jump);
// Successfully allocated the object, now update top to point to
// next object start and store the class in the class field of object.
- movq(TMP, Immediate(heap->TopAddress()));
+ LoadImmediate(TMP, Immediate(heap->TopAddress()), pp);
movq(Address(TMP, 0), instance_reg);
ASSERT(instance_size >= kHeapObjectTag);
- subq(instance_reg, Immediate(instance_size - kHeapObjectTag));
+ AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size), pp);
uword tags = 0;
tags = RawObject::SizeTag::update(instance_size, tags);
ASSERT(cls.id() != kIllegalCid);
tags = RawObject::ClassIdTag::update(cls.id(), tags);
- movq(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags));
+ LoadImmediate(FieldAddress(instance_reg, Object::tags_offset()),
+ Immediate(tags), pp);
} else {
jmp(failure);
}
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 4aa070c..5f17299 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -356,6 +356,7 @@
void pushq(Register reg);
void pushq(const Address& address);
void pushq(const Immediate& imm);
+ void PushImmediate(const Immediate& imm, Register pp);
void popq(Register reg);
void popq(const Address& address);
@@ -489,6 +490,10 @@
void cmpq(Register reg0, Register reg1);
void cmpq(Register reg, const Address& address);
+ void CompareImmediate(Register reg, const Immediate& imm, Register pp);
+ void CompareImmediate(const Address& address, const Immediate& imm,
+ Register pp);
+
void testl(Register reg1, Register reg2);
void testl(Register reg, const Immediate& imm);
@@ -506,15 +511,18 @@
void andq(Register dst, Register src);
void andq(Register dst, const Address& address);
void andq(Register dst, const Immediate& imm);
+ void AndImmediate(Register dst, const Immediate& imm, Register pp);
void orq(Register dst, Register src);
void orq(Register dst, const Address& address);
void orq(Register dst, const Immediate& imm);
+ void OrImmediate(Register dst, const Immediate& imm, Register pp);
void xorq(Register dst, Register src);
void xorq(Register dst, const Address& address);
void xorq(const Address& dst, Register src);
void xorq(Register dst, const Immediate& imm);
+ void XorImmediate(Register dst, const Immediate& imm, Register pp);
void addl(Register dst, Register src);
void addl(const Address& address, const Immediate& imm);
@@ -541,10 +549,13 @@
void imulq(Register dst, Register src);
void imulq(Register dst, const Address& address);
void imulq(Register dst, const Immediate& imm);
+ void MulImmediate(Register reg, const Immediate& imm, Register pp);
void subq(Register dst, Register src);
void subq(Register reg, const Immediate& imm);
void subq(Register reg, const Address& address);
+ void subq(const Address& address, Register reg);
+ void subq(const Address& address, const Immediate& imm);
void shll(Register reg, const Immediate& imm);
void shll(Register operand, Register shifter);
@@ -657,7 +668,8 @@
void MoveRegister(Register to, Register from);
void PopRegister(Register r);
- void AddImmediate(Register reg, const Immediate& imm);
+ void AddImmediate(Register reg, const Immediate& imm, Register pp);
+ void AddImmediate(const Address& address, const Immediate& imm, Register pp);
void Drop(intptr_t stack_elements);
@@ -666,15 +678,18 @@
kNotPatchable,
};
+ bool CanLoadImmediateFromPool(const Immediate& imm, Register pp);
+ void LoadImmediate(Register reg, const Immediate& imm, Register pp);
+ void LoadImmediate(const Address& dst, const Immediate& imm, Register pp);
void LoadObject(Register dst, const Object& obj, Register pp);
void JmpPatchable(const ExternalLabel* label, Register pp);
void Jmp(const ExternalLabel* label, Register pp);
void J(Condition condition, const ExternalLabel* label, Register pp);
void CallPatchable(const ExternalLabel* label);
void Call(const ExternalLabel* label, Register pp);
- void StoreObject(const Address& dst, const Object& obj);
- void PushObject(const Object& object);
- void CompareObject(Register reg, const Object& object);
+ void StoreObject(const Address& dst, const Object& obj, Register pp);
+ void PushObject(const Object& object, Register pp);
+ void CompareObject(Register reg, const Object& object, Register pp);
void LoadDoubleConstant(XmmRegister dst, double value);
// Destroys value.
@@ -812,10 +827,13 @@
// calls. Jump to 'failure' if the instance cannot be allocated here.
// Allocated instance is returned in 'instance_reg'.
// Only the tags field of the object is initialized.
+ // Loads large immediates from the object pool with pool pointer in PP if it
+ // is not kNoRegister
void TryAllocate(const Class& cls,
Label* failure,
bool near_jump,
- Register instance_reg);
+ Register instance_reg,
+ Register pp);
// Debugging and bringup support.
void Stop(const char* message);
@@ -901,6 +919,7 @@
intptr_t FindObject(const Object& obj, Patchability patchable);
intptr_t FindExternalLabel(const ExternalLabel* label,
Patchability patchable);
+ intptr_t FindImmediate(int64_t imm);
void LoadExternalLabel(Register dst,
const ExternalLabel* label,
Patchability patchable,
diff --git a/runtime/vm/assembler_x64_test.cc b/runtime/vm/assembler_x64_test.cc
index 2d148cd..fd68d8e 100644
--- a/runtime/vm/assembler_x64_test.cc
+++ b/runtime/vm/assembler_x64_test.cc
@@ -1292,14 +1292,14 @@
ExternalLabel call2("LeafReturnArgument",
reinterpret_cast<uword>(LeafReturnArgument));
int space = ComputeStackSpaceReservation(0, 8);
- __ AddImmediate(RSP, Immediate(-space));
+ __ subq(RSP, Immediate(space));
__ call(&call1);
- __ AddImmediate(RSP, Immediate(space));
+ __ addq(RSP, Immediate(space));
space = ComputeStackSpaceReservation(0, 8);
- __ AddImmediate(RSP, Immediate(-space));
+ __ subq(RSP, Immediate(space));
__ movl(RDI, RAX);
__ call(&call2);
- __ AddImmediate(RSP, Immediate(space));
+ __ addq(RSP, Immediate(space));
__ ret();
}
@@ -1314,9 +1314,9 @@
ExternalLabel call1("LeafReturn42", reinterpret_cast<uword>(LeafReturn42));
Label L;
int space = ComputeStackSpaceReservation(0, 8);
- __ AddImmediate(RSP, Immediate(-space));
+ __ subq(RSP, Immediate(space));
__ call(&L);
- __ AddImmediate(RSP, Immediate(space));
+ __ addq(RSP, Immediate(space));
__ ret();
__ Bind(&L);
__ jmp(&call1);
@@ -1625,11 +1625,13 @@
ASSEMBLER_TEST_GENERATE(PackedNegate, assembler) {
+ __ EnterDartFrame(0);
__ movl(RAX, Immediate(bit_cast<int32_t, float>(12.3f)));
__ movd(XMM0, RAX);
__ shufps(XMM0, XMM0, Immediate(0x0));
__ negateps(XMM0);
__ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes.
+ __ LeaveFrameWithPP();
__ ret();
}
@@ -1642,11 +1644,13 @@
ASSEMBLER_TEST_GENERATE(PackedAbsolute, assembler) {
+ __ EnterDartFrame(0);
__ movl(RAX, Immediate(bit_cast<int32_t, float>(-15.3f)));
__ movd(XMM0, RAX);
__ shufps(XMM0, XMM0, Immediate(0x0));
__ absps(XMM0);
__ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes.
+ __ LeaveFrameWithPP();
__ ret();
}
@@ -1659,9 +1663,11 @@
ASSEMBLER_TEST_GENERATE(PackedSetWZero, assembler) {
+ __ EnterDartFrame(0);
__ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(12.3f)));
__ zerowps(XMM0);
__ shufps(XMM0, XMM0, Immediate(0xFF)); // Copy the W lane which is now 0.0.
+ __ LeaveFrameWithPP();
__ ret();
}
@@ -1778,13 +1784,15 @@
uint32_t d;
} constant1 =
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1)));
+ __ EnterDartFrame(0);
+ __ LoadImmediate(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1)), PP);
__ movups(XMM9, Address(RAX, 0));
__ notps(XMM9);
__ movaps(XMM0, XMM9);
__ pushq(RAX);
__ movss(Address(RSP, 0), XMM0);
__ popq(RAX);
+ __ LeaveFrameWithPP();
__ ret();
}
@@ -2183,24 +2191,24 @@
Label fail;
__ EnterDartFrame(0);
__ LoadObject(RAX, obj, PP);
- __ CompareObject(RAX, obj);
+ __ CompareObject(RAX, obj, PP);
__ j(NOT_EQUAL, &fail);
__ LoadObject(RCX, obj, PP);
- __ CompareObject(RCX, obj);
+ __ CompareObject(RCX, obj, PP);
__ j(NOT_EQUAL, &fail);
const Smi& smi = Smi::ZoneHandle(Smi::New(15));
__ LoadObject(RCX, smi, PP);
- __ CompareObject(RCX, smi);
+ __ CompareObject(RCX, smi, PP);
__ j(NOT_EQUAL, &fail);
__ pushq(RAX);
- __ StoreObject(Address(RSP, 0), obj);
+ __ StoreObject(Address(RSP, 0), obj, PP);
__ popq(RCX);
- __ CompareObject(RCX, obj);
+ __ CompareObject(RCX, obj, PP);
__ j(NOT_EQUAL, &fail);
__ pushq(RAX);
- __ StoreObject(Address(RSP, 0), smi);
+ __ StoreObject(Address(RSP, 0), smi, PP);
__ popq(RCX);
- __ CompareObject(RCX, smi);
+ __ CompareObject(RCX, smi, PP);
__ j(NOT_EQUAL, &fail);
__ movl(RAX, Immediate(1)); // OK
__ LeaveFrameWithPP();
@@ -2539,7 +2547,9 @@
ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) {
+ __ EnterDartFrame(0);
__ DoubleAbs(XMM0);
+ __ LeaveFrameWithPP();
__ ret();
}
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 2c911eb..ded8a96 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -376,6 +376,25 @@
}
+bool ConditionalExprNode::IsPotentiallyConst() const {
+ return this->condition()->IsPotentiallyConst() &&
+ this->true_expr()->IsPotentiallyConst() &&
+ this->false_expr()->IsPotentiallyConst();
+}
+
+
+const Instance* ConditionalExprNode::EvalConstExpr() const {
+ const Instance* cond = this->condition()->EvalConstExpr();
+ if ((cond != NULL) &&
+ cond->IsBool() &&
+ (this->true_expr()->EvalConstExpr() != NULL) &&
+ (this->false_expr()->EvalConstExpr() != NULL)) {
+ return cond;
+ }
+ return NULL;
+}
+
+
bool ClosureNode::IsPotentiallyConst() const {
if (function().IsImplicitStaticClosureFunction()) {
return true;
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 2f7af98..c294eeb 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -699,6 +699,9 @@
false_expr_ = false_expr;
}
+ virtual bool IsPotentiallyConst() const;
+ virtual const Instance* EvalConstExpr() const;
+
virtual void VisitChildren(AstNodeVisitor* visitor) const {
condition()->Visit(visitor);
true_expr()->Visit(visitor);
diff --git a/runtime/vm/block_scheduler.cc b/runtime/vm/block_scheduler.cc
index 2594e8a..27d2a9e 100644
--- a/runtime/vm/block_scheduler.cc
+++ b/runtime/vm/block_scheduler.cc
@@ -5,6 +5,7 @@
#include "vm/block_scheduler.h"
#include "vm/allocation.h"
+#include "vm/code_patcher.h"
#include "vm/flow_graph.h"
namespace dart {
@@ -14,25 +15,9 @@
intptr_t deopt_id) {
ASSERT(deopt_id != Isolate::kNoDeoptId);
- // Intrinsified functions do not have edge counts, so give all edges equal
- // weights.
- if (unoptimized_code.pointer_offsets_length() == 0) return 1;
-
uword pc = unoptimized_code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt);
Array& array = Array::Handle();
- // Pointer offsets are sorted in decreasing order. Find the first one
- // after the deopt id's pc.
- // TODO(kmillikin): Use a more reliable way to find the counter.
- for (intptr_t j = unoptimized_code.pointer_offsets_length() - 1;
- j >= 0;
- --j) {
- uword addr =
- unoptimized_code.GetPointerOffsetAt(j) + unoptimized_code.EntryPoint();
- if (addr > pc) {
- array ^= *reinterpret_cast<RawObject**>(addr);
- break;
- }
- }
+ array ^= CodePatcher::GetEdgeCounterAt(pc, unoptimized_code);
ASSERT(!array.IsNull());
return Smi::Value(Smi::RawCast(array.At(0)));
}
@@ -208,7 +193,7 @@
for (intptr_t i = block_count - 1; i >= 0; --i) {
if (chains[i]->first->block == flow_graph()->postorder()[i]) {
for (Link* link = chains[i]->first; link != NULL; link = link->next) {
- flow_graph()->codegen_block_order(true)->Add(link->block);
+ flow_graph()->CodegenBlockOrder(true)->Add(link->block);
}
}
}
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index f4b947c..48844b2 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -82,11 +82,11 @@
V(JSSyntaxRegExp_getIsCaseSensitive, 1) \
V(JSSyntaxRegExp_getGroupCount, 1) \
V(JSSyntaxRegExp_ExecuteMatch, 3) \
- V(ObjectArray_allocate, 2) \
- V(ObjectArray_getIndexed, 2) \
- V(ObjectArray_setIndexed, 3) \
- V(ObjectArray_getLength, 1) \
- V(ObjectArray_copyFromObjectArray, 5) \
+ V(List_allocate, 2) \
+ V(List_getIndexed, 2) \
+ V(List_setIndexed, 3) \
+ V(List_getLength, 1) \
+ V(List_copyFromObjectArray, 5) \
V(StringBase_createFromCodePoints, 1) \
V(StringBase_substringUnchecked, 3) \
V(StringBuffer_createStringFromUint16Array, 3) \
@@ -101,7 +101,7 @@
V(String_concat, 2) \
V(String_toLowerCase, 1) \
V(String_toUpperCase, 1) \
- V(Strings_concatAll, 1) \
+ V(Strings_concatAll, 3) \
V(Math_sqrt, 1) \
V(Math_sin, 1) \
V(Math_cos, 1) \
@@ -292,13 +292,13 @@
V(ParameterMirror_type, 2) \
V(TypedefMirror_referent, 1) \
V(VariableMirror_type, 1) \
- V(GrowableObjectArray_allocate, 2) \
- V(GrowableObjectArray_getIndexed, 2) \
- V(GrowableObjectArray_setIndexed, 3) \
- V(GrowableObjectArray_getLength, 1) \
- V(GrowableObjectArray_getCapacity, 1) \
- V(GrowableObjectArray_setLength, 2) \
- V(GrowableObjectArray_setData, 2) \
+ V(GrowableList_allocate, 2) \
+ V(GrowableList_getIndexed, 2) \
+ V(GrowableList_setIndexed, 3) \
+ V(GrowableList_getLength, 1) \
+ V(GrowableList_getCapacity, 1) \
+ V(GrowableList_setLength, 2) \
+ V(GrowableList_setData, 2) \
V(WeakProperty_new, 2) \
V(WeakProperty_getKey, 1) \
V(WeakProperty_getValue, 1) \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index dff2717..b5c6103 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -337,7 +337,7 @@
// Replace the type with a malformed type and compile a throw when called.
type = NewFinalizedMalformedType(
Error::Handle(), // No previous error.
- cls,
+ Script::Handle(cls.script()),
factory.token_pos(),
"factory may not redirect to 'dynamic'");
factory.SetRedirectionType(type);
@@ -364,7 +364,7 @@
// Replace the type with a malformed type and compile a throw when called.
type = NewFinalizedMalformedType(
Error::Handle(), // No previous error.
- cls,
+ Script::Handle(target_class.script()),
factory.token_pos(),
"class '%s' has no constructor or factory named '%s'",
target_class_name.ToCString(),
@@ -378,8 +378,9 @@
// Verify that the target is compatible with the redirecting factory.
Error& error = Error::Handle();
if (!target.HasCompatibleParametersWith(factory, &error)) {
+ const Script& script = Script::Handle(target_class.script());
type = NewFinalizedMalformedType(
- error, target_class, target.token_pos(),
+ error, script, target.token_pos(),
"constructor '%s' has incompatible parameters with "
"redirecting factory '%s'",
String::Handle(target.name()).ToCString(),
@@ -428,7 +429,8 @@
if (malformed_error.IsNull()) {
target_type ^= FinalizeType(cls, target_type, kCanonicalize);
} else {
- FinalizeMalformedType(malformed_error, cls, target_type,
+ const Script& script = Script::Handle(target_class.script());
+ FinalizeMalformedType(malformed_error, script, target_type,
"cannot resolve redirecting factory");
target_target = Function::null();
}
@@ -471,7 +473,7 @@
// The type class could not be resolved. The type is malformed.
FinalizeMalformedType(
Error::Handle(), // No previous error.
- cls,
+ Script::Handle(cls.script()),
parameterized_type,
"cannot resolve class '%s' from '%s'",
String::Handle(unresolved_class.Name()).ToCString(),
@@ -908,7 +910,7 @@
parameterized_type.UserVisibleName());
const Type& malformed_bound = Type::Handle(
NewFinalizedMalformedType(bound_error,
- cls,
+ Script::Handle(cls.script()),
parameterized_type.token_pos(),
"type '%s' has an out of bound type argument",
parameterized_type_name.ToCString()));
@@ -2460,12 +2462,11 @@
// Either report an error or mark the type as malformed.
void ClassFinalizer::ReportMalformedType(const Error& prev_error,
- const Class& cls,
+ const Script& script,
const Type& type,
const char* format,
va_list args) {
LanguageError& error = LanguageError::Handle();
- const Script& script = Script::Handle(cls.script());
if (prev_error.IsNull()) {
error ^= Parser::FormatError(
script, type.token_pos(), "Error", format, args);
@@ -2493,7 +2494,7 @@
RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error,
- const Class& cls,
+ const Script& script,
intptr_t type_pos,
const char* format, ...) {
va_list args;
@@ -2504,7 +2505,7 @@
type_pos));
const Type& type = Type::Handle(
Type::New(unresolved_class, TypeArguments::Handle(), type_pos));
- ReportMalformedType(prev_error, cls, type, format, args);
+ ReportMalformedType(prev_error, script, type, format, args);
va_end(args);
ASSERT(type.IsMalformed());
ASSERT(type.IsFinalized());
@@ -2513,12 +2514,12 @@
void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
- const Class& cls,
+ const Script& script,
const Type& type,
const char* format, ...) {
va_list args;
va_start(args, format);
- ReportMalformedType(prev_error, cls, type, format, args);
+ ReportMalformedType(prev_error, script, type, format, args);
va_end(args);
}
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index e2689d0..cc94684 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -52,7 +52,7 @@
// If not null, prepend prev_error to the error message built from the format
// string and its arguments.
static RawType* NewFinalizedMalformedType(const Error& prev_error,
- const Class& cls,
+ const Script& script,
intptr_t type_pos,
const char* format, ...)
PRINTF_ATTRIBUTE(4, 5);
@@ -62,7 +62,7 @@
// If not null, prepend prev_error to the error message built from the format
// string and its arguments.
static void FinalizeMalformedType(const Error& prev_error,
- const Class& cls,
+ const Script& script,
const Type& type,
const char* format, ...)
PRINTF_ATTRIBUTE(4, 5);
@@ -145,7 +145,7 @@
static void CollectInterfaces(const Class& cls,
const GrowableObjectArray& interfaces);
static void ReportMalformedType(const Error& prev_error,
- const Class& cls,
+ const Script& script,
const Type& type,
const char* format,
va_list args);
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 9bfd2a5..162e702 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1494,8 +1494,9 @@
}
-// Copy saved registers into the isolate buffer.
-static void CopySavedRegisters(uword saved_registers_address) {
+static void CopySavedRegisters(uword saved_registers_address,
+ fpu_register_t** fpu_registers,
+ intptr_t** cpu_registers) {
ASSERT(sizeof(fpu_register_t) == kFpuRegisterSize);
fpu_register_t* fpu_registers_copy =
new fpu_register_t[kNumberOfFpuRegisters];
@@ -1505,7 +1506,7 @@
*reinterpret_cast<fpu_register_t*>(saved_registers_address);
saved_registers_address += kFpuRegisterSize;
}
- Isolate::Current()->set_deopt_fpu_registers_copy(fpu_registers_copy);
+ *fpu_registers = fpu_registers_copy;
ASSERT(sizeof(intptr_t) == kWordSize);
intptr_t* cpu_registers_copy = new intptr_t[kNumberOfCpuRegisters];
@@ -1515,14 +1516,16 @@
*reinterpret_cast<intptr_t*>(saved_registers_address);
saved_registers_address += kWordSize;
}
- Isolate::Current()->set_deopt_cpu_registers_copy(cpu_registers_copy);
+ *cpu_registers = cpu_registers_copy;
}
-// Copy optimized frame into the isolate buffer.
-// The first incoming argument is stored at the last entry in the
-// copied frame buffer.
-static void CopyFrame(const Code& optimized_code, const StackFrame& frame) {
+// Copy optimized frame. The first incoming argument is stored at the
+// last entry in the copied frame buffer.
+static void CopyFrame(const Code& optimized_code,
+ const StackFrame& frame,
+ intptr_t** frame_start,
+ intptr_t* frame_size) {
const Function& function = Function::Handle(optimized_code.function());
// Do not copy incoming arguments if there are optional arguments (they
// are copied into local space at method entry).
@@ -1545,7 +1548,8 @@
for (intptr_t i = 0; i < frame_copy_size; i++) {
frame_copy[i] = *(start + i);
}
- Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size);
+ *frame_start = frame_copy;
+ *frame_size = frame_copy_size;
}
@@ -1562,7 +1566,6 @@
+ (kNumberOfCpuRegisters * kWordSize)
+ (kNumberOfFpuRegisters * kFpuRegisterSize)
- ((kFirstLocalSlotFromFp + 1) * kWordSize);
- CopySavedRegisters(saved_registers_address);
// Get optimized code and frame that need to be deoptimized.
DartFrameIterator iterator(last_fp);
@@ -1576,9 +1579,28 @@
optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
ASSERT(!deopt_info.IsNull());
- CopyFrame(optimized_code, *caller_frame);
+ // Create the DeoptContext for this deoptimization. Store in isolate.
+ const Function& function = Function::Handle(optimized_code.function());
+ const intptr_t num_args =
+ function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
+ DeoptContext* deopt_context = new DeoptContext(
+ Array::Handle(optimized_code.object_table()),
+ num_args,
+ static_cast<DeoptReasonId>(deopt_reason));
+ isolate->set_deopt_context(deopt_context);
+
+ // Copy the saved registers and the source frame.
+ fpu_register_t* fpu_registers;
+ intptr_t* cpu_registers;
+ intptr_t* frame_start;
+ intptr_t frame_size;
+ CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers);
+ CopyFrame(optimized_code, *caller_frame, &frame_start, &frame_size);
+ deopt_context->SetSourceArgs(frame_start, frame_size,
+ fpu_registers, cpu_registers,
+ true); // true = source frame is a copy.
+
if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
- Function& function = Function::Handle(optimized_code.function());
OS::PrintErr(
"Deoptimizing (reason %" Pd " '%s') at pc %#" Px " '%s' (count %d)\n",
deopt_reason,
@@ -1591,9 +1613,6 @@
// Compute the stack size of the unoptimized frame. For functions with
// optional arguments the deoptimization info does not describe the
// incoming arguments.
- const Function& function = Function::Handle(optimized_code.function());
- const intptr_t num_args =
- function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
const intptr_t unoptimized_stack_size =
+ deopt_info.FrameSize()
- kDartFrameFixedSize
@@ -1605,10 +1624,10 @@
END_LEAF_RUNTIME_ENTRY
-static void DeoptimizeWithDeoptInfo(const Code& code,
+static void DeoptimizeWithDeoptInfo(DeoptContext* deopt_context,
+ const Code& code,
const DeoptInfo& deopt_info,
- const StackFrame& caller_frame,
- intptr_t deopt_reason) {
+ const StackFrame& caller_frame) {
const intptr_t len = deopt_info.TranslationLength();
GrowableArray<DeoptInstr*> deopt_instructions(len);
const Array& deopt_table = Array::Handle(code.deopt_info_array());
@@ -1626,11 +1645,9 @@
+ 1 // For fp.
+ kParamEndSlotFromFp
+ num_args;
- DeoptimizationContext deopt_context(start,
- to_frame_size,
- Array::Handle(code.object_table()),
- num_args,
- static_cast<DeoptReasonId>(deopt_reason));
+
+ deopt_context->SetDestArgs(start, to_frame_size);
+
const intptr_t frame_size = deopt_info.FrameSize();
// All kMaterializeObject instructions are emitted before the instructions
@@ -1642,15 +1659,15 @@
// frame. They will be used during materialization and removed from the stack
// right before control switches to the unoptimized code.
const intptr_t num_materializations = len - frame_size;
- Isolate::Current()->PrepareForDeferredMaterialization(num_materializations);
+ deopt_context->PrepareForDeferredMaterialization(num_materializations);
for (intptr_t from_index = 0, to_index = kDartFrameFixedSize;
from_index < num_materializations;
from_index++) {
const intptr_t field_count =
DeoptInstr::GetFieldCount(deopt_instructions[from_index]);
- intptr_t* args = deopt_context.GetToFrameAddressAt(to_index);
+ intptr_t* args = deopt_context->GetDestFrameAddressAt(to_index);
DeferredObject* obj = new DeferredObject(field_count, args);
- Isolate::Current()->SetDeferredObjectAt(from_index, obj);
+ deopt_context->SetDeferredObjectAt(from_index, obj);
to_index += obj->ArgumentCount();
}
@@ -1658,8 +1675,8 @@
for (intptr_t to_index = frame_size - 1, from_index = len - 1;
to_index >= 0;
to_index--, from_index--) {
- intptr_t* to_addr = deopt_context.GetToFrameAddressAt(to_index);
- deopt_instructions[from_index]->Execute(&deopt_context, to_addr);
+ intptr_t* to_addr = deopt_context->GetDestFrameAddressAt(to_index);
+ deopt_instructions[from_index]->Execute(deopt_context, to_addr);
}
if (FLAG_trace_deoptimization_verbose) {
@@ -1691,26 +1708,16 @@
ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized());
ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized());
- intptr_t* frame_copy = isolate->deopt_frame_copy();
- intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy();
- fpu_register_t* fpu_registers_copy = isolate->deopt_fpu_registers_copy();
-
intptr_t deopt_reason = kDeoptUnknown;
const DeoptInfo& deopt_info = DeoptInfo::Handle(
optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
ASSERT(!deopt_info.IsNull());
- DeoptimizeWithDeoptInfo(optimized_code,
+ DeoptContext* deopt_context = isolate->deopt_context();
+ DeoptimizeWithDeoptInfo(deopt_context,
+ optimized_code,
deopt_info,
- *caller_frame,
- deopt_reason);
-
- isolate->SetDeoptFrameCopy(NULL, 0);
- isolate->set_deopt_cpu_registers_copy(NULL);
- isolate->set_deopt_fpu_registers_copy(NULL);
- delete[] frame_copy;
- delete[] cpu_registers_copy;
- delete[] fpu_registers_copy;
+ *caller_frame);
}
END_LEAF_RUNTIME_ENTRY
@@ -1721,25 +1728,15 @@
// under return address to keep them discoverable by GC that can occur during
// materialization phase.
DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) {
- // First materialize all unboxed "primitive" values (doubles, mints, simd)
- // then materialize objects. The order is important: objects might be
- // referencing boxes allocated on the first step. At the same time
- // objects can't be referencing other deferred objects because storing
- // an object into a field is always conservatively treated as escaping by
- // allocation sinking and load forwarding.
- isolate->MaterializeDeferredBoxes();
- isolate->MaterializeDeferredObjects();
+ DeoptContext* deopt_context = isolate->deopt_context();
- // Compute total number of artificial arguments used during deoptimization.
- intptr_t deopt_arguments = 0;
- for (intptr_t i = 0; i < isolate->DeferredObjectsCount(); i++) {
- deopt_arguments += isolate->GetDeferredObject(i)->ArgumentCount();
- }
- Isolate::Current()->DeleteDeferredObjects();
+ intptr_t deopt_arg_count = deopt_context->MaterializeDeferredObjects();
+ isolate->set_deopt_context(NULL);
+ delete deopt_context;
// Return value tells deoptimization stub to remove the given number of bytes
// from the stack.
- arguments.SetReturn(Smi::Handle(Smi::New(deopt_arguments * kWordSize)));
+ arguments.SetReturn(Smi::Handle(Smi::New(deopt_arg_count * kWordSize)));
// Since this is the only step where GC can occur during deoptimization,
// use it to report the source line where deoptimization occured.
@@ -1756,7 +1753,7 @@
String& line_string = String::Handle(script.GetLine(line));
OS::PrintErr(" Function: %s\n", top_function.ToFullyQualifiedCString());
OS::PrintErr(" Line %" Pd ": '%s'\n", line, line_string.ToCString());
- OS::PrintErr(" Deopt args: %" Pd "\n", deopt_arguments);
+ OS::PrintErr(" Deopt args: %" Pd "\n", deopt_arg_count);
}
}
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index fea3ba4..9294e0e 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -19,6 +19,7 @@
class RawArray;
class RawFunction;
class RawICData;
+class RawObject;
class String;
class CodePatcher : public AllStatic {
@@ -70,6 +71,8 @@
static intptr_t InstanceCallSizeInBytes();
static void InsertCallAt(uword start, uword target);
+
+ static RawObject* GetEdgeCounterAt(uword pc, const Code& code);
};
} // namespace dart
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 105d3a1..759bf54 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -84,6 +84,47 @@
return ic_data.GetTargetAt(0);
}
+
+// This class pattern matches on a load from the object pool. Loading on
+// ARM is complicated because it can take four possible different forms. We
+// match backwards from the end of the sequence so we can reuse the code for
+// matching object pool loads at calls.
+class EdgeCounter : public ValueObject {
+ public:
+ EdgeCounter(uword pc, const Code& code)
+ : end_(pc - kAdjust), object_pool_(Array::Handle(code.ObjectPool())) {
+ // An IsValid predicate is complicated and duplicates the code in the
+ // decoding function. Instead we rely on decoding the pattern which
+ // will assert partial validity.
+ }
+
+ RawObject* edge_counter() const {
+ Register ignored;
+ intptr_t index;
+ InstructionPattern::DecodeLoadWordFromPool(end_, &ignored, &index);
+ ASSERT(ignored == R0);
+ return object_pool_.At(index);
+ }
+
+ private:
+ // The object pool load is followed by the fixed-size edge counter
+ // incrementing code:
+ // ldr ip, [r0, #+11]
+ // adds ip, ip, #2
+ // str ip, [r0, #+11]
+ static const intptr_t kAdjust = 3 * Instr::kInstrSize;
+
+ uword end_;
+ const Array& object_pool_;
+};
+
+
+RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
+ ASSERT(code.ContainsInstructionAt(pc));
+ EdgeCounter counter(pc, code);
+ return counter.edge_counter();
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index 9cccd56..8143d69 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -149,7 +149,7 @@
};
-// The expected pattern of a dart closure call:
+// The expected pattern of a Dart closure call:
// mov EDX, arguments_descriptor_array
// call target_address
// <- return address
@@ -259,6 +259,39 @@
return InstanceCall::kNumInstructions * InstanceCall::kInstructionSize;
}
+
+// The expected code pattern of an edge counter in unoptimized code:
+// b8 imm32 mov EAX, immediate
+class EdgeCounter : public ValueObject {
+ public:
+ EdgeCounter(uword pc, const Code& ignored) : end_(pc - kAdjust) {
+ ASSERT(IsValid(end_));
+ }
+
+ static bool IsValid(uword end) {
+ return (*reinterpret_cast<uint8_t*>(end - 5) == 0xb8);
+ }
+
+ RawObject* edge_counter() const {
+ return *reinterpret_cast<RawObject**>(end_ - 4);
+ }
+
+ private:
+ // The edge counter load is followed by the fixed-size edge counter
+ // incrementing code:
+ // 83 40 0b 02 add [eax+0xb],0x2
+ static const intptr_t kAdjust = 4;
+
+ uword end_;
+};
+
+
+RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
+ ASSERT(code.ContainsInstructionAt(pc));
+ EdgeCounter counter(pc, code);
+ return counter.edge_counter();
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/code_patcher_mips.cc b/runtime/vm/code_patcher_mips.cc
index f25b460..7a84596 100644
--- a/runtime/vm/code_patcher_mips.cc
+++ b/runtime/vm/code_patcher_mips.cc
@@ -84,6 +84,47 @@
return ic_data.GetTargetAt(0);
}
+
+// This class pattern matches on a load from the object pool. Loading on
+// MIPS is complicated because it can take four possible different forms.
+// We match backwards from the end of the sequence so we can reuse the code
+// for matching object pool loads at calls.
+class EdgeCounter : public ValueObject {
+ public:
+ EdgeCounter(uword pc, const Code& code)
+ : end_(pc - kAdjust), object_pool_(Array::Handle(code.ObjectPool())) {
+ // An IsValid predicate is complicated and duplicates the code in the
+ // decoding function. Instead we rely on decoding the pattern which
+ // will assert partial validity.
+ }
+
+ RawObject* edge_counter() const {
+ Register ignored;
+ intptr_t index;
+ InstructionPattern::DecodeLoadWordFromPool(end_, &ignored, &index);
+ ASSERT(ignored == T0);
+ return object_pool_.At(index);
+ }
+
+ private:
+ // The object pool load is followed by the fixed-size edge counter
+ // incrementing code:
+ // lw r9, 11(r8)
+ // addiu r9, r9, 2
+ // sw r9, 11(r8)
+ static const intptr_t kAdjust = 3 * Instr::kInstrSize;
+
+ uword end_;
+ const Array& object_pool_;
+};
+
+
+RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
+ ASSERT(code.ContainsInstructionAt(pc));
+ EdgeCounter counter(pc, code);
+ return counter.edge_counter();
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 5782527..0de7bd6 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -142,7 +142,7 @@
};
-// The expected code pattern of a dart closure call:
+// The expected code pattern of a Dart closure call:
// 00: 49 ba imm64 mov R10, immediate 2 ; 10 bytes
// 10: 4d 8b 9f imm32 mov R11, [PP + off]
// 17: 41 ff d3 call R11 ; 3 bytes
@@ -248,6 +248,42 @@
return ic_data.GetTargetAt(0);
}
+
+// The expected code pattern of an edge counter in unoptimized code:
+// 49 8b 87 imm32 mov RAX, [PP + offset]
+class EdgeCounter : public ValueObject {
+ public:
+ EdgeCounter(uword pc, const Code& code)
+ : end_(pc - kAdjust), object_pool_(Array::Handle(code.ObjectPool())) {
+ ASSERT(IsValid(end_));
+ }
+
+ static bool IsValid(uword end) {
+ uint8_t* bytes = reinterpret_cast<uint8_t*>(end - 7);
+ return (bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87);
+ }
+
+ RawObject* edge_counter() const {
+ return object_pool_.At(InstructionPattern::IndexFromPPLoad(end_ - 4));
+ }
+
+ private:
+ // The edge counter load is followed by the fixed-size edge counter
+ // incrementing code:
+ // 48 83 40 17 02 addq [rax+0x17],0x2
+ static const intptr_t kAdjust = 5;
+
+ uword end_;
+ const Array& object_pool_;
+};
+
+
+RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
+ ASSERT(code.ContainsInstructionAt(pc));
+ EdgeCounter counter(pc, code);
+ return counter.edge_counter();
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_X64
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index d9f1a53..5a9ff9d 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -307,7 +307,9 @@
}
BlockScheduler block_scheduler(flow_graph);
- if (optimized && FLAG_reorder_basic_blocks) {
+ const bool reorder_blocks =
+ FlowGraph::ShouldReorderBlocks(function, optimized);
+ if (reorder_blocks) {
block_scheduler.AssignEdgeWeights();
}
@@ -508,7 +510,7 @@
// Perform register allocation on the SSA graph.
FlowGraphAllocator allocator(*flow_graph);
allocator.AllocateRegisters();
- if (FLAG_reorder_basic_blocks) block_scheduler.ReorderBlocks();
+ if (reorder_blocks) block_scheduler.ReorderBlocks();
if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
@@ -739,8 +741,8 @@
TIMERSCOPE(time_compilation);
Timer per_compile_timer(FLAG_trace_compiler, "Compilation time");
per_compile_timer.Start();
- ParsedFunction* parsed_function = new ParsedFunction(
- Function::ZoneHandle(function.raw()));
+ ParsedFunction* parsed_function =
+ new ParsedFunction(Function::ZoneHandle(function.raw()));
if (FLAG_trace_compiler) {
OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
(osr_id == Isolate::kNoDeoptId ? "" : "osr "),
diff --git a/runtime/vm/coverage.cc b/runtime/vm/coverage.cc
index 5d284d2..56733f4 100644
--- a/runtime/vm/coverage.cc
+++ b/runtime/vm/coverage.cc
@@ -6,6 +6,7 @@
#include "include/dart_api.h"
+#include "vm/compiler.h"
#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/object.h"
@@ -16,64 +17,105 @@
DEFINE_FLAG(charp, coverage_dir, NULL,
"Enable writing coverage data into specified directory.");
+
+void CodeCoverage::CompileAndAdd(const Function& function,
+ const JSONArray& hits_arr) {
+ if (!function.HasCode()) {
+ if (Compiler::CompileFunction(function) != Error::null()) {
+ return;
+ }
+ }
+ ASSERT(function.HasCode());
+
+ Isolate* isolate = Isolate::Current();
+ // Print the hit counts for all IC datas.
+ const Script& script = Script::Handle(function.script());
+ const Code& code = Code::Handle(function.unoptimized_code());
+ const Array& ic_array = Array::Handle(code.ExtractTypeFeedbackArray());
+ const PcDescriptors& descriptors = PcDescriptors::Handle(
+ code.pc_descriptors());
+ ICData& ic_data = ICData::Handle();
+
+ for (int j = 0; j < descriptors.Length(); j++) {
+ HANDLESCOPE(isolate);
+ PcDescriptors::Kind kind = descriptors.DescriptorKind(j);
+ // Only IC based calls have counting.
+ if ((kind == PcDescriptors::kIcCall) ||
+ (kind == PcDescriptors::kUnoptStaticCall)) {
+ intptr_t deopt_id = descriptors.DeoptId(j);
+ ic_data ^= ic_array.At(deopt_id);
+ if (!ic_data.IsNull()) {
+ intptr_t token_pos = descriptors.TokenPos(j);
+ intptr_t line = -1;
+ script.GetTokenLocation(token_pos, &line, NULL);
+ hits_arr.AddValue(line);
+ hits_arr.AddValue(ic_data.AggregateCount());
+ }
+ }
+ }
+}
+
+
void CodeCoverage::PrintClass(const Class& cls, const JSONArray& jsarr) {
- const Array& functions = Array::Handle(cls.functions());
+ Isolate* isolate = Isolate::Current();
+ Array& functions = Array::Handle(cls.functions());
ASSERT(!functions.IsNull());
Function& function = Function::Handle();
- Code& code = Code::Handle();
Script& script = Script::Handle();
+ String& saved_url = String::Handle();
String& url = String::Handle();
- String& name = String::Handle();
- PcDescriptors& descriptors = PcDescriptors::Handle();
- Array& ic_array = Array::Handle();
- ICData& ic_data = ICData::Handle();
- for (int i = 0; i < functions.Length(); i++) {
- function ^= functions.At(i);
+ int i = 0;
+ while (i < functions.Length()) {
+ HANDLESCOPE(isolate);
+ 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());
+ saved_url = script.url();
+ jsobj.AddProperty("source", saved_url.ToCString());
+ JSONArray hits_arr(&jsobj, "hits");
- JSONArray jsarr(&jsobj, "hits");
-
- if (function.HasCode()) {
- // Print the hit counts for all IC datas.
- code = function.unoptimized_code();
- ic_array = code.ExtractTypeFeedbackArray();
- descriptors = code.pc_descriptors();
-
- for (int j = 0; j < descriptors.Length(); j++) {
- PcDescriptors::Kind kind = descriptors.DescriptorKind(j);
- // Only IC based calls have counting.
- if ((kind == PcDescriptors::kIcCall) ||
- (kind == PcDescriptors::kUnoptStaticCall)) {
- intptr_t deopt_id = descriptors.DeoptId(j);
- ic_data ^= ic_array.At(deopt_id);
- if (!ic_data.IsNull()) {
- intptr_t token_pos = descriptors.TokenPos(j);
- intptr_t line = -1;
- intptr_t col = -1;
- script.GetTokenLocation(token_pos, &line, &col);
- JSONObject ic_info(&jsarr);
- ic_info.AddProperty("line", line);
- ic_info.AddProperty("col", col);
- ic_info.AddProperty("count", ic_data.AggregateCount());
- }
- }
+ // We stay within this loop while we are seeing functions from the same
+ // source URI.
+ while (i < functions.Length()) {
+ function ^= functions.At(i);
+ script = function.script();
+ url = script.url();
+ if (!url.Equals(saved_url)) {
+ break;
}
- } 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));
+ CompileAndAdd(function, hits_arr);
+ i++;
+ }
+ }
+
+ GrowableObjectArray& closures =
+ GrowableObjectArray::Handle(cls.closures());
+ if (!closures.IsNull()) {
+ i = 0;
+ // We need to keep rechecking the length of the closures array, as handling
+ // a closure potentially adds new entries to the end.
+ while (i < closures.Length()) {
+ HANDLESCOPE(isolate);
+ function ^= closures.At(i);
+ JSONObject jsobj(&jsarr);
+ script = function.script();
+ saved_url = script.url();
+ jsobj.AddProperty("source", saved_url.ToCString());
+ JSONArray hits_arr(&jsobj, "hits");
+
+ // We stay within this loop while we are seeing functions from the same
+ // source URI.
+ while (i < closures.Length()) {
+ function ^= closures.At(i);
+ script = function.script();
+ url = script.url();
+ if (!url.Equals(saved_url)) {
+ break;
+ }
+ CompileAndAdd(function, hits_arr);
+ i++;
+ }
}
}
}
@@ -103,7 +145,7 @@
ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
while (it.HasNext()) {
cls = it.GetNextClass();
- if (cls.is_finalized()) {
+ if (cls.EnsureIsFinalized(isolate) == Error::null()) {
// Only classes that have been finalized do have a meaningful list of
// functions.
PrintClass(cls, jsarr);
diff --git a/runtime/vm/coverage.h b/runtime/vm/coverage.h
index ef7ee82..0c17bda 100644
--- a/runtime/vm/coverage.h
+++ b/runtime/vm/coverage.h
@@ -14,6 +14,7 @@
// Forward declarations.
class Class;
+class Function;
class Isolate;
class JSONArray;
@@ -23,6 +24,8 @@
private:
static void PrintClass(const Class& cls, const JSONArray& arr);
+ static void CompileAndAdd(const Function& function,
+ const JSONArray& hits_arr);
};
} // namespace dart
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 7a6bc66..680476e 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -2834,12 +2834,14 @@
}
// Get the class to instantiate.
- const Type& type_obj = Api::UnwrapTypeHandle(isolate, type);
- if (type_obj.IsNull()) {
+ Object& unchecked_type = Object::Handle(Api::UnwrapHandle(type));
+ if (unchecked_type.IsNull() || !unchecked_type.IsType()) {
RETURN_TYPE_ERROR(isolate, type, Type);
}
+ Type& type_obj = Type::Handle();
+ type_obj ^= unchecked_type.raw();
Class& cls = Class::Handle(isolate, type_obj.type_class());
- const AbstractTypeArguments& type_arguments =
+ AbstractTypeArguments& type_arguments =
AbstractTypeArguments::Handle(isolate, type_obj.arguments());
const String& base_constructor_name = String::Handle(isolate, cls.Name());
@@ -2877,13 +2879,28 @@
Instance& new_object = Instance::Handle(isolate);
if (constructor.IsRedirectingFactory()) {
ClassFinalizer::ResolveRedirectingFactory(cls, constructor);
- const Type& type = Type::Handle(constructor.RedirectionType());
+ Type& redirect_type = Type::Handle(constructor.RedirectionType());
constructor = constructor.RedirectionTarget();
if (constructor.IsNull()) {
- ASSERT(type.IsMalformed());
- return Api::NewHandle(isolate, type.malformed_error());
+ ASSERT(redirect_type.IsMalformed());
+ return Api::NewHandle(isolate, redirect_type.malformed_error());
}
- cls = type.type_class();
+
+ if (!redirect_type.IsInstantiated()) {
+ // The type arguments of the redirection type are instantiated from the
+ // type arguments of the type argument.
+ Error& malformed_error = Error::Handle();
+ redirect_type ^= redirect_type.InstantiateFrom(type_arguments,
+ &malformed_error);
+ if (!malformed_error.IsNull()) {
+ return Api::NewHandle(isolate, malformed_error.raw());
+ }
+ }
+
+ type_obj = redirect_type.raw();
+ type_arguments = redirect_type.arguments();
+
+ cls = type_obj.type_class();
}
if (constructor.IsConstructor()) {
// Create the new object.
@@ -3613,7 +3630,7 @@
CHECK_ISOLATE(isolate);
ReusableObjectHandleScope reused_obj_handle(isolate);
Object& obj = reused_obj_handle.Handle();
- obj = arguments->NativeArgAt(0);
+ obj = arguments->NativeArg0();
intptr_t cid = obj.GetClassId();
if (cid <= kNumPredefinedCids) {
if (cid == kNullCid) {
@@ -4208,9 +4225,9 @@
}
-DART_EXPORT Dart_Handle Dart_LoadPatch(Dart_Handle library,
- Dart_Handle url,
- Dart_Handle patch_source) {
+DART_EXPORT Dart_Handle Dart_LibraryLoadPatch(Dart_Handle library,
+ Dart_Handle url,
+ Dart_Handle patch_source) {
TIMERSCOPE(time_script_loading);
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index e5fce0d..aa860ea 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -2711,19 +2711,6 @@
}
-#define CHECK_CLASS(handle, name) \
- { \
- Dart_Handle tmp = (handle); \
- EXPECT_VALID(tmp); \
- EXPECT(Dart_IsClass(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)); \
- EXPECT_STREQ((name), intf_name_cstr); \
- }
-
-
TEST_CASE(TypeGetNonParamtericTypes) {
const char* kScriptChars =
"class MyClass0 {\n"
@@ -5258,7 +5245,7 @@
url = NewString("patch_url");
source = NewString(kPatchChars);
- result = Dart_LoadPatch(lib, url, source);
+ result = Dart_LibraryLoadPatch(lib, url, source);
EXPECT_VALID(result);
result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 66930ed..c085f5c 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1595,6 +1595,9 @@
if (!IsDebuggable(func)) {
return;
}
+ if (frame->TokenPos() == Scanner::kDummyTokenIndex) {
+ return;
+ }
if (FLAG_verbose_debug) {
OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 130decd..3ffff4a 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -507,6 +507,7 @@
CURRENT_FUNC);
}
UNWRAP_AND_CHECK_PARAM(String, expr, expr_in);
+ // Type extends Instance, must check first.
if (target.IsType()) {
const Class& cls = Class::Handle(isolate, Type::Cast(target).type_class());
return Api::NewHandle(isolate, cls.Evaluate(expr));
@@ -514,6 +515,8 @@
return Api::NewHandle(isolate, Instance::Cast(target).Evaluate(expr));
} else if (target.IsLibrary()) {
return Api::NewHandle(isolate, Library::Cast(target).Evaluate(expr));
+ } else if (target.IsClass()) {
+ return Api::NewHandle(isolate, Class::Cast(target).Evaluate(expr));
}
return Api::NewError("%s: unsupported target type", CURRENT_FUNC);
}
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index d73e812..5bd2084 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -1583,14 +1583,16 @@
EXPECT(Dart_IsNumber(len));
EXPECT_EQ(3, ToInt64(len));
- Dart_Handle point_class = Dart_GetClass(script_lib, NewString("Point"));
- EXPECT_VALID(point_class);
- Dart_Handle elem = Dart_EvaluateExpr(point_class, NewString("m['\"']"));
+ Dart_Handle point_type =
+ Dart_GetType(script_lib, NewString("Point"), 0, NULL);
+ EXPECT_VALID(point_type);
+ EXPECT(Dart_IsType(point_type));
+ Dart_Handle elem = Dart_EvaluateExpr(point_type, NewString("m['\"']"));
EXPECT_VALID(elem);
EXPECT(Dart_IsString(elem));
EXPECT_STREQ("quote", ToCString(elem));
- elem = Dart_EvaluateExpr(point_class, NewString("m[\"\\t\"]"));
+ elem = Dart_EvaluateExpr(point_type, NewString("m[\"\\t\"]"));
EXPECT_VALID(elem);
EXPECT(Dart_IsString(elem));
EXPECT_STREQ("tab", ToCString(elem));
@@ -1617,6 +1619,10 @@
EXPECT_VALID(len);
EXPECT(Dart_IsNumber(len));
EXPECT_EQ(6, ToInt64(len));
+
+ Dart_Handle error =
+ Dart_EvaluateExpr(script_lib, NewString("new NonexistingType()"));
+ EXPECT(Dart_IsError(error));
}
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
new file mode 100644
index 0000000..76f5be7
--- /dev/null
+++ b/runtime/vm/deferred_objects.cc
@@ -0,0 +1,127 @@
+// 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 "vm/deferred_objects.h"
+
+#include "vm/deopt_instructions.h"
+#include "vm/flags.h"
+#include "vm/object.h"
+
+namespace dart {
+
+DECLARE_FLAG(bool, trace_deoptimization_verbose);
+
+
+void DeferredDouble::Materialize() {
+ RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot());
+ *double_slot = Double::New(value());
+
+ if (FLAG_trace_deoptimization_verbose) {
+ OS::PrintErr("materializing double at %" Px ": %g\n",
+ reinterpret_cast<uword>(slot()), value());
+ }
+}
+
+
+void DeferredMint::Materialize() {
+ RawMint** mint_slot = reinterpret_cast<RawMint**>(slot());
+ ASSERT(!Smi::IsValid64(value()));
+ Mint& mint = Mint::Handle();
+ mint ^= Integer::New(value());
+ *mint_slot = mint.raw();
+
+ if (FLAG_trace_deoptimization_verbose) {
+ OS::PrintErr("materializing mint at %" Px ": %" Pd64 "\n",
+ reinterpret_cast<uword>(slot()), value());
+ }
+}
+
+
+void DeferredFloat32x4::Materialize() {
+ RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(slot());
+ RawFloat32x4* raw_float32x4 = Float32x4::New(value());
+ *float32x4_slot = raw_float32x4;
+
+ if (FLAG_trace_deoptimization_verbose) {
+ float x = raw_float32x4->x();
+ float y = raw_float32x4->y();
+ float z = raw_float32x4->z();
+ float w = raw_float32x4->w();
+ OS::PrintErr("materializing Float32x4 at %" Px ": %g,%g,%g,%g\n",
+ reinterpret_cast<uword>(slot()), x, y, z, w);
+ }
+}
+
+
+void DeferredUint32x4::Materialize() {
+ RawUint32x4** uint32x4_slot = reinterpret_cast<RawUint32x4**>(slot());
+ RawUint32x4* raw_uint32x4 = Uint32x4::New(value());
+ *uint32x4_slot = raw_uint32x4;
+
+ if (FLAG_trace_deoptimization_verbose) {
+ uint32_t x = raw_uint32x4->x();
+ uint32_t y = raw_uint32x4->y();
+ uint32_t z = raw_uint32x4->z();
+ uint32_t w = raw_uint32x4->w();
+ OS::PrintErr("materializing Uint32x4 at %" Px ": %x,%x,%x,%x\n",
+ reinterpret_cast<uword>(slot()), x, y, z, w);
+ }
+}
+
+
+void DeferredObjectRef::Materialize() {
+ // TODO(turnidge): Consider passing the deopt_context to materialize
+ // instead of accessing it through the current isolate. It would
+ // make it easier to test deferred object materialization in a unit
+ // test eventually.
+ DeferredObject* obj =
+ Isolate::Current()->deopt_context()->GetDeferredObject(index());
+ *slot() = obj->object();
+ if (FLAG_trace_deoptimization_verbose) {
+ OS::PrintErr("writing instance ref at %" Px ": %s\n",
+ reinterpret_cast<uword>(slot()),
+ Instance::Handle(obj->object()).ToCString());
+ }
+}
+
+
+RawInstance* DeferredObject::object() {
+ if (object_ == NULL) {
+ Materialize();
+ }
+ return object_->raw();
+}
+
+
+void DeferredObject::Materialize() {
+ Class& cls = Class::Handle();
+ cls ^= GetClass();
+
+ if (FLAG_trace_deoptimization_verbose) {
+ OS::PrintErr("materializing instance of %s (%" Px ", %" Pd " fields)\n",
+ cls.ToCString(),
+ reinterpret_cast<uword>(args_),
+ field_count_);
+ }
+
+ const Instance& obj = Instance::ZoneHandle(Instance::New(cls));
+
+ Field& field = Field::Handle();
+ Object& value = Object::Handle();
+ for (intptr_t i = 0; i < field_count_; i++) {
+ field ^= GetField(i);
+ value = GetValue(i);
+ obj.SetField(field, value);
+
+ if (FLAG_trace_deoptimization_verbose) {
+ OS::PrintErr(" %s <- %s\n",
+ String::Handle(field.name()).ToCString(),
+ value.ToCString());
+ }
+ }
+
+ object_ = &obj;
+}
+
+} // namespace dart
diff --git a/runtime/vm/deferred_objects.h b/runtime/vm/deferred_objects.h
new file mode 100644
index 0000000..7e2c3c9
--- /dev/null
+++ b/runtime/vm/deferred_objects.h
@@ -0,0 +1,187 @@
+// 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 VM_DEFERRED_OBJECTS_H_
+#define VM_DEFERRED_OBJECTS_H_
+
+#include "platform/globals.h"
+
+namespace dart {
+
+// Forward declarations.
+class Instance;
+class RawInstance;
+class RawObject;
+
+// Used by the deoptimization infrastructure to defer allocation of
+// unboxed objects until frame is fully rewritten and GC is safe.
+// Describes a stack slot that should be populated with a reference to
+// the materialized object.
+class DeferredSlot {
+ public:
+ DeferredSlot(RawInstance** slot, DeferredSlot* next)
+ : slot_(slot), next_(next) { }
+ virtual ~DeferredSlot() { }
+
+ RawInstance** slot() const { return slot_; }
+ DeferredSlot* next() const { return next_; }
+
+ virtual void Materialize() = 0;
+
+ private:
+ RawInstance** const slot_;
+ DeferredSlot* const next_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
+};
+
+
+class DeferredDouble : public DeferredSlot {
+ public:
+ DeferredDouble(double value, RawInstance** slot, DeferredSlot* next)
+ : DeferredSlot(slot, next), value_(value) { }
+
+ virtual void Materialize();
+
+ double value() const { return value_; }
+
+ private:
+ const double value_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeferredDouble);
+};
+
+
+class DeferredMint : public DeferredSlot {
+ public:
+ DeferredMint(int64_t value, RawInstance** slot, DeferredSlot* next)
+ : DeferredSlot(slot, next), value_(value) { }
+
+ virtual void Materialize();
+
+ int64_t value() const { return value_; }
+
+ private:
+ const int64_t value_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeferredMint);
+};
+
+
+class DeferredFloat32x4 : public DeferredSlot {
+ public:
+ DeferredFloat32x4(simd128_value_t value, RawInstance** slot,
+ DeferredSlot* next)
+ : DeferredSlot(slot, next), value_(value) { }
+
+ virtual void Materialize();
+
+ simd128_value_t value() const { return value_; }
+
+ private:
+ const simd128_value_t value_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeferredFloat32x4);
+};
+
+
+class DeferredUint32x4 : public DeferredSlot {
+ public:
+ DeferredUint32x4(simd128_value_t value, RawInstance** slot,
+ DeferredSlot* next)
+ : DeferredSlot(slot, next), value_(value) { }
+
+ virtual void Materialize();
+
+ simd128_value_t value() const { return value_; }
+
+ private:
+ const simd128_value_t value_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeferredUint32x4);
+};
+
+
+// Describes a slot that contains a reference to an object that had its
+// allocation removed by AllocationSinking pass.
+// Object itself is described and materialized by DeferredObject.
+class DeferredObjectRef : public DeferredSlot {
+ public:
+ DeferredObjectRef(intptr_t index, RawInstance** slot, DeferredSlot* next)
+ : DeferredSlot(slot, next), index_(index) { }
+
+ virtual void Materialize();
+
+ intptr_t index() const { return index_; }
+
+ private:
+ const intptr_t index_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeferredObjectRef);
+};
+
+
+// Describes an object which allocation was removed by AllocationSinking pass.
+// Arguments for materialization are stored as a part of expression stack
+// for the bottommost deoptimized frame so that GC could discover them.
+// They will be removed from the stack at the very end of deoptimization.
+class DeferredObject {
+ public:
+ DeferredObject(intptr_t field_count, intptr_t* args)
+ : field_count_(field_count),
+ args_(reinterpret_cast<RawObject**>(args)),
+ object_(NULL) { }
+
+ intptr_t ArgumentCount() const {
+ return kFieldsStartIndex + kFieldEntrySize * field_count_;
+ }
+
+ RawInstance* object();
+
+ private:
+ enum {
+ kClassIndex = 0,
+ kFieldsStartIndex = kClassIndex + 1
+ };
+
+ enum {
+ kFieldIndex = 0,
+ kValueIndex,
+ kFieldEntrySize,
+ };
+
+ // Materializes the object. Returns amount of values that were consumed
+ // and should be removed from the expression stack at the very end of
+ // deoptimization.
+ void Materialize();
+
+ RawObject* GetClass() const {
+ return args_[kClassIndex];
+ }
+
+ RawObject* GetField(intptr_t index) const {
+ return args_[kFieldsStartIndex + kFieldEntrySize * index + kFieldIndex];
+ }
+
+ RawObject* GetValue(intptr_t index) const {
+ return args_[kFieldsStartIndex + kFieldEntrySize * index + kValueIndex];
+ }
+
+ // Amount of fields that have to be initialized.
+ const intptr_t field_count_;
+
+ // Pointer to the first materialization argument on the stack.
+ // The first argument is Class of the instance to materialize followed by
+ // Field, value pairs.
+ RawObject** args_;
+
+ // Object materialized from this description.
+ const Instance* object_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeferredObject);
+};
+
+} // namespace dart
+
+#endif // VM_DEFERRED_OBJECTS_H_
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index adca206..f7a7c53 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -18,71 +18,158 @@
DECLARE_FLAG(bool, trace_deoptimization);
DECLARE_FLAG(bool, trace_deoptimization_verbose);
-DeoptimizationContext::DeoptimizationContext(intptr_t* to_frame_start,
- intptr_t to_frame_size,
- const Array& object_table,
- intptr_t num_args,
- DeoptReasonId deopt_reason)
- : object_table_(object_table),
- to_frame_(to_frame_start),
- to_frame_size_(to_frame_size),
- from_frame_(NULL),
- from_frame_size_(0),
- registers_copy_(NULL),
- fpu_registers_copy_(NULL),
+DeoptContext::DeoptContext(const Array& object_table,
+ intptr_t num_args,
+ DeoptReasonId deopt_reason)
+ : object_table_(object_table.raw()),
+ dest_frame_(NULL),
+ dest_frame_size_(0),
+ source_frame_is_copy_(false),
+ source_frame_(NULL),
+ source_frame_size_(0),
+ cpu_registers_(NULL),
+ fpu_registers_(NULL),
num_args_(num_args),
deopt_reason_(deopt_reason),
- isolate_(Isolate::Current()) {
- from_frame_ = isolate_->deopt_frame_copy();
- from_frame_size_ = isolate_->deopt_frame_copy_size();
- registers_copy_ = isolate_->deopt_cpu_registers_copy();
- fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy();
- // The deoptimized frame is filled starting just below the sp of its caller
- // down to kDartFrameFixedSize words below its own sp.
- // The chain of frame pointers is recreated from the fp of the caller.
- caller_fp_ = GetFromFp();
+ isolate_(Isolate::Current()),
+ deferred_boxes_(NULL),
+ deferred_object_refs_(NULL),
+ deferred_objects_count_(0),
+ deferred_objects_(NULL) {
}
-intptr_t DeoptimizationContext::GetFromFp() const {
- return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp];
+DeoptContext::~DeoptContext() {
+ // Delete memory for source frame and registers.
+ if (source_frame_is_copy_) {
+ delete[] source_frame_;
+ }
+ source_frame_ = NULL;
+ delete[] fpu_registers_;
+ delete[] cpu_registers_;
+ fpu_registers_ = NULL;
+ cpu_registers_ = NULL;
+
+ // Delete all deferred objects.
+ for (intptr_t i = 0; i < deferred_objects_count_; i++) {
+ delete deferred_objects_[i];
+ }
+ delete[] deferred_objects_;
+ deferred_objects_ = NULL;
+ deferred_objects_count_ = 0;
}
-intptr_t DeoptimizationContext::GetFromPp() const {
- return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp +
- StackFrame::SavedCallerPpSlotFromFp()];
+void DeoptContext::SetSourceArgs(intptr_t* frame_start,
+ intptr_t frame_size,
+ fpu_register_t* fpu_registers,
+ intptr_t* cpu_registers,
+ bool source_frame_is_copy) {
+ ASSERT(frame_start != NULL);
+ ASSERT(frame_size >= 0);
+ ASSERT(source_frame_ == NULL);
+ ASSERT(cpu_registers_ == NULL && fpu_registers_ == NULL);
+ source_frame_ = frame_start;
+ source_frame_size_ = frame_size;
+ caller_fp_ = GetSourceFp();
+ cpu_registers_ = cpu_registers;
+ fpu_registers_ = fpu_registers;
+ source_frame_is_copy_ = source_frame_is_copy;
}
-intptr_t DeoptimizationContext::GetFromPc() const {
- return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp];
+void DeoptContext::SetDestArgs(intptr_t* frame_start,
+ intptr_t frame_size) {
+ ASSERT(frame_start != NULL);
+ ASSERT(frame_size >= 0);
+ ASSERT(dest_frame_ == NULL);
+ dest_frame_ = frame_start;
+ dest_frame_size_ = frame_size;
}
-intptr_t DeoptimizationContext::GetCallerFp() const {
+void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+ visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_table_));
+}
+
+
+intptr_t DeoptContext::GetSourceFp() const {
+ return source_frame_[source_frame_size_ - 1 - num_args_ -
+ kParamEndSlotFromFp];
+}
+
+
+intptr_t DeoptContext::GetSourcePp() const {
+ return source_frame_[source_frame_size_ - 1 - num_args_ -
+ kParamEndSlotFromFp +
+ StackFrame::SavedCallerPpSlotFromFp()];
+}
+
+
+intptr_t DeoptContext::GetSourcePc() const {
+ return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp];
+}
+
+
+intptr_t DeoptContext::GetCallerFp() const {
return caller_fp_;
}
-void DeoptimizationContext::SetCallerFp(intptr_t caller_fp) {
+void DeoptContext::SetCallerFp(intptr_t caller_fp) {
caller_fp_ = caller_fp;
}
+static void FillDeferredSlots(DeferredSlot** slot_list) {
+ DeferredSlot* slot = *slot_list;
+ *slot_list = NULL;
+
+ while (slot != NULL) {
+ DeferredSlot* current = slot;
+ slot = slot->next();
+
+ current->Materialize();
+
+ delete current;
+ }
+}
+
+
+// Materializes all deferred objects. Returns the total number of
+// artificial arguments used during deoptimization.
+intptr_t DeoptContext::MaterializeDeferredObjects() {
+ // First materialize all unboxed "primitive" values (doubles, mints, simd)
+ // then materialize objects. The order is important: objects might be
+ // referencing boxes allocated on the first step. At the same time
+ // objects can't be referencing other deferred objects because storing
+ // an object into a field is always conservatively treated as escaping by
+ // allocation sinking and load forwarding.
+ FillDeferredSlots(&deferred_boxes_);
+ FillDeferredSlots(&deferred_object_refs_);
+
+ // Compute total number of artificial arguments used during deoptimization.
+ intptr_t deopt_arguments = 0;
+ for (intptr_t i = 0; i < DeferredObjectsCount(); i++) {
+ deopt_arguments += GetDeferredObject(i)->ArgumentCount();
+ }
+ return deopt_arguments;
+}
+
+
// Deoptimization instruction moving value from optimized frame at
-// 'from_index' to specified slots in the unoptimized frame.
-// 'from_index' represents the slot index of the frame (0 being first argument)
-// and accounts for saved return address, frame pointer, pool pointer and pc
-// marker.
+// 'source_index' to specified slots in the unoptimized frame.
+// 'source_index' represents the slot index of the frame (0 being
+// first argument) and accounts for saved return address, frame
+// pointer, pool pointer and pc marker.
class DeoptStackSlotInstr : public DeoptInstr {
public:
- explicit DeoptStackSlotInstr(intptr_t from_index)
- : stack_slot_index_(from_index) {
+ explicit DeoptStackSlotInstr(intptr_t source_index)
+ : stack_slot_index_(source_index) {
ASSERT(stack_slot_index_ >= 0);
}
- virtual intptr_t from_index() const { return stack_slot_index_; }
+ virtual intptr_t source_index() const { return stack_slot_index_; }
virtual DeoptInstr::Kind kind() const { return kStackSlot; }
virtual const char* ToCString() const {
@@ -90,11 +177,12 @@
"s%" Pd "", stack_slot_index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- intptr_t from_index =
- deopt_context->from_frame_size() - stack_slot_index_ - 1;
- intptr_t* from_addr = deopt_context->GetFromFrameAddressAt(from_index);
- *to_addr = *from_addr;
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ intptr_t source_index =
+ deopt_context->source_frame_size() - stack_slot_index_ - 1;
+ intptr_t* source_addr =
+ deopt_context->GetSourceFrameAddressAt(source_index);
+ *dest_addr = *source_addr;
}
private:
@@ -106,12 +194,12 @@
class DeoptDoubleStackSlotInstr : public DeoptInstr {
public:
- explicit DeoptDoubleStackSlotInstr(intptr_t from_index)
- : stack_slot_index_(from_index) {
+ explicit DeoptDoubleStackSlotInstr(intptr_t source_index)
+ : stack_slot_index_(source_index) {
ASSERT(stack_slot_index_ >= 0);
}
- virtual intptr_t from_index() const { return stack_slot_index_; }
+ virtual intptr_t source_index() const { return stack_slot_index_; }
virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; }
virtual const char* ToCString() const {
@@ -119,14 +207,14 @@
"ds%" Pd "", stack_slot_index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- intptr_t from_index =
- deopt_context->from_frame_size() - stack_slot_index_ - 1;
- double* from_addr = reinterpret_cast<double*>(
- deopt_context->GetFromFrameAddressAt(from_index));
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
- Isolate::Current()->DeferDoubleMaterialization(
- *from_addr, reinterpret_cast<RawDouble**>(to_addr));
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ intptr_t source_index =
+ deopt_context->source_frame_size() - stack_slot_index_ - 1;
+ double* source_addr = reinterpret_cast<double*>(
+ deopt_context->GetSourceFrameAddressAt(source_index));
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ deopt_context->DeferDoubleMaterialization(
+ *source_addr, reinterpret_cast<RawDouble**>(dest_addr));
}
private:
@@ -138,12 +226,12 @@
class DeoptInt64StackSlotInstr : public DeoptInstr {
public:
- explicit DeoptInt64StackSlotInstr(intptr_t from_index)
- : stack_slot_index_(from_index) {
+ explicit DeoptInt64StackSlotInstr(intptr_t source_index)
+ : stack_slot_index_(source_index) {
ASSERT(stack_slot_index_ >= 0);
}
- virtual intptr_t from_index() const { return stack_slot_index_; }
+ virtual intptr_t source_index() const { return stack_slot_index_; }
virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; }
virtual const char* ToCString() const {
@@ -151,18 +239,18 @@
"ms%" Pd "", stack_slot_index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- intptr_t from_index =
- deopt_context->from_frame_size() - stack_slot_index_ - 1;
- int64_t* from_addr = reinterpret_cast<int64_t*>(
- deopt_context->GetFromFrameAddressAt(from_index));
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
- if (Smi::IsValid64(*from_addr)) {
- *to_addr = reinterpret_cast<intptr_t>(
- Smi::New(static_cast<intptr_t>(*from_addr)));
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ intptr_t source_index =
+ deopt_context->source_frame_size() - stack_slot_index_ - 1;
+ int64_t* source_addr = reinterpret_cast<int64_t*>(
+ deopt_context->GetSourceFrameAddressAt(source_index));
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ if (Smi::IsValid64(*source_addr)) {
+ *dest_addr = reinterpret_cast<intptr_t>(
+ Smi::New(static_cast<intptr_t>(*source_addr)));
} else {
- Isolate::Current()->DeferMintMaterialization(
- *from_addr, reinterpret_cast<RawMint**>(to_addr));
+ deopt_context->DeferMintMaterialization(
+ *source_addr, reinterpret_cast<RawMint**>(dest_addr));
}
}
@@ -175,12 +263,12 @@
class DeoptFloat32x4StackSlotInstr : public DeoptInstr {
public:
- explicit DeoptFloat32x4StackSlotInstr(intptr_t from_index)
- : stack_slot_index_(from_index) {
+ explicit DeoptFloat32x4StackSlotInstr(intptr_t source_index)
+ : stack_slot_index_(source_index) {
ASSERT(stack_slot_index_ >= 0);
}
- virtual intptr_t from_index() const { return stack_slot_index_; }
+ virtual intptr_t source_index() const { return stack_slot_index_; }
virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; }
virtual const char* ToCString() const {
@@ -188,14 +276,14 @@
"f32x4s%" Pd "", stack_slot_index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- intptr_t from_index =
- deopt_context->from_frame_size() - stack_slot_index_ - 1;
- simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>(
- deopt_context->GetFromFrameAddressAt(from_index));
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
- Isolate::Current()->DeferFloat32x4Materialization(
- *from_addr, reinterpret_cast<RawFloat32x4**>(to_addr));
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ intptr_t source_index =
+ deopt_context->source_frame_size() - stack_slot_index_ - 1;
+ simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
+ deopt_context->GetSourceFrameAddressAt(source_index));
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ deopt_context->DeferFloat32x4Materialization(
+ *source_addr, reinterpret_cast<RawFloat32x4**>(dest_addr));
}
private:
@@ -207,12 +295,12 @@
class DeoptUint32x4StackSlotInstr : public DeoptInstr {
public:
- explicit DeoptUint32x4StackSlotInstr(intptr_t from_index)
- : stack_slot_index_(from_index) {
+ explicit DeoptUint32x4StackSlotInstr(intptr_t source_index)
+ : stack_slot_index_(source_index) {
ASSERT(stack_slot_index_ >= 0);
}
- virtual intptr_t from_index() const { return stack_slot_index_; }
+ virtual intptr_t source_index() const { return stack_slot_index_; }
virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; }
virtual const char* ToCString() const {
@@ -220,14 +308,14 @@
"ui32x4s%" Pd "", stack_slot_index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- intptr_t from_index =
- deopt_context->from_frame_size() - stack_slot_index_ - 1;
- simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>(
- deopt_context->GetFromFrameAddressAt(from_index));
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
- Isolate::Current()->DeferUint32x4Materialization(
- *from_addr, reinterpret_cast<RawUint32x4**>(to_addr));
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ intptr_t source_index =
+ deopt_context->source_frame_size() - stack_slot_index_ - 1;
+ simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
+ deopt_context->GetSourceFrameAddressAt(source_index));
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ deopt_context->DeferUint32x4Materialization(
+ *source_addr, reinterpret_cast<RawUint32x4**>(dest_addr));
}
private:
@@ -247,12 +335,12 @@
ASSERT(deopt_id >= 0);
}
- explicit DeoptRetAddressInstr(intptr_t from_index)
- : object_table_index_(ObjectTableIndex::decode(from_index)),
- deopt_id_(DeoptId::decode(from_index)) {
+ explicit DeoptRetAddressInstr(intptr_t source_index)
+ : object_table_index_(ObjectTableIndex::decode(source_index)),
+ deopt_id_(DeoptId::decode(source_index)) {
}
- virtual intptr_t from_index() const {
+ virtual intptr_t source_index() const {
return ObjectTableIndex::encode(object_table_index_) |
DeoptId::encode(deopt_id_);
}
@@ -264,7 +352,7 @@
"ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
Function& function = Function::Handle(deopt_context->isolate());
function ^= deopt_context->ObjectAt(object_table_index_);
const Code& code =
@@ -273,7 +361,7 @@
uword continue_at_pc = code.GetPcForDeoptId(deopt_id_,
PcDescriptors::kDeopt);
ASSERT(continue_at_pc != 0);
- *to_addr = continue_at_pc;
+ *dest_addr = continue_at_pc;
uword pc = code.GetPcForDeoptId(deopt_id_, PcDescriptors::kIcCall);
if (pc != 0) {
@@ -310,7 +398,7 @@
ASSERT(object_table_index >= 0);
}
- virtual intptr_t from_index() const { return object_table_index_; }
+ virtual intptr_t source_index() const { return object_table_index_; }
virtual DeoptInstr::Kind kind() const { return kConstant; }
virtual const char* ToCString() const {
@@ -318,10 +406,10 @@
"const oti:%" Pd "", object_table_index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
const Object& obj = Object::Handle(
deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_));
- *reinterpret_cast<RawObject**>(to_addr) = obj.raw();
+ *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
}
private:
@@ -337,15 +425,15 @@
explicit DeoptRegisterInstr(intptr_t reg_as_int)
: reg_(static_cast<Register>(reg_as_int)) {}
- virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+ virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
virtual DeoptInstr::Kind kind() const { return kRegister; }
virtual const char* ToCString() const {
return Assembler::RegisterName(reg_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- *to_addr = deopt_context->RegisterValue(reg_);
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ *dest_addr = deopt_context->RegisterValue(reg_);
}
private:
@@ -361,18 +449,18 @@
explicit DeoptFpuRegisterInstr(intptr_t reg_as_int)
: reg_(static_cast<FpuRegister>(reg_as_int)) {}
- virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+ virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
virtual DeoptInstr::Kind kind() const { return kFpuRegister; }
virtual const char* ToCString() const {
return Assembler::FpuRegisterName(reg_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
double value = deopt_context->FpuRegisterValue(reg_);
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
- Isolate::Current()->DeferDoubleMaterialization(
- value, reinterpret_cast<RawDouble**>(to_addr));
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ deopt_context->DeferDoubleMaterialization(
+ value, reinterpret_cast<RawDouble**>(dest_addr));
}
private:
@@ -387,7 +475,7 @@
explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int)
: reg_(static_cast<FpuRegister>(reg_as_int)) {}
- virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+ virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; }
virtual const char* ToCString() const {
@@ -395,15 +483,15 @@
"%s(m)", Assembler::FpuRegisterName(reg_));
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_);
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
if (Smi::IsValid64(value)) {
- *to_addr = reinterpret_cast<intptr_t>(
+ *dest_addr = reinterpret_cast<intptr_t>(
Smi::New(static_cast<intptr_t>(value)));
} else {
- Isolate::Current()->DeferMintMaterialization(
- value, reinterpret_cast<RawMint**>(to_addr));
+ deopt_context->DeferMintMaterialization(
+ value, reinterpret_cast<RawMint**>(dest_addr));
}
}
@@ -420,7 +508,7 @@
explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int)
: reg_(static_cast<FpuRegister>(reg_as_int)) {}
- virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+ virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; }
virtual const char* ToCString() const {
@@ -428,11 +516,11 @@
"%s(f32x4)", Assembler::FpuRegisterName(reg_));
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
- Isolate::Current()->DeferFloat32x4Materialization(
- value, reinterpret_cast<RawFloat32x4**>(to_addr));
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ deopt_context->DeferFloat32x4Materialization(
+ value, reinterpret_cast<RawFloat32x4**>(dest_addr));
}
private:
@@ -448,7 +536,7 @@
explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int)
: reg_(static_cast<FpuRegister>(reg_as_int)) {}
- virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+ virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; }
virtual const char* ToCString() const {
@@ -456,11 +544,11 @@
"%s(f32x4)", Assembler::FpuRegisterName(reg_));
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
- Isolate::Current()->DeferUint32x4Materialization(
- value, reinterpret_cast<RawUint32x4**>(to_addr));
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ deopt_context->DeferUint32x4Materialization(
+ value, reinterpret_cast<RawUint32x4**>(dest_addr));
}
private:
@@ -479,7 +567,7 @@
ASSERT(object_table_index >= 0);
}
- virtual intptr_t from_index() const { return object_table_index_; }
+ virtual intptr_t source_index() const { return object_table_index_; }
virtual DeoptInstr::Kind kind() const { return kPcMarker; }
virtual const char* ToCString() const {
@@ -487,12 +575,12 @@
"pcmark oti:%" Pd "", object_table_index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
Function& function = Function::Handle(deopt_context->isolate());
function ^= deopt_context->ObjectAt(object_table_index_);
if (function.IsNull()) {
// Callee's PC marker is not used (pc of Deoptimize stub). Set to 0.
- *to_addr = 0;
+ *dest_addr = 0;
return;
}
const Code& code =
@@ -500,7 +588,7 @@
ASSERT(!code.IsNull());
const intptr_t pc_marker =
code.EntryPoint() + Assembler::kEntryPointToPcMarkerOffset;
- *to_addr = pc_marker;
+ *dest_addr = pc_marker;
// Increment the deoptimization counter. This effectively increments each
// function occurring in the optimized frame.
function.set_deoptimization_counter(function.deoptimization_counter() + 1);
@@ -531,7 +619,7 @@
ASSERT(object_table_index >= 0);
}
- virtual intptr_t from_index() const { return object_table_index_; }
+ virtual intptr_t source_index() const { return object_table_index_; }
virtual DeoptInstr::Kind kind() const { return kPp; }
virtual const char* ToCString() const {
@@ -539,14 +627,14 @@
"pp oti:%" Pd "", object_table_index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
Function& function = Function::Handle(deopt_context->isolate());
function ^= deopt_context->ObjectAt(object_table_index_);
const Code& code =
Code::Handle(deopt_context->isolate(), function.unoptimized_code());
ASSERT(!code.IsNull());
const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
- *to_addr = pp;
+ *dest_addr = pp;
}
private:
@@ -561,17 +649,17 @@
public:
DeoptCallerFpInstr() {}
- virtual intptr_t from_index() const { return 0; }
+ virtual intptr_t source_index() const { return 0; }
virtual DeoptInstr::Kind kind() const { return kCallerFp; }
virtual const char* ToCString() const {
return "callerfp";
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- *to_addr = deopt_context->GetCallerFp();
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ *dest_addr = deopt_context->GetCallerFp();
deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(
- to_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
+ dest_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
}
private:
@@ -584,15 +672,15 @@
public:
DeoptCallerPpInstr() {}
- virtual intptr_t from_index() const { return 0; }
+ virtual intptr_t source_index() const { return 0; }
virtual DeoptInstr::Kind kind() const { return kCallerPp; }
virtual const char* ToCString() const {
return "callerpp";
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- *to_addr = deopt_context->GetFromPp();
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ *dest_addr = deopt_context->GetSourcePp();
}
private:
@@ -606,15 +694,15 @@
public:
DeoptCallerPcInstr() {}
- virtual intptr_t from_index() const { return 0; }
+ virtual intptr_t source_index() const { return 0; }
virtual DeoptInstr::Kind kind() const { return kCallerPc; }
virtual const char* ToCString() const {
return "callerpc";
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- *to_addr = deopt_context->GetFromPc();
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ *dest_addr = deopt_context->GetSourcePc();
}
private:
@@ -634,12 +722,12 @@
ASSERT(suffix_length >= 0);
}
- explicit DeoptSuffixInstr(intptr_t from_index)
- : info_number_(InfoNumber::decode(from_index)),
- suffix_length_(SuffixLength::decode(from_index)) {
+ explicit DeoptSuffixInstr(intptr_t source_index)
+ : info_number_(InfoNumber::decode(source_index)),
+ suffix_length_(SuffixLength::decode(source_index)) {
}
- virtual intptr_t from_index() const {
+ virtual intptr_t source_index() const {
return InfoNumber::encode(info_number_) |
SuffixLength::encode(suffix_length_);
}
@@ -650,7 +738,7 @@
"suffix %" Pd ":%" Pd, info_number_, suffix_length_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
// The deoptimization info is uncompressed by translating away suffixes
// before executing the instructions.
UNREACHABLE();
@@ -681,7 +769,7 @@
ASSERT(index >= 0);
}
- virtual intptr_t from_index() const { return index_; }
+ virtual intptr_t source_index() const { return index_; }
virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; }
virtual const char* ToCString() const {
@@ -689,10 +777,10 @@
"mat ref #%" Pd "", index_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
- *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
- Isolate::Current()->DeferMaterializedObjectRef(
- index_, to_addr);
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+ deopt_context->DeferMaterializedObjectRef(
+ index_, dest_addr);
}
private:
@@ -712,7 +800,7 @@
ASSERT(field_count >= 0);
}
- virtual intptr_t from_index() const { return field_count_; }
+ virtual intptr_t source_index() const { return field_count_; }
virtual DeoptInstr::Kind kind() const { return kMaterializeObject; }
virtual const char* ToCString() const {
@@ -720,7 +808,7 @@
"mat obj len:%" Pd "", field_count_);
}
- void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
// This instructions are executed manually by the DeoptimizeWithDeoptInfo.
UNREACHABLE();
}
@@ -732,9 +820,10 @@
};
-intptr_t DeoptInstr::DecodeSuffix(intptr_t from_index, intptr_t* info_number) {
- *info_number = DeoptSuffixInstr::InfoNumber::decode(from_index);
- return DeoptSuffixInstr::SuffixLength::decode(from_index);
+intptr_t DeoptInstr::DecodeSuffix(intptr_t source_index,
+ intptr_t* info_number) {
+ *info_number = DeoptSuffixInstr::InfoNumber::decode(source_index);
+ return DeoptSuffixInstr::SuffixLength::decode(source_index);
}
@@ -759,34 +848,35 @@
}
-DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
+DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) {
Kind kind = static_cast<Kind>(kind_as_int);
switch (kind) {
- case kStackSlot: return new DeoptStackSlotInstr(from_index);
- case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index);
- case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index);
+ case kStackSlot: return new DeoptStackSlotInstr(source_index);
+ case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(source_index);
+ case kInt64StackSlot: return new DeoptInt64StackSlotInstr(source_index);
case kFloat32x4StackSlot:
- return new DeoptFloat32x4StackSlotInstr(from_index);
+ return new DeoptFloat32x4StackSlotInstr(source_index);
case kUint32x4StackSlot:
- return new DeoptUint32x4StackSlotInstr(from_index);
- case kRetAddress: return new DeoptRetAddressInstr(from_index);
- case kConstant: return new DeoptConstantInstr(from_index);
- case kRegister: return new DeoptRegisterInstr(from_index);
- case kFpuRegister: return new DeoptFpuRegisterInstr(from_index);
- case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index);
+ return new DeoptUint32x4StackSlotInstr(source_index);
+ case kRetAddress: return new DeoptRetAddressInstr(source_index);
+ case kConstant: return new DeoptConstantInstr(source_index);
+ case kRegister: return new DeoptRegisterInstr(source_index);
+ case kFpuRegister: return new DeoptFpuRegisterInstr(source_index);
+ case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(source_index);
case kFloat32x4FpuRegister:
- return new DeoptFloat32x4FpuRegisterInstr(from_index);
+ return new DeoptFloat32x4FpuRegisterInstr(source_index);
case kUint32x4FpuRegister:
- return new DeoptUint32x4FpuRegisterInstr(from_index);
- case kPcMarker: return new DeoptPcMarkerInstr(from_index);
- case kPp: return new DeoptPpInstr(from_index);
+ return new DeoptUint32x4FpuRegisterInstr(source_index);
+ case kPcMarker: return new DeoptPcMarkerInstr(source_index);
+ case kPp: return new DeoptPpInstr(source_index);
case kCallerFp: return new DeoptCallerFpInstr();
case kCallerPp: return new DeoptCallerPpInstr();
case kCallerPc: return new DeoptCallerPcInstr();
- case kSuffix: return new DeoptSuffixInstr(from_index);
+ case kSuffix: return new DeoptSuffixInstr(source_index);
case kMaterializedObjectRef:
- return new DeoptMaterializedObjectRefInstr(from_index);
- case kMaterializeObject: return new DeoptMaterializeObjectInstr(from_index);
+ return new DeoptMaterializedObjectRefInstr(source_index);
+ case kMaterializeObject:
+ return new DeoptMaterializeObjectInstr(source_index);
}
UNREACHABLE();
return NULL;
@@ -850,16 +940,17 @@
}
-intptr_t DeoptInfoBuilder::CalculateStackIndex(const Location& from_loc) const {
- return from_loc.stack_index() < 0 ?
- from_loc.stack_index() + num_args_ :
- from_loc.stack_index() + num_args_ + kDartFrameFixedSize;
+intptr_t DeoptInfoBuilder::CalculateStackIndex(
+ const Location& source_loc) const {
+ return source_loc.stack_index() < 0 ?
+ source_loc.stack_index() + num_args_ :
+ source_loc.stack_index() + num_args_ + kDartFrameFixedSize;
}
void DeoptInfoBuilder::AddReturnAddress(const Function& function,
intptr_t deopt_id,
- intptr_t to_index) {
+ intptr_t dest_index) {
// Check that deopt_id exists.
// TODO(vegorov): verify after deoptimization targets as well.
#ifdef DEBUG
@@ -868,68 +959,68 @@
(code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt) != 0));
#endif
const intptr_t object_table_index = FindOrAddObjectInTable(function);
- ASSERT(to_index == FrameSize());
+ ASSERT(dest_index == FrameSize());
instructions_.Add(new DeoptRetAddressInstr(object_table_index, deopt_id));
}
void DeoptInfoBuilder::AddPcMarker(const Function& function,
- intptr_t to_index) {
+ intptr_t dest_index) {
intptr_t object_table_index = FindOrAddObjectInTable(function);
- ASSERT(to_index == FrameSize());
+ ASSERT(dest_index == FrameSize());
instructions_.Add(new DeoptPcMarkerInstr(object_table_index));
}
-void DeoptInfoBuilder::AddPp(const Function& function, intptr_t to_index) {
+void DeoptInfoBuilder::AddPp(const Function& function, intptr_t dest_index) {
intptr_t object_table_index = FindOrAddObjectInTable(function);
- ASSERT(to_index == FrameSize());
+ ASSERT(dest_index == FrameSize());
instructions_.Add(new DeoptPpInstr(object_table_index));
}
void DeoptInfoBuilder::AddCopy(Value* value,
- const Location& from_loc,
- const intptr_t to_index) {
+ const Location& source_loc,
+ const intptr_t dest_index) {
DeoptInstr* deopt_instr = NULL;
- if (from_loc.IsConstant()) {
- intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant());
+ if (source_loc.IsConstant()) {
+ intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant());
deopt_instr = new DeoptConstantInstr(object_table_index);
- } else if (from_loc.IsRegister()) {
+ } else if (source_loc.IsRegister()) {
ASSERT(value->definition()->representation() == kTagged);
- deopt_instr = new DeoptRegisterInstr(from_loc.reg());
- } else if (from_loc.IsFpuRegister()) {
+ deopt_instr = new DeoptRegisterInstr(source_loc.reg());
+ } else if (source_loc.IsFpuRegister()) {
if (value->definition()->representation() == kUnboxedDouble) {
- deopt_instr = new DeoptFpuRegisterInstr(from_loc.fpu_reg());
+ deopt_instr = new DeoptFpuRegisterInstr(source_loc.fpu_reg());
} else if (value->definition()->representation() == kUnboxedMint) {
- deopt_instr = new DeoptInt64FpuRegisterInstr(from_loc.fpu_reg());
+ deopt_instr = new DeoptInt64FpuRegisterInstr(source_loc.fpu_reg());
} else if (value->definition()->representation() == kUnboxedFloat32x4) {
- deopt_instr = new DeoptFloat32x4FpuRegisterInstr(from_loc.fpu_reg());
+ deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg());
} else {
ASSERT(value->definition()->representation() == kUnboxedUint32x4);
- deopt_instr = new DeoptUint32x4FpuRegisterInstr(from_loc.fpu_reg());
+ deopt_instr = new DeoptUint32x4FpuRegisterInstr(source_loc.fpu_reg());
}
- } else if (from_loc.IsStackSlot()) {
+ } else if (source_loc.IsStackSlot()) {
ASSERT(value->definition()->representation() == kTagged);
- intptr_t from_index = CalculateStackIndex(from_loc);
- deopt_instr = new DeoptStackSlotInstr(from_index);
- } else if (from_loc.IsDoubleStackSlot()) {
- intptr_t from_index = CalculateStackIndex(from_loc);
+ intptr_t source_index = CalculateStackIndex(source_loc);
+ deopt_instr = new DeoptStackSlotInstr(source_index);
+ } else if (source_loc.IsDoubleStackSlot()) {
+ intptr_t source_index = CalculateStackIndex(source_loc);
if (value->definition()->representation() == kUnboxedDouble) {
- deopt_instr = new DeoptDoubleStackSlotInstr(from_index);
+ deopt_instr = new DeoptDoubleStackSlotInstr(source_index);
} else {
ASSERT(value->definition()->representation() == kUnboxedMint);
- deopt_instr = new DeoptInt64StackSlotInstr(from_index);
+ deopt_instr = new DeoptInt64StackSlotInstr(source_index);
}
- } else if (from_loc.IsQuadStackSlot()) {
- intptr_t from_index = CalculateStackIndex(from_loc);
+ } else if (source_loc.IsQuadStackSlot()) {
+ intptr_t source_index = CalculateStackIndex(source_loc);
if (value->definition()->representation() == kUnboxedFloat32x4) {
- deopt_instr = new DeoptFloat32x4StackSlotInstr(from_index);
+ deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index);
} else {
ASSERT(value->definition()->representation() == kUnboxedUint32x4);
- deopt_instr = new DeoptUint32x4StackSlotInstr(from_index);
+ deopt_instr = new DeoptUint32x4StackSlotInstr(source_index);
}
- } else if (from_loc.IsInvalid() &&
+ } else if (source_loc.IsInvalid() &&
value->definition()->IsMaterializeObject()) {
const intptr_t index = FindMaterialization(
value->definition()->AsMaterializeObject());
@@ -938,32 +1029,32 @@
} else {
UNREACHABLE();
}
- ASSERT(to_index == FrameSize());
+ ASSERT(dest_index == FrameSize());
ASSERT(deopt_instr != NULL);
instructions_.Add(deopt_instr);
}
-void DeoptInfoBuilder::AddCallerFp(intptr_t to_index) {
- ASSERT(to_index == FrameSize());
+void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) {
+ ASSERT(dest_index == FrameSize());
instructions_.Add(new DeoptCallerFpInstr());
}
-void DeoptInfoBuilder::AddCallerPp(intptr_t to_index) {
- ASSERT(to_index == FrameSize());
+void DeoptInfoBuilder::AddCallerPp(intptr_t dest_index) {
+ ASSERT(dest_index == FrameSize());
instructions_.Add(new DeoptCallerPpInstr());
}
-void DeoptInfoBuilder::AddCallerPc(intptr_t to_index) {
- ASSERT(to_index == FrameSize());
+void DeoptInfoBuilder::AddCallerPc(intptr_t dest_index) {
+ ASSERT(dest_index == FrameSize());
instructions_.Add(new DeoptCallerPcInstr());
}
-void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t to_index) {
- ASSERT(to_index == FrameSize());
+void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t dest_index) {
+ ASSERT(dest_index == FrameSize());
intptr_t object_table_index = FindOrAddObjectInTable(obj);
instructions_.Add(new DeoptConstantInstr(object_table_index));
}
@@ -990,20 +1081,21 @@
}
-intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t to_index) {
- ASSERT(to_index == kDartFrameFixedSize);
+intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t dest_index) {
+ ASSERT(dest_index == kDartFrameFixedSize);
for (intptr_t i = 0; i < materializations_.length(); i++) {
MaterializeObjectInstr* mat = materializations_[i];
- AddConstant(mat->cls(), to_index++); // Class of the instance to allocate.
+ // Class of the instance to allocate.
+ AddConstant(mat->cls(), dest_index++);
for (intptr_t i = 0; i < mat->InputCount(); i++) {
if (!mat->InputAt(i)->BindsToConstantNull()) {
// Emit field-value pair.
- AddConstant(mat->FieldAt(i), to_index++);
- AddCopy(mat->InputAt(i), mat->LocationAt(i), to_index++);
+ AddConstant(mat->FieldAt(i), dest_index++);
+ AddCopy(mat->InputAt(i), mat->LocationAt(i), dest_index++);
}
}
}
- return to_index;
+ return dest_index;
}
@@ -1049,7 +1141,7 @@
intptr_t write_count = (suffix_length > 1) ? length - 1 : length;
for (intptr_t i = 0; i < write_count; ++i) {
DeoptInstr* instr = instructions_[i];
- deopt_info.SetAt(i, instr->kind(), instr->from_index());
+ deopt_info.SetAt(i, instr->kind(), instr->source_index());
TrieNode* child = node;
node = new TrieNode(instr, current_info_number_);
node->AddChild(child);
@@ -1059,7 +1151,7 @@
suffix->AddChild(node);
DeoptInstr* instr =
new DeoptSuffixInstr(suffix->info_number(), suffix_length);
- deopt_info.SetAt(length - 1, instr->kind(), instr->from_index());
+ deopt_info.SetAt(length - 1, instr->kind(), instr->source_index());
} else {
trie_root_->AddChild(node);
}
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 564b744..420ce10 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -8,6 +8,7 @@
#include "vm/allocation.h"
#include "vm/assembler.h"
#include "vm/code_generator.h"
+#include "vm/deferred_objects.h"
#include "vm/growable_array.h"
#include "vm/object.h"
@@ -18,75 +19,167 @@
class MaterializeObjectInstr;
// Holds all data relevant for execution of deoptimization instructions.
-class DeoptimizationContext : public ValueObject {
+class DeoptContext {
public:
- // 'to_frame_start' points to the fixed size portion of the frame under sp.
// 'num_args' is 0 if there are no arguments or if there are optional
// arguments.
- DeoptimizationContext(intptr_t* to_frame_start,
- intptr_t to_frame_size,
- const Array& object_table,
- intptr_t num_args,
- DeoptReasonId deopt_reason);
+ DeoptContext(const Array& object_table,
+ intptr_t num_args,
+ DeoptReasonId deopt_reason);
- intptr_t* GetFromFrameAddressAt(intptr_t index) const {
- ASSERT((0 <= index) && (index < from_frame_size_));
- return &from_frame_[index];
+ virtual ~DeoptContext();
+
+ // Sets the sources (frame and registers) for this deoptimization.
+ //
+ // if 'frame_is_copy' is true, DeoptContext will delete the frame
+ // when it is done.
+ void SetSourceArgs(intptr_t* frame_start,
+ intptr_t frame_size,
+ fpu_register_t* fpu_registers,
+ intptr_t* cpu_registers,
+ bool frame_is_copy);
+
+ // Sets the destination fraem for this deoptimization.
+ //
+ // 'frame_start' oints to the fixed size portion of the frame under
+ // sp.
+ //
+ // DeoptContext does not claim ownership of the frame memory.
+ void SetDestArgs(intptr_t* frame_start, intptr_t frame_size);
+
+ intptr_t* GetSourceFrameAddressAt(intptr_t index) const {
+ ASSERT(source_frame_ != NULL);
+ ASSERT((0 <= index) && (index < source_frame_size_));
+ return &source_frame_[index];
}
- intptr_t* GetToFrameAddressAt(intptr_t index) const {
- ASSERT((0 <= index) && (index < to_frame_size_));
- return &to_frame_[index];
+ intptr_t* GetDestFrameAddressAt(intptr_t index) const {
+ ASSERT(dest_frame_ != NULL);
+ ASSERT((0 <= index) && (index < dest_frame_size_));
+ return &dest_frame_[index];
}
- intptr_t GetFromFp() const;
- intptr_t GetFromPp() const;
- intptr_t GetFromPc() const;
+ intptr_t GetSourceFp() const;
+ intptr_t GetSourcePp() const;
+ intptr_t GetSourcePc() const;
intptr_t GetCallerFp() const;
void SetCallerFp(intptr_t callers_fp);
RawObject* ObjectAt(intptr_t index) const {
- return object_table_.At(index);
+ const Array& object_table = Array::Handle(object_table_);
+ return object_table.At(index);
}
intptr_t RegisterValue(Register reg) const {
- return registers_copy_[reg];
+ return cpu_registers_[reg];
}
double FpuRegisterValue(FpuRegister reg) const {
- return *reinterpret_cast<double*>(&fpu_registers_copy_[reg]);
+ return *reinterpret_cast<double*>(&fpu_registers_[reg]);
}
int64_t FpuRegisterValueAsInt64(FpuRegister reg) const {
- return *reinterpret_cast<int64_t*>(&fpu_registers_copy_[reg]);
+ return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]);
}
simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const {
- const float* address = reinterpret_cast<float*>(&fpu_registers_copy_[reg]);
+ const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]);
return simd128_value_t().readFrom(address);
}
Isolate* isolate() const { return isolate_; }
- intptr_t from_frame_size() const { return from_frame_size_; }
+ intptr_t source_frame_size() const { return source_frame_size_; }
DeoptReasonId deopt_reason() const { return deopt_reason_; }
+ void VisitObjectPointers(ObjectPointerVisitor* visitor);
+
+ void PrepareForDeferredMaterialization(intptr_t count) {
+ if (count > 0) {
+ deferred_objects_ = new DeferredObject*[count];
+ deferred_objects_count_ = count;
+ }
+ }
+
+ DeferredObject* GetDeferredObject(intptr_t idx) const {
+ return deferred_objects_[idx];
+ }
+
+ // Sets the materialized value for some deferred object.
+ //
+ // Claims ownership of the memory for 'object'.
+ void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) {
+ deferred_objects_[idx] = object;
+ }
+
+ intptr_t DeferredObjectsCount() const {
+ return deferred_objects_count_;
+ }
+
+ void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
+ deferred_object_refs_ = new DeferredObjectRef(
+ idx,
+ reinterpret_cast<RawInstance**>(slot),
+ deferred_object_refs_);
+ }
+
+ void DeferDoubleMaterialization(double value, RawDouble** slot) {
+ deferred_boxes_ = new DeferredDouble(
+ value,
+ reinterpret_cast<RawInstance**>(slot),
+ deferred_boxes_);
+ }
+
+ void DeferMintMaterialization(int64_t value, RawMint** slot) {
+ deferred_boxes_ = new DeferredMint(
+ value,
+ reinterpret_cast<RawInstance**>(slot),
+ deferred_boxes_);
+ }
+
+ void DeferFloat32x4Materialization(simd128_value_t value,
+ RawFloat32x4** slot) {
+ deferred_boxes_ = new DeferredFloat32x4(
+ value,
+ reinterpret_cast<RawInstance**>(slot),
+ deferred_boxes_);
+ }
+
+ void DeferUint32x4Materialization(simd128_value_t value,
+ RawUint32x4** slot) {
+ deferred_boxes_ = new DeferredUint32x4(
+ value,
+ reinterpret_cast<RawInstance**>(slot),
+ deferred_boxes_);
+ }
+
+ // Materializes all deferred objects. Returns the total number of
+ // artificial arguments used during deoptimization.
+ intptr_t MaterializeDeferredObjects();
+
private:
- const Array& object_table_;
- intptr_t* to_frame_;
- const intptr_t to_frame_size_;
- intptr_t* from_frame_;
- intptr_t from_frame_size_;
- intptr_t* registers_copy_;
- fpu_register_t* fpu_registers_copy_;
+ RawArray* object_table_;
+ intptr_t* dest_frame_;
+ intptr_t dest_frame_size_;
+ bool source_frame_is_copy_;
+ intptr_t* source_frame_;
+ intptr_t source_frame_size_;
+ intptr_t* cpu_registers_;
+ fpu_register_t* fpu_registers_;
const intptr_t num_args_;
const DeoptReasonId deopt_reason_;
intptr_t caller_fp_;
Isolate* isolate_;
- DISALLOW_COPY_AND_ASSIGN(DeoptimizationContext);
+ DeferredSlot* deferred_boxes_;
+ DeferredSlot* deferred_object_refs_;
+
+ intptr_t deferred_objects_count_;
+ DeferredObject** deferred_objects_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeoptContext);
};
@@ -119,25 +212,24 @@
kMaterializeObject
};
- static DeoptInstr* Create(intptr_t kind_as_int, intptr_t from_index);
+ static DeoptInstr* Create(intptr_t kind_as_int, intptr_t source_index);
DeoptInstr() {}
virtual ~DeoptInstr() {}
virtual const char* ToCString() const = 0;
- virtual void Execute(DeoptimizationContext* deopt_context,
- intptr_t* to_addr) = 0;
+ virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0;
virtual DeoptInstr::Kind kind() const = 0;
bool Equals(const DeoptInstr& other) const {
- return (kind() == other.kind()) && (from_index() == other.from_index());
+ return (kind() == other.kind()) && (source_index() == other.source_index());
}
// Decode the payload of a suffix command. Return the suffix length and
// set the output parameter info_number to the index of the shared suffix.
- static intptr_t DecodeSuffix(intptr_t from_index, intptr_t* info_number);
+ static intptr_t DecodeSuffix(intptr_t source_index, intptr_t* info_number);
// Get the function and return address which is encoded in this
// kRetAfterAddress deopt instruction.
@@ -149,13 +241,13 @@
// materialized by kMaterializeObject instruction.
static intptr_t GetFieldCount(DeoptInstr* instr) {
ASSERT(instr->kind() == DeoptInstr::kMaterializeObject);
- return instr->from_index();
+ return instr->source_index();
}
protected:
friend class DeoptInfoBuilder;
- virtual intptr_t from_index() const = 0;
+ virtual intptr_t source_index() const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(DeoptInstr);
@@ -178,15 +270,15 @@
// Return address before instruction.
void AddReturnAddress(const Function& function,
intptr_t deopt_id,
- intptr_t to_index);
+ intptr_t dest_index);
// Copy from optimized frame to unoptimized.
- void AddCopy(Value* value, const Location& from_loc, intptr_t to_index);
- void AddPcMarker(const Function& function, intptr_t to_index);
- void AddPp(const Function& function, intptr_t to_index);
- void AddCallerFp(intptr_t to_index);
- void AddCallerPp(intptr_t to_index);
- void AddCallerPc(intptr_t to_index);
+ void AddCopy(Value* value, const Location& source_loc, intptr_t dest_index);
+ void AddPcMarker(const Function& function, intptr_t dest_index);
+ void AddPp(const Function& function, intptr_t dest_index);
+ void AddCallerFp(intptr_t dest_index);
+ void AddCallerPp(intptr_t dest_index);
+ void AddCallerPc(intptr_t dest_index);
// Add object to be materialized. Emit kMaterializeObject instruction.
void AddMaterialization(MaterializeObjectInstr* mat);
@@ -200,7 +292,7 @@
// At deoptimization they will be removed by the stub at the very end:
// after they were used to materialize objects.
// Returns the index of the next stack slot. Used for verification.
- intptr_t EmitMaterializationArguments(intptr_t to_index);
+ intptr_t EmitMaterializationArguments(intptr_t dest_index);
RawDeoptInfo* CreateDeoptInfo(const Array& deopt_table);
@@ -216,13 +308,13 @@
intptr_t FindOrAddObjectInTable(const Object& obj) const;
intptr_t FindMaterialization(MaterializeObjectInstr* mat) const;
- intptr_t CalculateStackIndex(const Location& from_loc) const;
+ intptr_t CalculateStackIndex(const Location& source_loc) const;
intptr_t FrameSize() const {
return instructions_.length() - frame_start_;
}
- void AddConstant(const Object& obj, intptr_t to_index);
+ void AddConstant(const Object& obj, intptr_t dest_index);
GrowableArray<DeoptInstr*> instructions_;
const GrowableObjectArray& object_table_;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 04cf4f5..5365419 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -609,6 +609,13 @@
}
+void Exceptions::ThrowArgumentError(const Instance& arg) {
+ const Array& args = Array::Handle(Array::New(1));
+ args.SetAt(0, arg);
+ Exceptions::ThrowByType(Exceptions::kArgument, args);
+}
+
+
RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) {
Library& library = Library::Handle();
const String* class_name = NULL;
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 79f7e3a..46d8120 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -65,6 +65,7 @@
static void ThrowByType(ExceptionType type, const Array& arguments);
static void ThrowOOM();
static void ThrowStackOverflow();
+ static void ThrowArgumentError(const Instance& arg);
// Returns a RawInstance if the exception is successfully created,
// otherwise returns a RawError.
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 0f6dce3..b39671b 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -60,9 +60,15 @@
}
-GrowableArray<BlockEntryInstr*>* FlowGraph::codegen_block_order(
+bool FlowGraph::ShouldReorderBlocks(const Function& function,
+ bool is_optimized) {
+ return is_optimized && FLAG_reorder_basic_blocks && !function.is_intrinsic();
+}
+
+
+GrowableArray<BlockEntryInstr*>* FlowGraph::CodegenBlockOrder(
bool is_optimized) {
- return (is_optimized && FLAG_reorder_basic_blocks)
+ return ShouldReorderBlocks(parsed_function().function(), is_optimized)
? &optimized_block_order_
: &reverse_postorder_;
}
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index db384d0..517a9eb 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -82,7 +82,8 @@
const GrowableArray<BlockEntryInstr*>& reverse_postorder() const {
return reverse_postorder_;
}
- GrowableArray<BlockEntryInstr*>* codegen_block_order(bool is_optimized);
+ static bool ShouldReorderBlocks(const Function& function, bool is_optimized);
+ GrowableArray<BlockEntryInstr*>* CodegenBlockOrder(bool is_optimized);
// Iterators.
BlockIterator reverse_postorder_iterator() const {
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index ec2b202..69199f0 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2151,18 +2151,6 @@
}
-void EffectGraphVisitor::TranslateArgumentList(
- const ArgumentListNode& node,
- ZoneGrowableArray<Value*>* values) {
- for (intptr_t i = 0; i < node.length(); ++i) {
- ValueGraphVisitor for_argument(owner(), temp_index());
- node.NodeAt(i)->Visit(&for_argument);
- Append(for_argument);
- values->Add(for_argument.value());
- }
-}
-
-
void EffectGraphVisitor::BuildPushArguments(
const ArgumentListNode& node,
ZoneGrowableArray<PushArgumentInstr*>* values) {
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 5013f3e..d022409 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -20,9 +20,9 @@
// (factory-name-symbol, result-cid, fingerprint).
// TODO(srdjan): Store the values in the snapshot instead.
#define RECOGNIZED_LIST_FACTORY_LIST(V) \
- V(ObjectArrayFactory, kArrayCid, 1558200848) \
- V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 619965861) \
- V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 1180134731) \
+ V(_ListFactory, kArrayCid, 1436567945) \
+ V(_GrowableListWithData, kGrowableObjectArrayCid, 461305701) \
+ V(_GrowableListFactory, kGrowableObjectArrayCid, 910639199) \
V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 810750844) \
V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1246070930) \
V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 1882603960) \
@@ -278,8 +278,6 @@
void HandleStoreLocal(StoreLocalNode* node, bool result_is_needed);
// Helpers for translating parts of the AST.
- void TranslateArgumentList(const ArgumentListNode& node,
- ZoneGrowableArray<Value*>* values);
void BuildPushArguments(const ArgumentListNode& node,
ZoneGrowableArray<PushArgumentInstr*>* values);
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 42df32d..2914711 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -69,7 +69,7 @@
: assembler_(assembler),
parsed_function_(flow_graph->parsed_function()),
flow_graph_(*flow_graph),
- block_order_(*flow_graph->codegen_block_order(is_optimizing)),
+ block_order_(*flow_graph->CodegenBlockOrder(is_optimizing)),
current_block_(NULL),
exception_handlers_list_(NULL),
pc_descriptors_list_(NULL),
@@ -225,6 +225,31 @@
}
+void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
+ if (!is_optimizing()) {
+ if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
+ AssertAssignableInstr* assert = instr->AsAssertAssignable();
+ AddCurrentDescriptor(PcDescriptors::kDeopt,
+ assert->deopt_id(),
+ assert->token_pos());
+ } else if (instr->IsGuardField() ||
+ (instr->CanBecomeDeoptimizationTarget() && !instr->IsGoto())) {
+ // GuardField and instructions that can be deoptimization targets need
+ // to record their deopt id. GotoInstr records its own so that it can
+ // control the placement.
+ AddCurrentDescriptor(PcDescriptors::kDeopt,
+ instr->deopt_id(),
+ Scanner::kDummyTokenIndex);
+ }
+ AllocateRegistersLocally(instr);
+ } else if (instr->MayThrow() &&
+ (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
+ // Optimized try-block: Sync locals to fixed stack locations.
+ EmitTrySync(instr, CurrentTryIndex());
+ }
+}
+
+
void FlowGraphCompiler::VisitBlocks() {
CompactBlocks();
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index f53ad0f..00f31ec 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -340,6 +340,8 @@
void EmitComment(Instruction* instr);
+ void EmitEdgeCounter();
+
void EmitOptimizedInstanceCall(ExternalLabel* target_label,
const ICData& ic_data,
intptr_t argument_count,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 7353b27..fded60a 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -720,28 +720,6 @@
}
-void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
- if (!is_optimizing()) {
- if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
- AssertAssignableInstr* assert = instr->AsAssertAssignable();
- AddCurrentDescriptor(PcDescriptors::kDeopt,
- assert->deopt_id(),
- assert->token_pos());
- } else if (instr->IsGuardField() ||
- instr->CanBecomeDeoptimizationTarget()) {
- AddCurrentDescriptor(PcDescriptors::kDeopt,
- instr->deopt_id(),
- Scanner::kDummyTokenIndex);
- }
- AllocateRegistersLocally(instr);
- } else if (instr->MayThrow() &&
- (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
- // Optimized try-block: Sync locals to fixed stack locations.
- EmitTrySync(instr, CurrentTryIndex());
- }
-}
-
-
void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
Location loc,
bool* push_emitted) {
@@ -1275,6 +1253,22 @@
}
+void FlowGraphCompiler::EmitEdgeCounter() {
+ // We do not check for overflow when incrementing the edge counter. The
+ // function should normally be optimized long before the counter can
+ // overflow; and though we do not reset the counters when we optimize or
+ // deoptimize, there is a bound on the number of
+ // optimization/deoptimization cycles we will attempt.
+ const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+ counter.SetAt(0, Smi::Handle(Smi::New(0)));
+ __ Comment("Edge counter");
+ __ LoadObject(R0, counter);
+ __ ldr(IP, FieldAddress(R0, Array::element_offset(0)));
+ __ adds(IP, IP, ShifterOperand(Smi::RawValue(1)));
+ __ str(IP, FieldAddress(R0, Array::element_offset(0)));
+}
+
+
void FlowGraphCompiler::EmitOptimizedInstanceCall(
ExternalLabel* target_label,
const ICData& ic_data,
@@ -1457,9 +1451,11 @@
__ Push(reg);
__ PushObject(obj);
if (is_optimizing()) {
- __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
+ __ BranchLinkPatchable(
+ &StubCode::OptimizedIdenticalWithNumberCheckLabel());
} else {
- __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
+ __ BranchLinkPatchable(
+ &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
}
AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
Isolate::kNoDeoptId,
@@ -1481,9 +1477,11 @@
__ Push(left);
__ Push(right);
if (is_optimizing()) {
- __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
+ __ BranchLinkPatchable(
+ &StubCode::OptimizedIdenticalWithNumberCheckLabel());
} else {
- __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
+ __ BranchLinkPatchable(
+ &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
}
AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
Isolate::kNoDeoptId,
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 2ea07d5..cfcde17 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -742,28 +742,6 @@
}
-void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
- if (!is_optimizing()) {
- if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
- AssertAssignableInstr* assert = instr->AsAssertAssignable();
- AddCurrentDescriptor(PcDescriptors::kDeopt,
- assert->deopt_id(),
- assert->token_pos());
- } else if (instr->IsGuardField() ||
- instr->CanBecomeDeoptimizationTarget()) {
- AddCurrentDescriptor(PcDescriptors::kDeopt,
- instr->deopt_id(),
- Scanner::kDummyTokenIndex);
- }
- AllocateRegistersLocally(instr);
- } else if (instr->MayThrow() &&
- (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
- // Optimized try-block: Sync locals to fixed stack locations.
- EmitTrySync(instr, CurrentTryIndex());
- }
-}
-
-
void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
Location loc,
bool* push_emitted) {
@@ -1323,6 +1301,21 @@
}
+void FlowGraphCompiler::EmitEdgeCounter() {
+ // We do not check for overflow when incrementing the edge counter. The
+ // function should normally be optimized long before the counter can
+ // overflow; and though we do not reset the counters when we optimize or
+ // deoptimize, there is a bound on the number of
+ // optimization/deoptimization cycles we will attempt.
+ const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+ counter.SetAt(0, Smi::Handle(Smi::New(0)));
+ __ Comment("Edge counter");
+ __ LoadObject(EAX, counter);
+ __ addl(FieldAddress(EAX, Array::element_offset(0)),
+ Immediate(Smi::RawValue(1)));
+}
+
+
void FlowGraphCompiler::EmitOptimizedInstanceCall(
ExternalLabel* target_label,
const ICData& ic_data,
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 03b0a9a..e18577e 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -744,28 +744,6 @@
}
-void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
- if (!is_optimizing()) {
- if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
- AssertAssignableInstr* assert = instr->AsAssertAssignable();
- AddCurrentDescriptor(PcDescriptors::kDeopt,
- assert->deopt_id(),
- assert->token_pos());
- } else if (instr->IsGuardField() ||
- instr->CanBecomeDeoptimizationTarget()) {
- AddCurrentDescriptor(PcDescriptors::kDeopt,
- instr->deopt_id(),
- Scanner::kDummyTokenIndex);
- }
- AllocateRegistersLocally(instr);
- } else if (instr->MayThrow() &&
- (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
- // Optimized try-block: Sync locals to fixed stack locations.
- EmitTrySync(instr, CurrentTryIndex());
- }
-}
-
-
void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
Location loc,
bool* push_emitted) {
@@ -1319,6 +1297,22 @@
}
+void FlowGraphCompiler::EmitEdgeCounter() {
+ // We do not check for overflow when incrementing the edge counter. The
+ // function should normally be optimized long before the counter can
+ // overflow; and though we do not reset the counters when we optimize or
+ // deoptimize, there is a bound on the number of
+ // optimization/deoptimization cycles we will attempt.
+ const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+ counter.SetAt(0, Smi::Handle(Smi::New(0)));
+ __ Comment("Edge counter");
+ __ LoadObject(T0, counter);
+ __ lw(T1, FieldAddress(T0, Array::element_offset(0)));
+ __ AddImmediate(T1, T1, Smi::RawValue(1));
+ __ sw(T1, FieldAddress(T0, Array::element_offset(0)));
+}
+
+
void FlowGraphCompiler::EmitOptimizedInstanceCall(
ExternalLabel* target_label,
const ICData& ic_data,
@@ -1508,9 +1502,11 @@
__ LoadObject(TMP1, obj);
__ sw(TMP1, Address(SP, 0 * kWordSize));
if (is_optimizing()) {
- __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
+ __ BranchLinkPatchable(
+ &StubCode::OptimizedIdenticalWithNumberCheckLabel());
} else {
- __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
+ __ BranchLinkPatchable(
+ &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
}
AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
Isolate::kNoDeoptId,
@@ -1535,9 +1531,11 @@
__ sw(left, Address(SP, 1 * kWordSize));
__ sw(right, Address(SP, 0 * kWordSize));
if (is_optimizing()) {
- __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
+ __ BranchLinkPatchable(
+ &StubCode::OptimizedIdenticalWithNumberCheckLabel());
} else {
- __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
+ __ BranchLinkPatchable(
+ &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
}
AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
Isolate::kNoDeoptId,
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index d3c4095..3078762 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -163,9 +163,9 @@
Label* is_true,
Label* is_false) {
Label fall_through;
- __ CompareObject(bool_register, Object::null_object());
+ __ CompareObject(bool_register, Object::null_object(), PP);
__ j(EQUAL, &fall_through, Assembler::kNearJump);
- __ CompareObject(bool_register, Bool::True());
+ __ CompareObject(bool_register, Bool::True(), PP);
__ j(EQUAL, is_true);
__ jmp(is_false);
__ Bind(&fall_through);
@@ -187,11 +187,11 @@
__ pushq(instance_reg); // Instance.
if (test_kind == kTestTypeOneArg) {
ASSERT(type_arguments_reg == kNoRegister);
- __ PushObject(Object::null_object());
+ __ PushObject(Object::null_object(), PP);
__ Call(&StubCode::Subtype1TestCacheLabel(), PP);
} else if (test_kind == kTestTypeTwoArgs) {
ASSERT(type_arguments_reg == kNoRegister);
- __ PushObject(Object::null_object());
+ __ PushObject(Object::null_object(), PP);
__ Call(&StubCode::Subtype2TestCacheLabel(), PP);
} else if (test_kind == kTestTypeThreeArgs) {
__ pushq(type_arguments_reg);
@@ -342,7 +342,7 @@
// Check if instance is a closure.
__ LoadClassById(R13, kClassIdReg);
__ movq(R13, FieldAddress(R13, Class::signature_function_offset()));
- __ CompareObject(R13, Object::null_object());
+ __ CompareObject(R13, Object::null_object(), PP);
__ j(NOT_EQUAL, is_instance_lbl);
}
// Custom checking for numbers (Smi, Mint, Bigint and Double).
@@ -380,7 +380,7 @@
// Check immediate superclass equality.
__ movq(R13, FieldAddress(R10, Class::super_type_offset()));
__ movq(R13, FieldAddress(R13, Type::type_class_offset()));
- __ CompareObject(R13, type_class);
+ __ CompareObject(R13, type_class, PP);
__ j(EQUAL, is_instance_lbl);
const Register kTypeArgumentsReg = kNoRegister;
@@ -411,7 +411,7 @@
__ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
// RDX: instantiator type arguments.
// Check if type argument is dynamic.
- __ CompareObject(RDX, Object::null_object());
+ __ CompareObject(RDX, Object::null_object(), PP);
__ j(EQUAL, is_instance_lbl);
// Can handle only type arguments that are instances of TypeArguments.
// (runtime checks canonicalize type arguments).
@@ -422,21 +422,21 @@
FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index())));
// RDI: Concrete type of type.
// Check if type argument is dynamic.
- __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType()));
+ __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType()), PP);
__ j(EQUAL, is_instance_lbl);
- __ CompareObject(RDI, Object::null_object());
+ __ CompareObject(RDI, Object::null_object(), PP);
__ j(EQUAL, is_instance_lbl);
const Type& object_type = Type::ZoneHandle(Type::ObjectType());
- __ CompareObject(RDI, object_type);
+ __ CompareObject(RDI, object_type, PP);
__ j(EQUAL, is_instance_lbl);
// For Smi check quickly against int and num interfaces.
Label not_smi;
__ testq(RAX, Immediate(kSmiTagMask)); // Value is Smi?
__ j(NOT_ZERO, ¬_smi, Assembler::kNearJump);
- __ CompareObject(RDI, Type::ZoneHandle(Type::IntType()));
+ __ CompareObject(RDI, Type::ZoneHandle(Type::IntType()), PP);
__ j(EQUAL, is_instance_lbl);
- __ CompareObject(RDI, Type::ZoneHandle(Type::Number()));
+ __ CompareObject(RDI, Type::ZoneHandle(Type::Number()), PP);
__ j(EQUAL, is_instance_lbl);
// Smi must be handled in runtime.
__ jmp(&fall_through);
@@ -577,7 +577,7 @@
// We can only inline this null check if the type is instantiated at compile
// time, since an uninstantiated type at compile time could be Object or
// dynamic at run time.
- __ CompareObject(RAX, Object::null_object());
+ __ CompareObject(RAX, Object::null_object(), PP);
__ j(EQUAL, &is_not_instance);
}
@@ -592,9 +592,9 @@
// Generate runtime call.
__ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
__ movq(RCX, Address(RSP, kWordSize)); // Get instantiator.
- __ PushObject(Object::ZoneHandle()); // Make room for the result.
+ __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
__ pushq(RAX); // Push the instance.
- __ PushObject(type); // Push the type.
+ __ PushObject(type, PP); // Push the type.
__ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null.
__ pushq(RDX); // Instantiator type arguments.
__ LoadObject(RAX, test_cache, PP);
@@ -657,13 +657,13 @@
__ pushq(RDX); // Store instantiator type arguments.
// A null object is always assignable and is returned as result.
Label is_assignable, runtime_call;
- __ CompareObject(RAX, Object::null_object());
+ __ CompareObject(RAX, Object::null_object(), PP);
__ j(EQUAL, &is_assignable);
if (!FLAG_eliminate_type_checks || dst_type.IsMalformed()) {
// If type checks are not eliminated during the graph building then
// a transition sentinel can be seen here.
- __ CompareObject(RAX, Object::transition_sentinel());
+ __ CompareObject(RAX, Object::transition_sentinel(), PP);
__ j(EQUAL, &is_assignable);
}
@@ -678,10 +678,10 @@
}
const String& error_message = String::ZoneHandle(
Symbols::New(error.ToErrorCString()));
- __ PushObject(Object::ZoneHandle()); // Make room for the result.
+ __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
__ pushq(RAX); // Push the source object.
- __ PushObject(dst_name); // Push the name of the destination.
- __ PushObject(error_message);
+ __ PushObject(dst_name, PP); // Push the name of the destination.
+ __ PushObject(error_message, PP);
GenerateCallRuntime(token_pos,
deopt_id,
kMalformedTypeErrorRuntimeEntry,
@@ -704,12 +704,12 @@
__ Bind(&runtime_call);
__ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
__ movq(RCX, Address(RSP, kWordSize)); // Get instantiator.
- __ PushObject(Object::ZoneHandle()); // Make room for the result.
+ __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
__ pushq(RAX); // Push the source object.
- __ PushObject(dst_type); // Push the type of the destination.
+ __ PushObject(dst_type, PP); // Push the type of the destination.
__ pushq(RCX); // Instantiator.
__ pushq(RDX); // Instantiator type arguments.
- __ PushObject(dst_name); // Push the name of the destination.
+ __ PushObject(dst_name, PP); // Push the name of the destination.
__ LoadObject(RAX, test_cache, PP);
__ pushq(RAX);
GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
@@ -724,28 +724,6 @@
}
-void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
- if (!is_optimizing()) {
- if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
- AssertAssignableInstr* assert = instr->AsAssertAssignable();
- AddCurrentDescriptor(PcDescriptors::kDeopt,
- assert->deopt_id(),
- assert->token_pos());
- } else if (instr->IsGuardField() ||
- instr->CanBecomeDeoptimizationTarget()) {
- AddCurrentDescriptor(PcDescriptors::kDeopt,
- instr->deopt_id(),
- Scanner::kDummyTokenIndex);
- }
- AllocateRegistersLocally(instr);
- } else if (instr->MayThrow() &&
- (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
- // Optimized try-block: Sync locals to fixed stack locations.
- EmitTrySync(instr, CurrentTryIndex());
- }
-}
-
-
void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
Location loc,
bool* push_emitted) {
@@ -844,10 +822,10 @@
FieldAddress(R10, ArgumentsDescriptor::positional_count_offset()));
// Check that min_num_pos_args <= num_pos_args.
Label wrong_num_arguments;
- __ cmpq(RCX, Immediate(Smi::RawValue(min_num_pos_args)));
+ __ CompareImmediate(RCX, Immediate(Smi::RawValue(min_num_pos_args)), PP);
__ j(LESS, &wrong_num_arguments);
// Check that num_pos_args <= max_num_pos_args.
- __ cmpq(RCX, Immediate(Smi::RawValue(max_num_pos_args)));
+ __ CompareImmediate(RCX, Immediate(Smi::RawValue(max_num_pos_args)), PP);
__ j(GREATER, &wrong_num_arguments);
// Copy positional arguments.
@@ -929,14 +907,15 @@
// Load RAX with the name of the argument.
__ movq(RAX, Address(RDI, ArgumentsDescriptor::name_offset()));
ASSERT(opt_param[i]->name().IsSymbol());
- __ CompareObject(RAX, opt_param[i]->name());
+ __ CompareObject(RAX, opt_param[i]->name(), PP);
__ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump);
// Load RAX with passed-in argument at provided arg_pos, i.e. at
// fp[kParamEndSlotFromFp + num_args - arg_pos].
__ movq(RAX, Address(RDI, ArgumentsDescriptor::position_offset()));
// RAX is arg_pos as Smi.
// Point to next named entry.
- __ addq(RDI, Immediate(ArgumentsDescriptor::named_entry_size()));
+ __ AddImmediate(
+ RDI, Immediate(ArgumentsDescriptor::named_entry_size()), PP);
__ negq(RAX);
Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi.
__ movq(RAX, argument_addr);
@@ -976,7 +955,7 @@
// arguments have been passed, where k is param_pos, the position of this
// optional parameter in the formal parameter list.
const int param_pos = num_fixed_params + i;
- __ cmpq(RCX, Immediate(param_pos));
+ __ CompareImmediate(RCX, Immediate(param_pos), PP);
__ j(GREATER, &next_parameter, Assembler::kNearJump);
// Load RAX with default argument.
const Object& value = Object::ZoneHandle(
@@ -1101,12 +1080,16 @@
if (is_optimizing()) {
// Reoptimization of an optimized function is triggered by counting in
// IC stubs, but not at the entry of the function.
- __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()),
- Immediate(FLAG_reoptimization_counter_threshold));
+ __ CompareImmediate(
+ FieldAddress(function_reg, Function::usage_counter_offset()),
+ Immediate(FLAG_reoptimization_counter_threshold),
+ new_pp);
} else {
__ incq(FieldAddress(function_reg, Function::usage_counter_offset()));
- __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()),
- Immediate(FLAG_optimization_counter_threshold));
+ __ CompareImmediate(
+ FieldAddress(function_reg, Function::usage_counter_offset()),
+ Immediate(FLAG_optimization_counter_threshold),
+ new_pp);
}
ASSERT(function_reg == RDI);
__ J(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel(), R13);
@@ -1181,7 +1164,7 @@
// Check that exactly num_fixed arguments are passed in.
Label correct_num_arguments, wrong_num_arguments;
__ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
- __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params)));
+ __ CompareImmediate(RAX, Immediate(Smi::RawValue(num_fixed_params)), PP);
__ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump);
__ cmpq(RAX,
FieldAddress(R10,
@@ -1353,6 +1336,21 @@
}
+void FlowGraphCompiler::EmitEdgeCounter() {
+ // We do not check for overflow when incrementing the edge counter. The
+ // function should normally be optimized long before the counter can
+ // overflow; and though we do not reset the counters when we optimize or
+ // deoptimize, there is a bound on the number of
+ // optimization/deoptimization cycles we will attempt.
+ const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+ counter.SetAt(0, Smi::Handle(Smi::New(0)));
+ __ Comment("Edge counter");
+ __ LoadObject(RAX, counter, PP);
+ __ AddImmediate(FieldAddress(RAX, Array::element_offset(0)),
+ Immediate(Smi::RawValue(1)), PP);
+}
+
+
void FlowGraphCompiler::EmitOptimizedInstanceCall(
ExternalLabel* target_label,
const ICData& ic_data,
@@ -1410,7 +1408,7 @@
__ movq(RAX, Address(RSP, (argument_count - 1) * kWordSize));
__ testq(RAX, Immediate(kSmiTagMask));
__ j(NOT_ZERO, ¬_smi, Assembler::kNearJump);
- __ movq(RAX, Immediate(Smi::RawValue(kSmiCid)));
+ __ LoadImmediate(RAX, Immediate(Smi::RawValue(kSmiCid)), PP);
__ jmp(&load_cache);
__ Bind(¬_smi);
@@ -1430,7 +1428,7 @@
__ jmp(&loop);
__ Bind(&update);
- __ addq(RCX, Immediate(Smi::RawValue(1)));
+ __ AddImmediate(RCX, Immediate(Smi::RawValue(1)), PP);
__ Bind(&loop);
__ andq(RCX, RBX);
const intptr_t base = Array::data_offset();
@@ -1453,7 +1451,8 @@
__ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
__ LoadObject(RBX, ic_data, PP);
__ LoadObject(R10, arguments_descriptor, PP);
- __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
+ __ AddImmediate(
+ RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag), PP);
__ call(RAX);
AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
RecordSafepoint(locs);
@@ -1500,7 +1499,7 @@
if (needs_number_check) {
__ pushq(reg);
- __ PushObject(obj);
+ __ PushObject(obj, PP);
if (is_optimizing()) {
__ CallPatchable(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
} else {
@@ -1514,7 +1513,7 @@
return;
}
- __ CompareObject(reg, obj);
+ __ CompareObject(reg, obj, PP);
}
@@ -1547,7 +1546,7 @@
// TODO(vegorov): consider saving only caller save (volatile) registers.
const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count();
if (xmm_regs_count > 0) {
- __ subq(RSP, Immediate(xmm_regs_count * kFpuRegisterSize));
+ __ AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize), PP);
// Store XMM registers with the lowest register number at the lowest
// address.
intptr_t offset = 0;
@@ -1594,7 +1593,7 @@
}
}
ASSERT(offset == (xmm_regs_count * kFpuRegisterSize));
- __ addq(RSP, Immediate(offset));
+ __ AddImmediate(RSP, Immediate(offset), PP);
}
}
@@ -1890,7 +1889,7 @@
void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) {
- __ StoreObject(dst, obj);
+ __ StoreObject(dst, obj, PP);
}
@@ -1926,14 +1925,14 @@
void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
- __ subq(RSP, Immediate(kFpuRegisterSize));
+ __ AddImmediate(RSP, Immediate(-kFpuRegisterSize), PP);
__ movups(Address(RSP, 0), reg);
}
void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
__ movups(reg, Address(RSP, 0));
- __ addq(RSP, Immediate(kFpuRegisterSize));
+ __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP);
}
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 7da716a..b9f6bd4 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -692,8 +692,6 @@
const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
- if (ic_data.NumberOfChecks() == 0) return kIllegalCid;
- // TODO(vegorov): Add multiple receiver type support.
if (ic_data.NumberOfChecks() != 1) return kIllegalCid;
ASSERT(ic_data.HasOneTarget());
@@ -1069,9 +1067,13 @@
case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
case MethodRecognizer::kInt16ArrayGetIndexed:
case MethodRecognizer::kUint16ArrayGetIndexed:
+ return TryInlineGetIndexed(kind, call, ic_data, entry, last);
+ case MethodRecognizer::kFloat32x4ArrayGetIndexed:
+ if (!ShouldInlineSimd()) return false;
+ return TryInlineGetIndexed(kind, call, ic_data, entry, last);
case MethodRecognizer::kInt32ArrayGetIndexed:
case MethodRecognizer::kUint32ArrayGetIndexed:
- case MethodRecognizer::kFloat32x4ArrayGetIndexed:
+ if (!CanUnboxInt32()) return false;
return TryInlineGetIndexed(kind, call, ic_data, entry, last);
default:
return false;
@@ -1176,44 +1178,22 @@
bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) {
- const intptr_t class_id = ReceiverClassId(call);
- switch (class_id) {
- case kArrayCid:
- case kImmutableArrayCid:
- case kGrowableObjectArrayCid:
- case kTypedDataFloat32ArrayCid:
- case kTypedDataFloat64ArrayCid:
- case kTypedDataInt8ArrayCid:
- case kTypedDataUint8ArrayCid:
- case kTypedDataUint8ClampedArrayCid:
- case kExternalTypedDataUint8ArrayCid:
- case kExternalTypedDataUint8ClampedArrayCid:
- case kTypedDataInt16ArrayCid:
- case kTypedDataUint16ArrayCid:
- break;
- case kTypedDataFloat32x4ArrayCid:
- if (!ShouldInlineSimd()) {
- return false;
- }
- break;
- case kTypedDataInt32ArrayCid:
- case kTypedDataUint32ArrayCid:
- if (!CanUnboxInt32()) return false;
- break;
- default:
- return false;
- }
+ // Check for monomorphic IC data.
+ if (!call->HasICData()) return false;
+ const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
+ if (ic_data.NumberOfChecks() != 1) return false;
+ ASSERT(ic_data.HasOneTarget());
- const Function& target =
- Function::Handle(call->ic_data()->GetTargetAt(0));
+ const Function& target = Function::Handle(ic_data.GetTargetAt(0));
TargetEntryInstr* entry;
Definition* last;
- ASSERT(class_id == MethodKindToCid(MethodRecognizer::RecognizeKind(target)));
- bool success = TryInlineRecognizedMethod(target,
- call,
- *call->ic_data(),
- &entry, &last);
- ASSERT(success);
+ if (!TryInlineRecognizedMethod(target,
+ call,
+ *call->ic_data(),
+ &entry, &last)) {
+ return false;
+ }
+
// Insert receiver class check.
AddReceiverCheck(call);
// Remove the original push arguments.
@@ -4168,7 +4148,7 @@
switch (instr->tag()) {
case Instruction::kLoadField: {
LoadFieldInstr* load_field = instr->AsLoadField();
- instance_ = load_field->instance()->definition();
+ instance_ = OriginalDefinition(load_field->instance()->definition());
if (load_field->field() != NULL) {
kind_ = kField;
field_ = load_field->field();
@@ -4184,7 +4164,8 @@
StoreInstanceFieldInstr* store_instance_field =
instr->AsStoreInstanceField();
kind_ = kField;
- instance_ = store_instance_field->instance()->definition();
+ instance_ =
+ OriginalDefinition(store_instance_field->instance()->definition());
field_ = &store_instance_field->field();
break;
}
@@ -4192,7 +4173,7 @@
case Instruction::kStoreVMField: {
StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
kind_ = kVMField;
- instance_ = store_vm_field->dest()->definition();
+ instance_ = OriginalDefinition(store_vm_field->dest()->definition());
offset_in_bytes_ = store_vm_field->offset_in_bytes();
break;
}
@@ -4211,7 +4192,7 @@
case Instruction::kLoadIndexed: {
LoadIndexedInstr* load_indexed = instr->AsLoadIndexed();
kind_ = kIndexed;
- instance_ = load_indexed->array()->definition();
+ instance_ = OriginalDefinition(load_indexed->array()->definition());
index_ = load_indexed->index()->definition();
*is_load = true;
break;
@@ -4220,7 +4201,7 @@
case Instruction::kStoreIndexed: {
StoreIndexedInstr* store_indexed = instr->AsStoreIndexed();
kind_ = kIndexed;
- instance_ = store_indexed->array()->definition();
+ instance_ = OriginalDefinition(store_indexed->array()->definition());
index_ = store_indexed->index()->definition();
break;
}
@@ -4251,7 +4232,7 @@
void set_instance(Definition* def) {
ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed));
- instance_ = def;
+ instance_ = OriginalDefinition(def);
}
const Field& field() const {
@@ -4322,6 +4303,13 @@
static Place* Wrap(const Place& place);
private:
+ static Definition* OriginalDefinition(Definition* defn) {
+ while (defn->IsRedefinition()) {
+ defn = defn->AsRedefinition()->value()->definition();
+ }
+ return defn;
+ }
+
bool SameField(Place* other) const {
return (kind_ == kField) ? (field().raw() == other->field().raw())
: (offset_in_bytes_ == other->offset_in_bytes_);
@@ -6048,6 +6036,80 @@
void ConstantPropagator::VisitStaticCall(StaticCallInstr* instr) {
SetValue(instr, non_constant_);
+ return;
+ // TODO(srdjan): Enable code below once issues resolved.
+ if (IsNonConstant(instr->constant_value())) {
+ // Do not bother with costly analysis if we already know that the
+ // instruction is not a constant.
+ SetValue(instr, non_constant_);
+ return;
+ }
+ MethodRecognizer::Kind recognized_kind =
+ MethodRecognizer::RecognizeKind(instr->function());
+ if (recognized_kind == MethodRecognizer::kStringBaseInterpolate) {
+ // static String _interpolate(List values)
+ //
+ // Code for calling interpolate is generated by the compiler:
+ // v2 <- CreateArray(v0)
+ // StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value.
+ // ..
+ // PushArgument(v2)
+ // v8 <- StaticCall(_interpolate, v2)
+ // Detect that all values are constant, interpolate at compile
+ // time.
+ ASSERT(instr->ArgumentCount() == 1);
+ CreateArrayInstr* create_array = instr->ArgumentAt(0)->AsCreateArray();
+ ASSERT(create_array != NULL);
+ // Check if the string interpolation has only constant inputs.
+ for (Value::Iterator it(create_array->input_use_list());
+ !it.Done();
+ it.Advance()) {
+ Instruction* curr = it.Current()->instruction();
+ StoreIndexedInstr* store = curr->AsStoreIndexed();
+ // 'store' is NULL fir PushArgument instruction: skip it.
+ if ((store != NULL) &&
+ (IsNonConstant(store->value()->definition()->constant_value()))) {
+ SetValue(instr, non_constant_);
+ return;
+ }
+ }
+ // Interpolate string at compile time.
+ const Array& value_arr =
+ Array::Handle(Array::New(create_array->num_elements()));
+ // Build the array of literal values to interpolate, abort if a value is
+ // not literal.
+ for (Value::Iterator it(create_array->input_use_list());
+ !it.Done();
+ it.Advance()) {
+ Instruction* curr = it.Current()->instruction();
+ StoreIndexedInstr* store = curr->AsStoreIndexed();
+ if (store == NULL) {
+ ASSERT(curr == instr->PushArgumentAt(0));
+ } else {
+ Value* index_value = store->index();
+ ASSERT(index_value->BindsToConstant() && index_value->IsSmiValue());
+ const intptr_t ix = Smi::Cast(index_value->BoundConstant()).Value();
+ ASSERT(IsConstant(store->value()->definition()->constant_value()));
+ value_arr.SetAt(ix, store->value()->definition()->constant_value());
+ }
+ }
+ // Build argument array to pass to the interpolation function.
+ const Array& interpolate_arg = Array::Handle(Array::New(1));
+ interpolate_arg.SetAt(0, value_arr);
+ // Call interpolation function.
+ String& concatenated = String::ZoneHandle();
+ concatenated ^=
+ DartEntry::InvokeFunction(instr->function(), interpolate_arg);
+ if (concatenated.IsUnhandledException()) {
+ SetValue(instr, non_constant_);
+ return;
+ }
+
+ concatenated = Symbols::New(concatenated);
+ SetValue(instr, concatenated);
+ } else {
+ SetValue(instr, non_constant_);
+ }
}
@@ -6300,6 +6362,16 @@
void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) {
+ intptr_t cid = instr->object()->Type()->ToCid();
+ if (cid != kDynamicCid) {
+ SetValue(instr, Smi::ZoneHandle(Smi::New(cid)));
+ return;
+ }
+ const Object& object = instr->object()->definition()->constant_value();
+ if (IsConstant(object)) {
+ SetValue(instr, Smi::ZoneHandle(Smi::New(object.GetClassId())));
+ return;
+ }
SetValue(instr, non_constant_);
}
@@ -6870,6 +6942,27 @@
}
+// Code for calling interpolate is generated by the compiler:
+// v2 <- CreateArray(v0)
+// StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value.
+// ..
+// PushArgument(v2)
+// v8 <- StaticCall(_interpolate, v2)
+// Remove the inputs.
+void ConstantPropagator::RemoveInterpolationInputs(
+ const StaticCallInstr& call) {
+ ASSERT(call.ArgumentCount() == 1);
+ CreateArrayInstr* create_array = call.ArgumentAt(0)->AsCreateArray();
+ ASSERT(create_array != NULL);
+ for (Value* use = create_array->input_use_list();
+ use != NULL;
+ use = create_array->input_use_list()) {
+ use->instruction()->RemoveFromGraph();
+ }
+ create_array->RemoveFromGraph();
+}
+
+
void ConstantPropagator::Transform() {
if (FLAG_trace_constant_propagation) {
OS::Print("\n==== Before constant propagation ====\n");
@@ -6977,6 +7070,13 @@
ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
defn->ReplaceUsesWith(constant);
i.RemoveCurrentFromGraph();
+ if (defn->IsStaticCall()) {
+ MethodRecognizer::Kind recognized_kind =
+ MethodRecognizer::RecognizeKind(defn->AsStaticCall()->function());
+ if (recognized_kind == MethodRecognizer::kStringBaseInterpolate) {
+ RemoveInterpolationInputs(*defn->AsStaticCall());
+ }
+ }
}
}
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 8c9f6fe..1879186 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -282,6 +282,8 @@
const Value& left,
const Value& right);
+ void RemoveInterpolationInputs(const StaticCallInstr& call);
+
virtual void VisitBlocks() { UNREACHABLE(); }
#define DECLARE_VISIT(type) virtual void Visit##type(type##Instr* instr);
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 5c442da..80817b5 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -650,7 +650,8 @@
void Float32x4ComparisonInstr::PrintOperandsTo(BufferFormatter* f) const {
- f->Print("Float32x4 Comparison %d", op_kind());
+ f->Print("Float32x4 Comparison %s, ",
+ MethodRecognizer::KindToCString(op_kind()));
left()->PrintTo(f);
f->Print(", ");
right()->PrintTo(f);
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 4ae5936..9cc0d58 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -13,88 +13,99 @@
namespace dart {
CallPattern::CallPattern(uword pc, const Code& code)
- : end_(reinterpret_cast<uword*>(pc)),
+ : object_pool_(Array::Handle(code.ObjectPool())),
+ end_(pc),
+ args_desc_load_end_(0),
+ ic_data_load_end_(0),
target_address_pool_index_(-1),
- args_desc_load_end_(-1),
args_desc_(Array::Handle()),
- ic_data_load_end_(-1),
- ic_data_(ICData::Handle()),
- object_pool_(Array::Handle(code.ObjectPool())) {
+ ic_data_(ICData::Handle()) {
ASSERT(code.ContainsInstructionAt(pc));
- ASSERT(Back(1) == 0xe12fff3e); // Last instruction: blx lr
+ // Last instruction: blx lr.
+ ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e);
+
Register reg;
ic_data_load_end_ =
- DecodeLoadWordFromPool(1, ®, &target_address_pool_index_);
+ InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize,
+ ®,
+ &target_address_pool_index_);
ASSERT(reg == LR);
}
-uword CallPattern::Back(int n) const {
- ASSERT(n > 0);
- return *(end_ - n);
-}
-
-
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the loaded object.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadObject(int end, Register* reg, Object* obj) {
- ASSERT(end > 0);
- uword instr = Back(end + 1);
- if ((instr & 0xfff00000) == 0xe5900000) { // ldr reg, [reg, #+offset]
- int index = 0;
- end = DecodeLoadWordFromPool(end, reg, &index);
- *obj = object_pool_.At(index);
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end). Returns a pointer to
+// the first instruction in the sequence. Returns the register being loaded
+// and the loaded object in the output parameters 'reg' and 'obj'
+// respectively.
+uword InstructionPattern::DecodeLoadObject(uword end,
+ const Array& object_pool,
+ Register* reg,
+ Object* obj) {
+ uword start = 0;
+ Instr* instr = Instr::At(end - Instr::kInstrSize);
+ if ((instr->InstructionBits() & 0xfff00000) == 0xe5900000) {
+ // ldr reg, [reg, #+offset]
+ intptr_t index = 0;
+ start = DecodeLoadWordFromPool(end, reg, &index);
+ *obj = object_pool.At(index);
} else {
- int value = 0;
- end = DecodeLoadWordImmediate(end, reg, &value);
+ intptr_t value = 0;
+ start = DecodeLoadWordImmediate(end, reg, &value);
*obj = reinterpret_cast<RawObject*>(value);
}
- return end;
+ return start;
}
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the loaded immediate value.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadWordImmediate(int end, Register* reg, int* value) {
- ASSERT(end > 0);
- uword instr = Back(++end);
- int imm = 0;
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end). Returns a pointer to
+// the first instruction in the sequence. Returns the register being loaded
+// and the loaded immediate value in the output parameters 'reg' and 'value'
+// respectively.
+uword InstructionPattern::DecodeLoadWordImmediate(uword end,
+ Register* reg,
+ intptr_t* value) {
+ uword start = end - Instr::kInstrSize;
+ int32_t instr = Instr::At(start)->InstructionBits();
+ intptr_t imm = 0;
if ((instr & 0xfff00000) == 0xe3400000) { // movt reg, #imm_hi
imm |= (instr & 0xf0000) << 12;
imm |= (instr & 0xfff) << 16;
- instr = Back(++end);
+ start -= Instr::kInstrSize;
+ instr = Instr::At(start)->InstructionBits();
}
ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo
imm |= (instr & 0xf0000) >> 4;
imm |= instr & 0xfff;
*reg = static_cast<Register>((instr & 0xf000) >> 12);
*value = imm;
- return end;
+ return start;
}
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the index in the pool being read from.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) {
- ASSERT(end > 0);
- uword instr = Back(++end);
- int offset = 0;
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end). Returns a pointer to
+// the first instruction in the sequence. Returns the register being loaded
+// and the index in the pool being read from in the output parameters 'reg'
+// and 'index' respectively.
+uword InstructionPattern::DecodeLoadWordFromPool(uword end,
+ Register* reg,
+ intptr_t* index) {
+ uword start = end - Instr::kInstrSize;
+ int32_t instr = Instr::At(start)->InstructionBits();
+ intptr_t offset = 0;
if ((instr & 0xffff0000) == 0xe59a0000) { // ldr reg, [pp, #+offset]
offset = instr & 0xfff;
*reg = static_cast<Register>((instr & 0xf000) >> 12);
} else {
ASSERT((instr & 0xfff00000) == 0xe5900000); // ldr reg, [reg, #+offset]
offset = instr & 0xfff;
- instr = Back(++end);
+ start -= Instr::kInstrSize;
+ instr = Instr::At(start)->InstructionBits();
if ((instr & 0xffff0000) == 0xe28a0000) { // add reg, pp, shifter_op
- const int rot = (instr & 0xf00) >> 7;
- const int imm8 = instr & 0xff;
+ const intptr_t rot = (instr & 0xf00) >> 7;
+ const intptr_t imm8 = instr & 0xff;
offset += (imm8 >> rot) | (imm8 << (32 - rot));
*reg = static_cast<Register>((instr & 0xf000) >> 12);
} else {
@@ -104,15 +115,19 @@
}
offset += kHeapObjectTag;
ASSERT(Utils::IsAligned(offset, 4));
- *index = (offset - Array::data_offset())/4;
- return end;
+ *index = (offset - Array::data_offset()) / 4;
+ return start;
}
RawICData* CallPattern::IcData() {
if (ic_data_.IsNull()) {
Register reg;
- args_desc_load_end_ = DecodeLoadObject(ic_data_load_end_, ®, &ic_data_);
+ args_desc_load_end_ =
+ InstructionPattern::DecodeLoadObject(ic_data_load_end_,
+ object_pool_,
+ ®,
+ &ic_data_);
ASSERT(reg == R5);
}
return ic_data_.raw();
@@ -123,7 +138,10 @@
if (args_desc_.IsNull()) {
IcData(); // Loading of the ic_data must be decoded first, if not already.
Register reg;
- DecodeLoadObject(args_desc_load_end_, ®, &args_desc_);
+ InstructionPattern::DecodeLoadObject(args_desc_load_end_,
+ object_pool_,
+ ®,
+ &args_desc_);
ASSERT(reg == R4);
}
return args_desc_.raw();
@@ -198,4 +216,3 @@
} // namespace dart
#endif // defined TARGET_ARCH_ARM
-
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 59cb259..05235d1 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -15,6 +15,38 @@
namespace dart {
+class InstructionPattern : public AllStatic {
+ public:
+ // Decodes a load sequence ending at 'end' (the last instruction of the
+ // load sequence is the instruction before the one at end). Returns the
+ // address of the first instruction in the sequence. Returns the register
+ // being loaded and the loaded object in the output parameters 'reg' and
+ // 'obj' respectively.
+ static uword DecodeLoadObject(uword end,
+ const Array& object_pool,
+ Register* reg,
+ Object* obj);
+
+ // Decodes a load sequence ending at 'end' (the last instruction of the
+ // load sequence is the instruction before the one at end). Returns the
+ // address of the first instruction in the sequence. Returns the register
+ // being loaded and the loaded immediate value in the output parameters
+ // 'reg' and 'value' respectively.
+ static uword DecodeLoadWordImmediate(uword end,
+ Register* reg,
+ intptr_t* value);
+
+ // Decodes a load sequence ending at 'end' (the last instruction of the
+ // load sequence is the instruction before the one at end). Returns the
+ // address of the first instruction in the sequence. Returns the register
+ // being loaded and the index in the pool being read from in the output
+ // parameters 'reg' and 'index' respectively.
+ static uword DecodeLoadWordFromPool(uword end,
+ Register* reg,
+ intptr_t* index);
+};
+
+
class CallPattern : public ValueObject {
public:
CallPattern(uword pc, const Code& code);
@@ -32,18 +64,16 @@
static void InsertAt(uword pc, uword target_address);
private:
- uword Back(int n) const;
- int DecodeLoadObject(int end, Register* reg, Object* obj);
- int DecodeLoadWordImmediate(int end, Register* reg, int* value);
- int DecodeLoadWordFromPool(int end, Register* reg, int* index);
- const uword* end_;
- int target_address_pool_index_;
- int args_desc_load_end_;
- Array& args_desc_;
- int ic_data_load_end_;
- ICData& ic_data_;
const Array& object_pool_;
+ uword end_;
+ uword args_desc_load_end_;
+ uword ic_data_load_end_;
+
+ intptr_t target_address_pool_index_;
+ Array& args_desc_;
+ ICData& ic_data_;
+
DISALLOW_COPY_AND_ASSIGN(CallPattern);
};
@@ -71,4 +101,3 @@
} // namespace dart
#endif // VM_INSTRUCTIONS_ARM_H_
-
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index 7215ec0..ae6fbf2 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -13,82 +13,88 @@
namespace dart {
CallPattern::CallPattern(uword pc, const Code& code)
- : end_(reinterpret_cast<uword*>(pc)),
+ : object_pool_(Array::Handle(code.ObjectPool())),
+ end_(pc),
+ args_desc_load_end_(0),
+ ic_data_load_end_(0),
target_address_pool_index_(-1),
- args_desc_load_end_(-1),
args_desc_(Array::Handle()),
- ic_data_load_end_(-1),
- ic_data_(ICData::Handle()),
- object_pool_(Array::Handle(code.ObjectPool())) {
+ ic_data_(ICData::Handle()) {
ASSERT(code.ContainsInstructionAt(pc));
- ASSERT(Back(2) == 0x0020f809); // Last instruction: jalr RA, TMP(=R1)
+ // Last instruction: jalr RA, TMP(=R1).
+ ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0020f809);
Register reg;
- // First end is 0 so that we begin from the delay slot of the jalr.
+ // The end of the pattern is the instruction after the delay slot of the jalr.
ic_data_load_end_ =
- DecodeLoadWordFromPool(2, ®, &target_address_pool_index_);
+ InstructionPattern::DecodeLoadWordFromPool(end_ - (2 * Instr::kInstrSize),
+ ®,
+ &target_address_pool_index_);
ASSERT(reg == TMP);
}
-uword CallPattern::Back(int n) const {
- ASSERT(n > 0);
- return *(end_ - n);
-}
-
-
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the loaded object.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadObject(int end, Register* reg, Object* obj) {
- ASSERT(end > 0);
- uword i = Back(end + 1);
- Instr* instr = Instr::At(reinterpret_cast<uword>(&i));
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end). Returns a pointer to
+// the first instruction in the sequence. Returns the register being loaded
+// and the loaded object in the output parameters 'reg' and 'obj'
+// respectively.
+uword InstructionPattern::DecodeLoadObject(uword end,
+ const Array& object_pool,
+ Register* reg,
+ Object* obj) {
+ uword start = 0;
+ Instr* instr = Instr::At(end - Instr::kInstrSize);
if (instr->OpcodeField() == LW) {
- int index = 0;
- end = DecodeLoadWordFromPool(end, reg, &index);
- *obj = object_pool_.At(index);
+ intptr_t index = 0;
+ start = DecodeLoadWordFromPool(end, reg, &index);
+ *obj = object_pool.At(index);
} else {
- int value = 0;
- end = DecodeLoadWordImmediate(end, reg, &value);
+ intptr_t value = 0;
+ start = DecodeLoadWordImmediate(end, reg, &value);
*obj = reinterpret_cast<RawObject*>(value);
}
- return end;
+ return start;
}
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the loaded immediate value.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadWordImmediate(int end, Register* reg, int* value) {
- ASSERT(end > 0);
- int imm = 0;
- uword i = Back(++end);
- Instr* instr = Instr::At(reinterpret_cast<uword>(&i));
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end). Returns a pointer to
+// the first instruction in the sequence. Returns the register being loaded
+// and the loaded immediate value in the output parameters 'reg' and 'value'
+// respectively.
+uword InstructionPattern::DecodeLoadWordImmediate(uword end,
+ Register* reg,
+ intptr_t* value) {
+ // The pattern is a fixed size, but match backwards for uniformity with
+ // DecodeLoadWordFromPool.
+ uword start = end - Instr::kInstrSize;
+ Instr* instr = Instr::At(start);
+ intptr_t imm = 0;
ASSERT(instr->OpcodeField() == ORI);
imm = instr->UImmField();
*reg = instr->RtField();
- i = Back(++end);
- instr = Instr::At(reinterpret_cast<uword>(&i));
+ start -= Instr::kInstrSize;
+ instr = Instr::At(start);
ASSERT(instr->OpcodeField() == LUI);
ASSERT(instr->RtField() == *reg);
imm |= (instr->UImmField() << 16);
*value = imm;
- return end;
+ return start;
}
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the index in the pool being read from.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) {
- ASSERT(end > 0);
- uword i = Back(++end);
- Instr* instr = Instr::At(reinterpret_cast<uword>(&i));
- int offset = 0;
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end). Returns a pointer to
+// the first instruction in the sequence. Returns the register being loaded
+// and the index in the pool being read from in the output parameters 'reg'
+// and 'index' respectively.
+uword InstructionPattern::DecodeLoadWordFromPool(uword end,
+ Register* reg,
+ intptr_t* index) {
+ uword start = end - Instr::kInstrSize;
+ Instr* instr = Instr::At(start);
+ intptr_t offset = 0;
if ((instr->OpcodeField() == LW) && (instr->RsField() == PP)) {
offset = instr->SImmField();
*reg = instr->RtField();
@@ -97,16 +103,16 @@
offset = instr->SImmField();
*reg = instr->RtField();
- i = Back(++end);
- instr = Instr::At(reinterpret_cast<uword>(&i));
+ start -= Instr::kInstrSize;
+ instr = Instr::At(start);
ASSERT(instr->OpcodeField() == SPECIAL);
ASSERT(instr->FunctionField() == ADDU);
ASSERT(instr->RdField() == *reg);
ASSERT(instr->RsField() == *reg);
ASSERT(instr->RtField() == PP);
- i = Back(++end);
- instr = Instr::At(reinterpret_cast<uword>(&i));
+ start -= Instr::kInstrSize;
+ instr = Instr::At(start);
ASSERT(instr->OpcodeField() == LUI);
ASSERT(instr->RtField() == *reg);
// Offset is signed, so add the upper 16 bits.
@@ -114,15 +120,19 @@
}
offset += kHeapObjectTag;
ASSERT(Utils::IsAligned(offset, 4));
- *index = (offset - Array::data_offset())/4;
- return end;
+ *index = (offset - Array::data_offset()) / 4;
+ return start;
}
RawICData* CallPattern::IcData() {
if (ic_data_.IsNull()) {
Register reg;
- args_desc_load_end_ = DecodeLoadObject(ic_data_load_end_, ®, &ic_data_);
+ args_desc_load_end_ =
+ InstructionPattern::DecodeLoadObject(ic_data_load_end_,
+ object_pool_,
+ ®,
+ &ic_data_);
ASSERT(reg == S5);
}
return ic_data_.raw();
@@ -133,7 +143,10 @@
if (args_desc_.IsNull()) {
IcData(); // Loading of the ic_data must be decoded first, if not already.
Register reg;
- DecodeLoadObject(args_desc_load_end_, ®, &args_desc_);
+ InstructionPattern::DecodeLoadObject(args_desc_load_end_,
+ object_pool_,
+ ®,
+ &args_desc_);
ASSERT(reg == S4);
}
return args_desc_.raw();
@@ -217,4 +230,3 @@
} // namespace dart
#endif // defined TARGET_ARCH_MIPS
-
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index 7cecc70..b4864b7 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -15,6 +15,38 @@
namespace dart {
+class InstructionPattern : public AllStatic {
+ public:
+ // Decodes a load sequence ending at 'end' (the last instruction of the
+ // load sequence is the instruction before the one at end). Returns the
+ // address of the first instruction in the sequence. Returns the register
+ // being loaded and the loaded object in the output parameters 'reg' and
+ // 'obj' respectively.
+ static uword DecodeLoadObject(uword end,
+ const Array& object_pool,
+ Register* reg,
+ Object* obj);
+
+ // Decodes a load sequence ending at 'end' (the last instruction of the
+ // load sequence is the instruction before the one at end). Returns the
+ // address of the first instruction in the sequence. Returns the register
+ // being loaded and the loaded immediate value in the output parameters
+ // 'reg' and 'value' respectively.
+ static uword DecodeLoadWordImmediate(uword end,
+ Register* reg,
+ intptr_t* value);
+
+ // Decodes a load sequence ending at 'end' (the last instruction of the
+ // load sequence is the instruction before the one at end). Returns the
+ // address of the first instruction in the sequence. Returns the register
+ // being loaded and the index in the pool being read from in the output
+ // parameters 'reg' and 'index' respectively.
+ static uword DecodeLoadWordFromPool(uword end,
+ Register* reg,
+ intptr_t* index);
+};
+
+
class CallPattern : public ValueObject {
public:
CallPattern(uword pc, const Code& code);
@@ -32,18 +64,16 @@
static void InsertAt(uword pc, uword target_address);
private:
- uword Back(int n) const;
- int DecodeLoadObject(int end, Register* reg, Object* obj);
- int DecodeLoadWordImmediate(int end, Register* reg, int* value);
- int DecodeLoadWordFromPool(int end, Register* reg, int* index);
- const uword* end_;
- int target_address_pool_index_;
- int args_desc_load_end_;
- Array& args_desc_;
- int ic_data_load_end_;
- ICData& ic_data_;
const Array& object_pool_;
+ uword end_;
+ uword args_desc_load_end_;
+ uword ic_data_load_end_;
+
+ intptr_t target_address_pool_index_;
+ Array& args_desc_;
+ ICData& ic_data_;
+
DISALLOW_COPY_AND_ASSIGN(CallPattern);
};
@@ -72,4 +102,3 @@
} // namespace dart
#endif // VM_INSTRUCTIONS_MIPS_H_
-
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index 0f788073..7b0b4ae 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -13,7 +13,7 @@
intptr_t InstructionPattern::IndexFromPPLoad(uword start) {
int32_t offset = *reinterpret_cast<int32_t*>(start);
- offset += kHeapObjectTag;
+ offset += kHeapObjectTag;
return (offset - Array::data_offset()) / kWordSize;
}
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 147ea56..50c4930 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -362,12 +362,12 @@
MethodRecognizer::Kind MethodRecognizer::RecognizeKind(
const Function& function) {
- const Class& function_class = Class::Handle(function.Owner());
- const Library& lib = Library::Handle(function_class.library());
- if (!IsRecognizedLibrary(lib)) {
+ if (!function.is_recognized()) {
return kUnknown;
}
+ const Class& function_class = Class::Handle(function.Owner());
+ const Library& lib = Library::Handle(function_class.library());
const String& function_name = String::Handle(function.name());
const String& class_name = String::Handle(function_class.Name());
@@ -379,6 +379,7 @@
}
RECOGNIZED_LIST(RECOGNIZE_FUNCTION)
#undef RECOGNIZE_FUNCTION
+ UNREACHABLE();
return kUnknown;
}
@@ -414,7 +415,25 @@
}
+void MethodRecognizer::InitializeState() {
+ GrowableArray<Library*> libs(3);
+ libs.Add(&Library::ZoneHandle(Library::CoreLibrary()));
+ libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
+ libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
+ Function& func = Function::Handle();
+
+#define SET_IS_RECOGNIZED(class_name, function_name, dest, fp) \
+ func = Library::GetFunction(libs, #class_name, #function_name); \
+ ASSERT(!func.IsNull()); \
+ func.set_is_recognized(true); \
+
+ RECOGNIZED_LIST(SET_IS_RECOGNIZED);
+
+#undef SET_IS_RECOGNIZED
+}
+
// ==== Support for visiting flow graphs.
+
#define DEFINE_ACCEPT(ShortName) \
void ShortName##Instr::Accept(FlowGraphVisitor* visitor) { \
visitor->Visit##ShortName(this); \
@@ -1645,6 +1664,12 @@
LocationSummary* TargetEntryInstr::MakeLocationSummary() const {
+ // FlowGraphCompiler::EmitInstructionPrologue is not called for block
+ // entry instructions, so this function is unused. If it becomes
+ // reachable, note that the deoptimization descriptor in unoptimized code
+ // comes after the point of local register allocation due to pattern
+ // matching the edge counter code backwards (as a code reuse convenience
+ // on some platforms).
UNREACHABLE();
return NULL;
}
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 766fcaa..35ca39c 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -41,8 +41,8 @@
V(::, identical, ObjectIdentical, 496869842) \
V(Object, Object., ObjectConstructor, 1058585294) \
V(Object, get:_cid, ObjectCid, 1498721510) \
- V(_ObjectArray, get:length, ObjectArrayLength, 259382695) \
- V(_ImmutableArray, get:length, ImmutableArrayLength, 1342001998) \
+ V(_List, get:length, ObjectArrayLength, 215153395) \
+ V(_ImmutableList, get:length, ImmutableArrayLength, 578733070) \
V(_TypedList, get:length, TypedDataLength, 26616328) \
V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 272598802) \
V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 831354841) \
@@ -62,14 +62,15 @@
V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1457395244) \
V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 49127618) \
V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1261559935) \
- V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160417196) \
- V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 1509841570) \
- V(_GrowableObjectArray, _setData, GrowableArraySetData, 1574432374) \
- V(_GrowableObjectArray, _setLength, GrowableArraySetLength, 1112774552) \
+ V(_GrowableList, get:length, GrowableArrayLength, 1654225242) \
+ V(_GrowableList, get:_capacity, GrowableArrayCapacity, 817090003) \
+ V(_GrowableList, _setData, GrowableArraySetData, 1375509957) \
+ V(_GrowableList, _setLength, GrowableArraySetLength, 1227678442) \
V(_StringBase, get:length, StringBaseLength, 1483520063) \
V(_StringBase, get:isEmpty, StringBaseIsEmpty, 879849436) \
V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1958436584) \
V(_StringBase, [], StringBaseCharAt, 990046076) \
+ V(_StringBase, _interpolate, StringBaseInterpolate, 908021574) \
V(_OneByteString, _setAt, OneByteStringSetAt, 308408714) \
V(_IntegerImplementation, toDouble, IntegerToDouble, 2011998508) \
V(_IntegerImplementation, _leftShiftWithMask32, IntegerLeftShiftWithMask32, \
@@ -134,9 +135,9 @@
V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 830610988) \
V(_Uint32x4, withFlagZ, Uint32x4WithFlagZ, 1714792414) \
V(_Uint32x4, withFlagW, Uint32x4WithFlagW, 1516924162) \
- V(_ObjectArray, [], ObjectArrayGetIndexed, 544020319) \
- V(_ImmutableArray, [], ImmutableArrayGetIndexed, 1345387065) \
- V(_GrowableObjectArray, [], GrowableArrayGetIndexed, 951312767) \
+ V(_List, [], ObjectArrayGetIndexed, 1079829188) \
+ V(_ImmutableList, [], ImmutableArrayGetIndexed, 25983597) \
+ V(_GrowableList, [], GrowableArrayGetIndexed, 1686777561) \
V(_Float32Array, [], Float32ArrayGetIndexed, 1225286513) \
V(_Float64Array, [], Float64ArrayGetIndexed, 871118335) \
V(_Int8Array, [], Int8ArrayGetIndexed, 199925538) \
@@ -154,14 +155,14 @@
// A list of core function that should always be inlined.
#define INLINE_WHITE_LIST(V) \
- V(_ObjectArray, get:length, ObjectArrayLength, 259382695) \
- V(_ImmutableArray, get:length, ImmutableArrayLength, 1342001998) \
+ V(_List, get:length, ObjectArrayLength, 215153395) \
+ V(_ImmutableList, get:length, ImmutableArrayLength, 578733070) \
V(_TypedList, get:length, TypedDataLength, 26616328) \
- V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160417196) \
+ V(_GrowableList, get:length, GrowableArrayLength, 1654225242) \
V(_StringBase, get:length, StringBaseLength, 1483520063) \
V(ListIterator, moveNext, ListIteratorMoveNext, 90930587) \
- V(_GrowableObjectArray, get:iterator, GrowableArrayIterator, 2129691657) \
- V(_GrowableObjectArray, forEach, GrowableArrayForEach, 1669274418)
+ V(_GrowableList, get:iterator, GrowableArrayIterator, 1305127405) \
+ V(_GrowableList, forEach, GrowableArrayForEach, 1675430533)
// Class that recognizes the name and owner of a function and returns the
@@ -179,6 +180,7 @@
static Kind RecognizeKind(const Function& function);
static bool AlwaysInline(const Function& function);
static const char* KindToCString(Kind kind);
+ static void InitializeState();
};
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 00df26b..35b43d9 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -361,14 +361,6 @@
const Array& kNoArgumentNames = Object::null_array();
const int kNumArgumentsChecked = 2;
- Label check_identity;
- __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
- __ ldm(IA, SP, (1 << R0) | (1 << R1));
- __ cmp(R1, ShifterOperand(IP));
- __ b(&check_identity, EQ);
- __ cmp(R0, ShifterOperand(IP));
- __ b(&check_identity, EQ);
-
ICData& equality_ic_data = ICData::ZoneHandle();
if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
ASSERT(!original_ic_data.IsNull());
@@ -395,42 +387,12 @@
kNoArgumentNames,
locs,
equality_ic_data);
- Label check_ne;
- __ b(&check_ne);
-
- __ Bind(&check_identity);
- Label equality_done;
- if (compiler->is_optimizing()) {
- // No need to update IC data.
- __ PopList((1 << R0) | (1 << R1));
- __ cmp(R0, ShifterOperand(R1));
- __ LoadObject(R0, Bool::Get(kind != Token::kEQ), NE);
- __ LoadObject(R0, Bool::Get(kind == Token::kEQ), EQ);
- if (kind == Token::kNE) {
- // Skip not-equal result conversion.
- __ b(&equality_done);
- }
- } else {
- // Call stub, load IC data in register. The stub will update ICData if
- // necessary.
- Register ic_data_reg = locs->temp(0).reg();
- ASSERT(ic_data_reg == R5); // Stub depends on it.
- __ LoadObject(ic_data_reg, equality_ic_data);
- // Pass left in R1 and right in R0.
- compiler->GenerateCall(token_pos,
- &StubCode::EqualityWithNullArgLabel(),
- PcDescriptors::kRuntimeCall,
- locs);
- __ Drop(2);
- }
- __ Bind(&check_ne);
if (kind == Token::kNE) {
// Negate the condition: true label returns false and vice versa.
__ CompareObject(R0, Bool::True());
__ LoadObject(R0, Bool::True(), NE);
__ LoadObject(R0, Bool::False(), EQ);
}
- __ Bind(&equality_done);
}
@@ -612,35 +574,11 @@
ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
Register left = locs->in(0).reg();
Register right = locs->in(1).reg();
- Label done, identity_compare, non_null_compare;
- __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
- __ cmp(right, ShifterOperand(IP));
- __ b(&identity_compare, EQ);
- __ cmp(left, ShifterOperand(IP));
- __ b(&non_null_compare, NE);
- // Comparison with NULL is "===".
- __ Bind(&identity_compare);
- __ cmp(left, ShifterOperand(right));
- Condition cond = TokenKindToSmiCondition(kind);
- if (branch != NULL) {
- branch->EmitBranchOnCondition(compiler, cond);
- } else {
- Register result = locs->out().reg();
- Label load_true;
- __ b(&load_true, cond);
- __ LoadObject(result, Bool::False());
- __ b(&done);
- __ Bind(&load_true);
- __ LoadObject(result, Bool::True());
- }
- __ b(&done);
- __ Bind(&non_null_compare); // Receiver is not null.
ASSERT(left == R1);
ASSERT(right == R0);
__ PushList((1 << R0) | (1 << R1));
EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
deopt_id, token_pos);
- __ Bind(&done);
}
@@ -4444,18 +4382,14 @@
void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
if (!compiler->is_optimizing()) {
+ compiler->EmitEdgeCounter();
+ // Add an edge counter.
+ // On ARM the deoptimization descriptor points after the edge counter
+ // code so that we can reuse the same pattern matching code as at call
+ // sites, which matches backwards from the end of the pattern.
compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
deopt_id_,
Scanner::kDummyTokenIndex);
- // Add an edge counter.
- const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
- counter.SetAt(0, Smi::Handle(Smi::New(0)));
- __ Comment("Edge counter");
- __ LoadObject(R0, counter);
- __ ldr(IP, FieldAddress(R0, Array::element_offset(0)));
- __ adds(IP, IP, ShifterOperand(Smi::RawValue(1)));
- __ LoadImmediate(IP, Smi::RawValue(Smi::kMaxValue), VS); // If overflow.
- __ str(IP, FieldAddress(R0, Array::element_offset(0)));
}
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -4469,6 +4403,17 @@
void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (!compiler->is_optimizing()) {
+ compiler->EmitEdgeCounter();
+ // Add a deoptimization descriptor for deoptimizing instructions that
+ // may be inserted before this instruction. On ARM this descriptor
+ // points after the edge counter code so that we can reuse the same
+ // pattern matching code as at call sites, which matches backwards from
+ // the end of the pattern.
+ compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+ GetDeoptId(),
+ Scanner::kDummyTokenIndex);
+ }
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 279051c..bbbbe97 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -310,14 +310,6 @@
const Array& kNoArgumentNames = Object::null_array();
const int kNumArgumentsChecked = 2;
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
- Label check_identity;
- __ cmpl(Address(ESP, 0 * kWordSize), raw_null);
- __ j(EQUAL, &check_identity);
- __ cmpl(Address(ESP, 1 * kWordSize), raw_null);
- __ j(EQUAL, &check_identity);
-
ICData& equality_ic_data = ICData::ZoneHandle();
if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
ASSERT(!original_ic_data.IsNull());
@@ -344,39 +336,6 @@
kNoArgumentNames,
locs,
equality_ic_data);
- Label check_ne;
- __ jmp(&check_ne);
-
- __ Bind(&check_identity);
- Label equality_done;
- if (compiler->is_optimizing()) {
- // No need to update IC data.
- Label is_true;
- __ popl(EAX);
- __ popl(EDX);
- __ cmpl(EAX, EDX);
- __ j(EQUAL, &is_true);
- __ LoadObject(EAX, Bool::Get(kind != Token::kEQ));
- __ jmp(&equality_done);
- __ Bind(&is_true);
- __ LoadObject(EAX, Bool::Get(kind == Token::kEQ));
- if (kind == Token::kNE) {
- // Skip not-equal result conversion.
- __ jmp(&equality_done);
- }
- } else {
- // Call stub, load IC data in register. The stub will update ICData if
- // necessary.
- Register ic_data_reg = locs->temp(0).reg();
- ASSERT(ic_data_reg == ECX); // Stub depends on it.
- __ LoadObject(ic_data_reg, equality_ic_data);
- compiler->GenerateCall(token_pos,
- &StubCode::EqualityWithNullArgLabel(),
- PcDescriptors::kRuntimeCall,
- locs);
- __ Drop(2);
- }
- __ Bind(&check_ne);
if (kind == Token::kNE) {
Label true_label, done;
// Negate the condition: true label returns false and vice versa.
@@ -388,7 +347,6 @@
__ LoadObject(EAX, Bool::False());
__ Bind(&done);
}
- __ Bind(&equality_done);
}
@@ -562,35 +520,10 @@
ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
Register left = locs->in(0).reg();
Register right = locs->in(1).reg();
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
- Label done, identity_compare, non_null_compare;
- __ cmpl(right, raw_null);
- __ j(EQUAL, &identity_compare, Assembler::kNearJump);
- __ cmpl(left, raw_null);
- __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
- // Comparison with NULL is "===".
- __ Bind(&identity_compare);
- __ cmpl(left, right);
- Condition cond = TokenKindToSmiCondition(kind);
- if (branch != NULL) {
- branch->EmitBranchOnCondition(compiler, cond);
- } else {
- Register result = locs->out().reg();
- Label load_true;
- __ j(cond, &load_true, Assembler::kNearJump);
- __ LoadObject(result, Bool::False());
- __ jmp(&done);
- __ Bind(&load_true);
- __ LoadObject(result, Bool::True());
- }
- __ jmp(&done);
- __ Bind(&non_null_compare); // Receiver is not null.
__ pushl(left);
__ pushl(right);
EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
deopt_id, token_pos);
- __ Bind(&done);
}
@@ -1827,7 +1760,7 @@
__ movl(value_cid_reg,
FieldAddress(value_reg, TypedData::length_offset()));
}
- __ cmpl(value_cid_reg, Immediate(field_length));
+ __ cmpl(value_cid_reg, Immediate(Smi::RawValue(field_length)));
if (ok_is_fall_through) {
__ j(NOT_EQUAL, fail);
}
@@ -4780,21 +4713,13 @@
void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
if (!compiler->is_optimizing()) {
+ compiler->EmitEdgeCounter();
+ // The deoptimization descriptor points after the edge counter code for
+ // uniformity with ARM and MIPS, where we can reuse pattern matching
+ // code that matches backwards from the end of the pattern.
compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
deopt_id_,
Scanner::kDummyTokenIndex);
- // Add an edge counter.
- const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
- counter.SetAt(0, Smi::Handle(Smi::New(0)));
- Label done;
- __ Comment("Edge counter");
- __ LoadObject(EAX, counter);
- __ addl(FieldAddress(EAX, Array::element_offset(0)),
- Immediate(Smi::RawValue(1)));
- __ j(NO_OVERFLOW, &done);
- __ movl(FieldAddress(EAX, Array::element_offset(0)),
- Immediate(Smi::RawValue(Smi::kMaxValue)));
- __ Bind(&done);
}
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -4809,23 +4734,15 @@
void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
if (!compiler->is_optimizing()) {
- // Add deoptimization descriptor for deoptimizing instructions that may
- // be inserted before this instruction.
+ compiler->EmitEdgeCounter();
+ // Add a deoptimization descriptor for deoptimizing instructions that
+ // may be inserted before this instruction. This descriptor points
+ // after the edge counter for uniformity with ARM and MIPS, where we can
+ // reuse pattern matching that matches backwards from the end of the
+ // pattern.
compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
GetDeoptId(),
- 0); // No token position.
- // Add an edge counter.
- const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
- counter.SetAt(0, Smi::Handle(Smi::New(0)));
- Label done;
- __ Comment("Edge counter");
- __ LoadObject(EAX, counter);
- __ addl(FieldAddress(EAX, Array::element_offset(0)),
- Immediate(Smi::RawValue(1)));
- __ j(NO_OVERFLOW, &done);
- __ movl(FieldAddress(EAX, Array::element_offset(0)),
- Immediate(Smi::RawValue(Smi::kMaxValue)));
- __ Bind(&done);
+ Scanner::kDummyTokenIndex);
}
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index a1d5b18..4456f6e 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -356,12 +356,6 @@
__ TraceSimMsg("EmitEqualityAsInstanceCall");
__ Comment("EmitEqualityAsInstanceCall");
- Label check_identity;
- __ lw(A1, Address(SP, 1 * kWordSize));
- __ lw(A0, Address(SP, 0 * kWordSize));
- __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null()));
- __ beq(A1, CMPRES1, &check_identity);
- __ beq(A0, CMPRES1, &check_identity);
ICData& equality_ic_data = ICData::ZoneHandle();
if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
@@ -389,40 +383,6 @@
kNoArgumentNames,
locs,
equality_ic_data);
- Label check_ne;
- __ b(&check_ne);
-
- __ Bind(&check_identity);
- Label equality_done;
- if (compiler->is_optimizing()) {
- // No need to update IC data.
- Label is_true;
- __ lw(A1, Address(SP, 1 * kWordSize));
- __ lw(A0, Address(SP, 0 * kWordSize));
- __ addiu(SP, SP, Immediate(2 * kWordSize));
- __ beq(A1, A0, &is_true);
- __ LoadObject(V0, Bool::Get(kind != Token::kEQ));
- __ b(&equality_done);
- __ Bind(&is_true);
- __ LoadObject(V0, Bool::Get(kind == Token::kEQ));
- if (kind == Token::kNE) {
- // Skip not-equal result conversion.
- __ b(&equality_done);
- }
- } else {
- // Call stub, load IC data in register. The stub will update ICData if
- // necessary.
- Register ic_data_reg = locs->temp(0).reg();
- ASSERT(ic_data_reg == T0); // Stub depends on it.
- __ LoadObject(ic_data_reg, equality_ic_data);
- // Pass left in A1 and right in A0.
- compiler->GenerateCall(token_pos,
- &StubCode::EqualityWithNullArgLabel(),
- PcDescriptors::kRuntimeCall,
- locs);
- __ Drop(2);
- }
- __ Bind(&check_ne);
if (kind == Token::kNE) {
Label true_label, done;
// Negate the condition: true label returns false and vice versa.
@@ -433,7 +393,6 @@
__ LoadObject(V0, Bool::False());
__ Bind(&done);
}
- __ Bind(&equality_done);
}
@@ -649,31 +608,8 @@
ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
Register left = locs->in(0).reg();
Register right = locs->in(1).reg();
- Label done, identity_compare, non_null_compare;
__ TraceSimMsg("EmitGenericEqualityCompare");
__ Comment("EmitGenericEqualityCompare");
- __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null()));
- __ beq(right, CMPRES1, &identity_compare);
- __ bne(left, CMPRES1, &non_null_compare);
-
- // Comparison with NULL is "===".
- __ Bind(&identity_compare);
- Condition cond = TokenKindToSmiCondition(kind);
- __ slt(CMPRES1, left, right);
- __ slt(CMPRES2, right, left);
- if (branch != NULL) {
- branch->EmitBranchOnCondition(compiler, cond);
- } else {
- Register result = locs->out().reg();
- Label load_true;
- EmitBranchAfterCompare(compiler, cond, &load_true);
- __ LoadObject(result, Bool::False());
- __ b(&done);
- __ Bind(&load_true);
- __ LoadObject(result, Bool::True());
- }
- __ b(&done);
- __ Bind(&non_null_compare); // Receiver is not null.
ASSERT(left == A1);
ASSERT(right == A0);
__ addiu(SP, SP, Immediate(-2 * kWordSize));
@@ -681,7 +617,6 @@
__ sw(A0, Address(SP, 0 * kWordSize));
EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
deopt_id, token_pos);
- __ Bind(&done);
}
@@ -3838,22 +3773,13 @@
void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
if (!compiler->is_optimizing()) {
+ compiler->EmitEdgeCounter();
+ // On MIPS the deoptimization descriptor points after the edge counter
+ // code so that we can reuse the same pattern matching code as at call
+ // sites, which matches backwards from the end of the pattern.
compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
deopt_id_,
Scanner::kDummyTokenIndex);
- // Add an edge counter.
- const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
- counter.SetAt(0, Smi::Handle(Smi::New(0)));
- Label done;
- __ Comment("Edge counter");
- __ LoadObject(T0, counter);
- __ lw(T1, FieldAddress(T0, Array::element_offset(0)));
- __ AddImmediateDetectOverflow(T1, T1, Smi::RawValue(1), CMPRES, T2);
- __ bgez(CMPRES, &done);
- __ delay_slot()->sw(T1, FieldAddress(T0, Array::element_offset(0)));
- __ LoadImmediate(TMP1, Smi::RawValue(Smi::kMaxValue));
- __ sw(TMP1, FieldAddress(T0, Array::element_offset(0))); // If overflow.
- __ Bind(&done);
}
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -3868,6 +3794,17 @@
void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ TraceSimMsg("GotoInstr");
+ if (!compiler->is_optimizing()) {
+ compiler->EmitEdgeCounter();
+ // Add a deoptimization descriptor for deoptimizing instructions that
+ // may be inserted before this instruction. On MIPS this descriptor
+ // points after the edge counter code so that we can reuse the same
+ // pattern matching code as at call sites, which matches backwards from
+ // the end of the pattern.
+ compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+ GetDeoptId(),
+ Scanner::kDummyTokenIndex);
+ }
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 096ff06..4b5562b 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -52,7 +52,7 @@
if (value.IsRegister()) {
__ pushq(value.reg());
} else if (value.IsConstant()) {
- __ PushObject(value.constant());
+ __ PushObject(value.constant(), PP);
} else {
ASSERT(value.IsStackSlot());
__ pushq(value.ToStackSlotAddress());
@@ -90,7 +90,7 @@
ASSERT(fp_sp_dist <= 0);
__ movq(RDI, RSP);
__ subq(RDI, RBP);
- __ cmpq(RDI, Immediate(fp_sp_dist));
+ __ CompareImmediate(RDI, Immediate(fp_sp_dist), PP);
__ j(EQUAL, &done, Assembler::kNearJump);
__ int3();
__ Bind(&done);
@@ -196,9 +196,9 @@
if ((kind_ == Token::kNE_STRICT) || (kind_ == Token::kNE)) {
result = !result;
}
- __ movq(locs()->out().reg(),
+ __ LoadImmediate(locs()->out().reg(),
Immediate(reinterpret_cast<int64_t>(
- Smi::New(result ? if_true_ : if_false_))));
+ Smi::New(result ? if_true_ : if_false_))), PP);
return;
}
@@ -212,9 +212,9 @@
// TODO(vegorov): reuse code from the other comparison instructions instead of
// generating it inline here.
if (left.IsConstant()) {
- __ CompareObject(right.reg(), left.constant());
+ __ CompareObject(right.reg(), left.constant(), PP);
} else if (right.IsConstant()) {
- __ CompareObject(left.reg(), right.constant());
+ __ CompareObject(left.reg(), right.constant(), PP);
} else {
__ cmpq(left.reg(), right.reg());
}
@@ -251,11 +251,11 @@
Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value));
__ shlq(RDX, Immediate(shift + kSmiTagSize));
} else {
- __ subq(RDX, Immediate(1));
- __ andq(RDX, Immediate(
- Smi::RawValue(true_value) - Smi::RawValue(false_value)));
+ __ AddImmediate(RDX, Immediate(-1), PP);
+ __ AndImmediate(RDX,
+ Immediate(Smi::RawValue(true_value) - Smi::RawValue(false_value)), PP);
if (false_value != 0) {
- __ addq(RDX, Immediate(Smi::RawValue(false_value)));
+ __ AddImmediate(RDX, Immediate(Smi::RawValue(false_value)), PP);
}
}
}
@@ -341,9 +341,9 @@
// Call the runtime if the object is not bool::true or bool::false.
ASSERT(locs->always_calls());
Label done;
- __ CompareObject(reg, Bool::True());
+ __ CompareObject(reg, Bool::True(), PP);
__ j(EQUAL, &done, Assembler::kNearJump);
- __ CompareObject(reg, Bool::False());
+ __ CompareObject(reg, Bool::False(), PP);
__ j(EQUAL, &done, Assembler::kNearJump);
__ pushq(reg); // Push the source object.
@@ -453,13 +453,6 @@
const Array& kNoArgumentNames = Object::null_array();
const int kNumArgumentsChecked = 2;
- Label check_identity;
- __ LoadObject(TMP, Object::null_object(), PP);
- __ cmpq(Address(RSP, 0 * kWordSize), TMP);
- __ j(EQUAL, &check_identity);
- __ cmpq(Address(RSP, 1 * kWordSize), TMP);
- __ j(EQUAL, &check_identity);
-
ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw());
if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
ASSERT(!original_ic_data.IsNull());
@@ -486,43 +479,10 @@
kNoArgumentNames,
locs,
equality_ic_data);
- Label check_ne;
- __ jmp(&check_ne);
-
- __ Bind(&check_identity);
- Label equality_done;
- if (compiler->is_optimizing()) {
- // No need to update IC data.
- Label is_true;
- __ popq(RAX);
- __ popq(RDX);
- __ cmpq(RAX, RDX);
- __ j(EQUAL, &is_true);
- __ LoadObject(RAX, Bool::Get(kind != Token::kEQ), PP);
- __ jmp(&equality_done);
- __ Bind(&is_true);
- __ LoadObject(RAX, Bool::Get(kind == Token::kEQ), PP);
- if (kind == Token::kNE) {
- // Skip not-equal result conversion.
- __ jmp(&equality_done);
- }
- } else {
- // Call stub, load IC data in register. The stub will update ICData if
- // necessary.
- Register ic_data_reg = locs->temp(0).reg();
- ASSERT(ic_data_reg == RBX); // Stub depends on it.
- __ LoadObject(ic_data_reg, equality_ic_data, PP);
- compiler->GenerateCall(token_pos,
- &StubCode::EqualityWithNullArgLabel(),
- PcDescriptors::kRuntimeCall,
- locs);
- __ Drop(2);
- }
- __ Bind(&check_ne);
if (kind == Token::kNE) {
Label true_label, done;
// Negate the condition: true label returns false and vice versa.
- __ CompareObject(RAX, Bool::True());
+ __ CompareObject(RAX, Bool::True(), PP);
__ j(EQUAL, &true_label, Assembler::kNearJump);
__ LoadObject(RAX, Bool::True(), PP);
__ jmp(&done, Assembler::kNearJump);
@@ -530,7 +490,6 @@
__ LoadObject(RAX, Bool::False(), PP);
__ Bind(&done);
}
- __ Bind(&equality_done);
}
@@ -540,7 +499,7 @@
Label* value_is_smi = NULL) {
Label done;
if (value_is_smi == NULL) {
- __ movq(value_cid_reg, Immediate(kSmiCid));
+ __ LoadImmediate(value_cid_reg, Immediate(kSmiCid), PP);
}
__ testq(value_reg, Immediate(kSmiTagMask));
if (value_is_smi == NULL) {
@@ -579,7 +538,7 @@
// Assert that the Smi is at position 0, if at all.
ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0));
Label next_test;
- __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
+ __ CompareImmediate(temp, Immediate(ic_data.GetReceiverClassIdAt(i)), PP);
if (i < len - 1) {
__ j(NOT_EQUAL, &next_test);
} else {
@@ -614,7 +573,7 @@
if (branch == NULL) {
if (kind == Token::kNE) {
Label false_label;
- __ CompareObject(RAX, Bool::True());
+ __ CompareObject(RAX, Bool::True(), PP);
__ j(EQUAL, &false_label, Assembler::kNearJump);
__ LoadObject(RAX, Bool::True(), PP);
__ jmp(&done);
@@ -625,7 +584,7 @@
if (branch->is_checked()) {
EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler);
}
- __ CompareObject(RAX, Bool::True());
+ __ CompareObject(RAX, Bool::True(), PP);
branch->EmitBranchOnCondition(compiler, cond);
}
}
@@ -655,16 +614,16 @@
// 'left' is not Smi.
Label identity_compare;
- __ CompareObject(right, Object::null_object());
+ __ CompareObject(right, Object::null_object(), PP);
__ j(EQUAL, &identity_compare);
- __ CompareObject(left, Object::null_object());
+ __ CompareObject(left, Object::null_object(), PP);
__ j(EQUAL, &identity_compare);
__ LoadClassId(temp, left);
const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
const intptr_t len = ic_data.NumberOfChecks();
for (intptr_t i = 0; i < len; i++) {
- __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
+ __ CompareImmediate(temp, Immediate(ic_data.GetReceiverClassIdAt(i)), PP);
if (i == (len - 1)) {
__ j(NOT_EQUAL, deopt);
} else {
@@ -704,34 +663,10 @@
ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
Register left = locs->in(0).reg();
Register right = locs->in(1).reg();
-
- Label done, identity_compare, non_null_compare;
- __ CompareObject(right, Object::null_object());
- __ j(EQUAL, &identity_compare, Assembler::kNearJump);
- __ CompareObject(left, Object::null_object());
- __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
- // Comparison with NULL is "===".
- __ Bind(&identity_compare);
- __ cmpq(left, right);
- Condition cond = TokenKindToSmiCondition(kind);
- if (branch != NULL) {
- branch->EmitBranchOnCondition(compiler, cond);
- } else {
- Register result = locs->out().reg();
- Label load_true;
- __ j(cond, &load_true, Assembler::kNearJump);
- __ LoadObject(result, Bool::False(), PP);
- __ jmp(&done);
- __ Bind(&load_true);
- __ LoadObject(result, Bool::True(), PP);
- }
- __ jmp(&done);
- __ Bind(&non_null_compare); // Receiver is not null.
__ pushq(left);
__ pushq(right);
EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
deopt_id, token_pos);
- __ Bind(&done);
}
@@ -765,10 +700,10 @@
Condition true_condition = TokenKindToSmiCondition(kind);
if (left.IsConstant()) {
- __ CompareObject(right.reg(), left.constant());
+ __ CompareObject(right.reg(), left.constant(), PP);
true_condition = FlipCondition(true_condition);
} else if (right.IsConstant()) {
- __ CompareObject(left.reg(), right.constant());
+ __ CompareObject(left.reg(), right.constant(), PP);
} else if (right.IsStackSlot()) {
__ cmpq(left.reg(), right.ToStackSlotAddress());
} else {
@@ -897,7 +832,7 @@
EmitAssertBoolean(RAX, token_pos(), deopt_id(), locs(), compiler);
}
Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
- __ CompareObject(RAX, Bool::True());
+ __ CompareObject(RAX, Bool::True(), PP);
branch->EmitBranchOnCondition(compiler, branch_condition);
}
@@ -968,7 +903,7 @@
Register result = locs()->out().reg();
// Push the result place holder initialized to NULL.
- __ PushObject(Object::ZoneHandle());
+ __ PushObject(Object::ZoneHandle(), PP);
// Pass a pointer to the first argument in RAX.
if (!function().HasOptionalParameters()) {
__ leaq(RAX, Address(RBP, (kParamEndSlotFromFp +
@@ -977,8 +912,10 @@
__ leaq(RAX,
Address(RBP, kFirstLocalSlotFromFp * kWordSize));
}
- __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function())));
- __ movq(R10, Immediate(NativeArguments::ComputeArgcTag(function())));
+ __ LoadImmediate(
+ RBX, Immediate(reinterpret_cast<uword>(native_c_function())), PP);
+ __ LoadImmediate(
+ R10, Immediate(NativeArguments::ComputeArgcTag(function())), PP);
const ExternalLabel* stub_entry =
(is_bootstrap_native()) ? &StubCode::CallBootstrapCFunctionLabel() :
&StubCode::CallNativeCFunctionLabel();
@@ -1014,8 +951,8 @@
void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register char_code = locs()->in(0).reg();
Register result = locs()->out().reg();
- __ movq(result,
- Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
+ __ LoadImmediate(result,
+ Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())), PP);
__ movq(result, Address(result,
char_code,
TIMES_HALF_WORD_SIZE, // Char code is a smi.
@@ -1052,7 +989,7 @@
Label load, done;
__ testq(object, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &load, Assembler::kNearJump);
- __ movq(result, Immediate(Smi::RawValue(kSmiCid)));
+ __ LoadImmediate(result, Immediate(Smi::RawValue(kSmiCid)), PP);
__ jmp(&done);
__ Bind(&load);
__ LoadClassId(result, object);
@@ -1360,7 +1297,7 @@
__ StoreIntoObject(array, element_address, value);
} else if (locs()->in(2).IsConstant()) {
const Object& constant = locs()->in(2).constant();
- __ StoreObject(element_address, constant);
+ __ StoreObject(element_address, constant, PP);
} else {
Register value = locs()->in(2).reg();
__ StoreIntoObjectNoBarrier(array, element_address, value);
@@ -1397,14 +1334,14 @@
ASSERT(locs()->in(2).reg() == RAX);
Label store_value, store_0xff;
__ SmiUntag(RAX);
- __ cmpq(RAX, Immediate(0xFF));
+ __ CompareImmediate(RAX, Immediate(0xFF), PP);
__ j(BELOW_EQUAL, &store_value, Assembler::kNearJump);
// Clamp to 0x0 or 0xFF respectively.
__ j(GREATER, &store_0xff);
__ xorq(RAX, RAX);
__ jmp(&store_value, Assembler::kNearJump);
__ Bind(&store_0xff);
- __ movq(RAX, Immediate(0xFF));
+ __ LoadImmediate(RAX, Immediate(0xFF), PP);
__ Bind(&store_value);
__ movb(element_address, RAX);
}
@@ -1538,13 +1475,15 @@
__ pushq(value_cid_reg);
__ movq(value_cid_reg,
FieldAddress(value_reg, Array::length_offset()));
- __ cmpq(value_cid_reg, Immediate(Smi::RawValue(field_length)));
+ __ CompareImmediate(
+ value_cid_reg, Immediate(Smi::RawValue(field_length)), PP);
__ popq(value_cid_reg);
} else if (RawObject::IsTypedDataClassId(field_cid)) {
__ pushq(value_cid_reg);
__ movq(value_cid_reg,
FieldAddress(value_reg, TypedData::length_offset()));
- __ cmpq(value_cid_reg, Immediate(Smi::RawValue(field_length)));
+ __ CompareImmediate(
+ value_cid_reg, Immediate(Smi::RawValue(field_length)), PP);
__ popq(value_cid_reg);
} else {
ASSERT(field_cid == kIllegalCid);
@@ -1558,15 +1497,18 @@
// If length is negative the length guard is either disabled or
// has not been initialized, either way it is safe to skip the
// length check.
- __ cmpq(field_length_operand, Immediate(Smi::RawValue(0)));
+ __ CompareImmediate(
+ field_length_operand, Immediate(Smi::RawValue(0)), PP);
__ j(LESS, &skip_length_check);
- __ cmpq(value_cid_reg, Immediate(kNullCid));
+ __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP);
__ j(EQUAL, &no_fixed_length, Assembler::kNearJump);
// Check for typed data array.
- __ cmpq(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
+ __ CompareImmediate(
+ value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid), PP);
// Not a typed array or a regular array.
__ j(GREATER, &no_fixed_length, Assembler::kNearJump);
- __ cmpq(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
+ __ CompareImmediate(
+ value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP);
// Could still be a regular array.
__ j(LESS, &check_array, Assembler::kNearJump);
__ pushq(value_cid_reg);
@@ -1577,9 +1519,9 @@
__ jmp(&length_compared, Assembler::kNearJump);
// Check for regular array.
__ Bind(&check_array);
- __ cmpq(value_cid_reg, Immediate(kImmutableArrayCid));
+ __ CompareImmediate(value_cid_reg, Immediate(kImmutableArrayCid), PP);
__ j(GREATER, &no_fixed_length, Assembler::kNearJump);
- __ cmpq(value_cid_reg, Immediate(kArrayCid));
+ __ CompareImmediate(value_cid_reg, Immediate(kArrayCid), PP);
__ j(LESS, &no_fixed_length, Assembler::kNearJump);
__ pushq(value_cid_reg);
__ movq(value_cid_reg,
@@ -1596,21 +1538,22 @@
__ Bind(&skip_length_check);
__ cmpq(value_cid_reg, field_nullability_operand);
} else if (value_cid == kNullCid) {
- __ cmpq(field_nullability_operand, Immediate(value_cid));
+ __ CompareImmediate(field_nullability_operand, Immediate(value_cid), PP);
} else {
Label skip_length_check;
- __ cmpq(field_cid_operand, Immediate(value_cid));
+ __ CompareImmediate(field_cid_operand, Immediate(value_cid), PP);
// If not equal, skip over length check.
__ j(NOT_EQUAL, &skip_length_check);
// Insert length check.
if (field_has_length) {
ASSERT(value_cid_reg != kNoRegister);
if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
- __ cmpq(FieldAddress(value_reg, Array::length_offset()),
- Immediate(Smi::RawValue(field_length)));
+ __ CompareImmediate(FieldAddress(value_reg, Array::length_offset()),
+ Immediate(Smi::RawValue(field_length)), PP);
} else if (RawObject::IsTypedDataClassId(value_cid)) {
- __ cmpq(FieldAddress(value_reg, TypedData::length_offset()),
- Immediate(Smi::RawValue(field_length)));
+ __ CompareImmediate(
+ FieldAddress(value_reg, TypedData::length_offset()),
+ Immediate(Smi::RawValue(field_length)), PP);
} else if (field_cid != kIllegalCid) {
ASSERT(field_cid != value_cid);
ASSERT(field_length >= 0);
@@ -1629,7 +1572,7 @@
}
__ j(EQUAL, &ok);
- __ cmpq(field_cid_operand, Immediate(kIllegalCid));
+ __ CompareImmediate(field_cid_operand, Immediate(kIllegalCid), PP);
__ j(NOT_EQUAL, fail);
if (value_cid == kDynamicCid) {
@@ -1637,13 +1580,15 @@
__ movq(field_nullability_operand, value_cid_reg);
if (field_has_length) {
Label check_array, length_set, no_fixed_length;
- __ cmpq(value_cid_reg, Immediate(kNullCid));
+ __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP);
__ j(EQUAL, &no_fixed_length, Assembler::kNearJump);
// Check for typed data array.
- __ cmpq(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
+ __ CompareImmediate(value_cid_reg,
+ Immediate(kTypedDataFloat32x4ArrayCid), PP);
// Not a typed array or a regular array.
__ j(GREATER, &no_fixed_length);
- __ cmpq(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
+ __ CompareImmediate(
+ value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP);
// Could still be a regular array.
__ j(LESS, &check_array, Assembler::kNearJump);
// Destroy value_cid_reg (safe because we are finished with it).
@@ -1654,9 +1599,9 @@
__ jmp(&length_set);
// Check for regular array.
__ Bind(&check_array);
- __ cmpq(value_cid_reg, Immediate(kImmutableArrayCid));
+ __ CompareImmediate(value_cid_reg, Immediate(kImmutableArrayCid), PP);
__ j(GREATER, &no_fixed_length, Assembler::kNearJump);
- __ cmpq(value_cid_reg, Immediate(kArrayCid));
+ __ CompareImmediate(value_cid_reg, Immediate(kArrayCid), PP);
__ j(LESS, &no_fixed_length, Assembler::kNearJump);
// Destroy value_cid_reg (safe because we are finished with it).
__ movq(value_cid_reg,
@@ -1665,14 +1610,14 @@
// Updated field length from regular array.
__ jmp(&length_set, Assembler::kNearJump);
__ Bind(&no_fixed_length);
- __ movq(field_length_operand,
- Immediate(Smi::RawValue(Field::kNoFixedLength)));
+ __ LoadImmediate(field_length_operand,
+ Immediate(Smi::RawValue(Field::kNoFixedLength)), PP);
__ Bind(&length_set);
}
} else {
ASSERT(field_reg != kNoRegister);
- __ movq(field_cid_operand, Immediate(value_cid));
- __ movq(field_nullability_operand, Immediate(value_cid));
+ __ LoadImmediate(field_cid_operand, Immediate(value_cid), PP);
+ __ LoadImmediate(field_nullability_operand, Immediate(value_cid), PP);
if (field_has_length) {
ASSERT(value_cid_reg != kNoRegister);
if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
@@ -1686,8 +1631,8 @@
FieldAddress(value_reg, TypedData::length_offset()));
__ movq(field_length_operand, value_cid_reg);
} else {
- __ movq(field_length_operand,
- Immediate(Smi::RawValue(Field::kNoFixedLength)));
+ __ LoadImmediate(field_length_operand,
+ Immediate(Smi::RawValue(Field::kNoFixedLength)), PP);
}
}
}
@@ -1706,7 +1651,7 @@
if (field_cid != kSmiCid) {
__ j(ZERO, fail);
__ LoadClassId(value_cid_reg, value_reg);
- __ cmpq(value_cid_reg, Immediate(field_cid));
+ __ CompareImmediate(value_cid_reg, Immediate(field_cid), PP);
}
if (field_has_length) {
@@ -1732,7 +1677,7 @@
if (field().is_nullable() && (field_cid != kNullCid)) {
__ j(EQUAL, &ok);
- __ CompareObject(value_reg, Object::null_object());
+ __ CompareObject(value_reg, Object::null_object(), PP);
}
if (ok_is_fall_through) {
@@ -1757,7 +1702,8 @@
__ movq(value_cid_reg,
FieldAddress(value_reg, TypedData::length_offset()));
}
- __ cmpq(value_cid_reg, Immediate(Smi::RawValue(field_length)));
+ __ CompareImmediate(
+ value_cid_reg, Immediate(Smi::RawValue(field_length)), PP);
if (ok_is_fall_through) {
__ j(NOT_EQUAL, fail);
}
@@ -1773,8 +1719,8 @@
ASSERT(!compiler->is_optimizing());
__ Bind(fail);
- __ cmpq(FieldAddress(field_reg, Field::guarded_cid_offset()),
- Immediate(kDynamicCid));
+ __ CompareImmediate(FieldAddress(field_reg, Field::guarded_cid_offset()),
+ Immediate(kDynamicCid), PP);
__ j(EQUAL, &ok);
__ pushq(field_reg);
@@ -1811,7 +1757,7 @@
} else {
if (locs()->in(1).IsConstant()) {
__ StoreObject(FieldAddress(instance_reg, field().Offset()),
- locs()->in(1).constant());
+ locs()->in(1).constant(), PP);
} else {
Register value_reg = locs()->in(1).reg();
__ StoreIntoObjectNoBarrier(instance_reg,
@@ -1909,7 +1855,7 @@
void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
// Allocate the array. R10 = length, RBX = element type.
ASSERT(locs()->in(0).reg() == RBX);
- __ movq(R10, Immediate(Smi::RawValue(num_elements())));
+ __ LoadImmediate(R10, Immediate(Smi::RawValue(num_elements())), PP);
compiler->GenerateCall(token_pos(),
&StubCode::AllocateArrayLabel(),
PcDescriptors::kOther,
@@ -1970,8 +1916,8 @@
// 'instantiator_reg' is the instantiator AbstractTypeArguments object
// (or null).
// A runtime call to instantiate the type is required.
- __ PushObject(Object::ZoneHandle()); // Make room for the result.
- __ PushObject(type());
+ __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
+ __ PushObject(type(), PP);
__ pushq(instantiator_reg); // Push instantiator type arguments.
compiler->GenerateCallRuntime(token_pos(),
deopt_id(),
@@ -2011,13 +1957,13 @@
Label type_arguments_instantiated;
const intptr_t len = type_arguments().Length();
if (type_arguments().IsRawInstantiatedRaw(len)) {
- __ CompareObject(instantiator_reg, Object::null_object());
+ __ CompareObject(instantiator_reg, Object::null_object(), PP);
__ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
}
// Instantiate non-null type arguments.
// A runtime call to instantiate the type arguments is required.
- __ PushObject(Object::ZoneHandle()); // Make room for the result.
- __ PushObject(type_arguments());
+ __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
+ __ PushObject(type_arguments(), PP);
__ pushq(instantiator_reg); // Push instantiator type arguments.
compiler->GenerateCallRuntime(token_pos(),
deopt_id(),
@@ -2060,7 +2006,7 @@
Label type_arguments_instantiated;
ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
- __ CompareObject(instantiator_reg, Object::null_object());
+ __ CompareObject(instantiator_reg, Object::null_object(), PP);
__ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
// Instantiate non-null type arguments.
// In the non-factory case, we rely on the allocation stub to
@@ -2102,12 +2048,12 @@
ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
Label instantiator_not_null;
- __ CompareObject(instantiator_reg, Object::null_object());
+ __ CompareObject(instantiator_reg, Object::null_object(), PP);
__ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
// Null was used in VisitExtractConstructorTypeArguments as the
// instantiated type arguments, no proper instantiator needed.
- __ movq(instantiator_reg,
- Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
+ __ LoadImmediate(instantiator_reg,
+ Immediate(Smi::RawValue(StubCode::kNoInstantiator)), PP);
__ Bind(&instantiator_not_null);
// instantiator_reg: instantiator or kNoInstantiator.
}
@@ -2128,7 +2074,7 @@
ASSERT(locs()->temp(0).reg() == R10);
ASSERT(locs()->out().reg() == RAX);
- __ movq(R10, Immediate(num_context_variables()));
+ __ LoadImmediate(R10, Immediate(num_context_variables()), PP);
const ExternalLabel label("alloc_context",
StubCode::AllocateContextEntryPoint());
compiler->GenerateCall(token_pos(),
@@ -2153,7 +2099,7 @@
Register context_value = locs()->in(0).reg();
Register result = locs()->out().reg();
- __ PushObject(Object::ZoneHandle()); // Make room for the result.
+ __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
__ pushq(context_value);
compiler->GenerateCallRuntime(token_pos(),
deopt_id(),
@@ -2255,7 +2201,8 @@
Register temp = locs()->temp(0).reg();
// Generate stack overflow check.
- __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
+ __ LoadImmediate(
+ temp, Immediate(Isolate::Current()->stack_limit_address()), PP);
__ cmpq(RSP, Address(temp, 0));
__ j(BELOW_EQUAL, slow_path->entry_label());
if (compiler->CanOSRFunction() && in_loop()) {
@@ -2265,8 +2212,8 @@
__ LoadObject(temp, compiler->parsed_function().function(), PP);
intptr_t threshold =
FLAG_optimization_counter_threshold * (loop_depth() + 1);
- __ cmpq(FieldAddress(temp, Function::usage_counter_offset()),
- Immediate(threshold));
+ __ CompareImmediate(FieldAddress(temp, Function::usage_counter_offset()),
+ Immediate(threshold), PP);
__ j(GREATER_EQUAL, slow_path->entry_label());
}
__ Bind(slow_path->exit_label());
@@ -2279,9 +2226,9 @@
Register result) {
if (!range->IsWithin(-0x20000000000000LL, 0x20000000000000LL)) {
ASSERT(overflow != NULL);
- __ cmpq(result, Immediate(-0x20000000000000LL));
+ __ CompareImmediate(result, Immediate(-0x20000000000000LL), PP);
__ j(LESS, overflow);
- __ cmpq(result, Immediate(0x20000000000000LL));
+ __ CompareImmediate(result, Immediate(0x20000000000000LL), PP);
__ j(GREATER, overflow);
}
}
@@ -2342,7 +2289,7 @@
if (obj.IsSmi()) {
const intptr_t left_int = Smi::Cast(obj).Value();
if (left_int == 0) {
- __ cmpq(right, Immediate(0));
+ __ CompareImmediate(right, Immediate(0), PP);
__ j(NEGATIVE, deopt);
return;
}
@@ -2351,8 +2298,8 @@
(right_range == NULL) ||
!right_range->IsWithin(0, max_right - 1);
if (right_needs_check) {
- __ cmpq(right,
- Immediate(reinterpret_cast<int64_t>(Smi::New(max_right))));
+ __ CompareImmediate(right,
+ Immediate(reinterpret_cast<int64_t>(Smi::New(max_right))), PP);
__ j(ABOVE_EQUAL, deopt);
}
__ SmiUntag(right);
@@ -2374,12 +2321,12 @@
!right_range->IsWithin(0, RangeBoundary::kPlusInfinity);
if (right_may_be_negative) {
ASSERT(shift_left->CanDeoptimize());
- __ cmpq(right, Immediate(0));
+ __ CompareImmediate(right, Immediate(0), PP);
__ j(NEGATIVE, deopt);
}
Label done, is_not_zero;
- __ cmpq(right,
- Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
+ __ CompareImmediate(right,
+ Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))), PP);
__ j(BELOW, &is_not_zero, Assembler::kNearJump);
__ xorq(left, left);
__ jmp(&done, Assembler::kNearJump);
@@ -2394,8 +2341,8 @@
} else {
if (right_needs_check) {
ASSERT(shift_left->CanDeoptimize());
- __ cmpq(right,
- Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
+ __ CompareImmediate(right,
+ Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))), PP);
__ j(ABOVE_EQUAL, deopt);
}
// Left is not a constant.
@@ -2518,12 +2465,12 @@
reinterpret_cast<int64_t>(constant.raw());
switch (op_kind()) {
case Token::kADD: {
- __ addq(left, Immediate(imm));
+ __ AddImmediate(left, Immediate(imm), PP);
if (deopt != NULL) __ j(OVERFLOW, deopt);
break;
}
case Token::kSUB: {
- __ subq(left, Immediate(imm));
+ __ AddImmediate(left, Immediate(-imm), PP);
if (deopt != NULL) __ j(OVERFLOW, deopt);
break;
}
@@ -2533,7 +2480,7 @@
if (value == 2) {
__ shlq(left, Immediate(1));
} else {
- __ imulq(left, Immediate(value));
+ __ MulImmediate(left, Immediate(value), PP);
}
if (deopt != NULL) __ j(OVERFLOW, deopt);
break;
@@ -2546,7 +2493,7 @@
} else if (value == -1) {
// Check the corner case of dividing the 'MIN_SMI' with -1, in which
// case we cannot negate the result.
- __ cmpq(left, Immediate(0x8000000000000000));
+ __ CompareImmediate(left, Immediate(0x8000000000000000), PP);
__ j(EQUAL, deopt);
__ negq(left);
break;
@@ -2572,17 +2519,17 @@
}
case Token::kBIT_AND: {
// No overflow check.
- __ andq(left, Immediate(imm));
+ __ AndImmediate(left, Immediate(imm), PP);
break;
}
case Token::kBIT_OR: {
// No overflow check.
- __ orq(left, Immediate(imm));
+ __ OrImmediate(left, Immediate(imm), PP);
break;
}
case Token::kBIT_XOR: {
// No overflow check.
- __ xorq(left, Immediate(imm));
+ __ XorImmediate(left, Immediate(imm), PP);
break;
}
@@ -2738,7 +2685,7 @@
__ idivq(right); // RAX: quotient, RDX: remainder.
// Check the corner case of dividing the 'MIN_SMI' with -1, in which
// case we cannot tag the result.
- __ cmpq(result, Immediate(0x4000000000000000));
+ __ CompareImmediate(result, Immediate(0x4000000000000000), PP);
__ j(EQUAL, deopt);
__ Bind(&done);
__ SmiTag(result);
@@ -2746,7 +2693,7 @@
}
case Token::kSHR: {
if (CanDeoptimize()) {
- __ cmpq(right, Immediate(0));
+ __ CompareImmediate(right, Immediate(0), PP);
__ j(LESS, deopt);
}
__ SmiUntag(right);
@@ -2755,10 +2702,10 @@
Range* right_range = this->right()->definition()->range();
if ((right_range == NULL) ||
!right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
- __ cmpq(right, Immediate(kCountLimit));
+ __ CompareImmediate(right, Immediate(kCountLimit), PP);
Label count_ok;
__ j(LESS, &count_ok, Assembler::kNearJump);
- __ movq(right, Immediate(kCountLimit));
+ __ LoadImmediate(right, Immediate(kCountLimit), PP);
__ Bind(&count_ok);
}
ASSERT(right == RCX); // Count must be in RCX
@@ -2886,7 +2833,8 @@
__ TryAllocate(compiler->double_class(),
slow_path->entry_label(),
Assembler::kFarJump,
- out_reg);
+ out_reg,
+ PP);
__ Bind(slow_path->exit_label());
__ movsd(FieldAddress(out_reg, Double::value_offset()), value);
}
@@ -2988,7 +2936,8 @@
__ TryAllocate(compiler->float32x4_class(),
slow_path->entry_label(),
Assembler::kFarJump,
- out_reg);
+ out_reg,
+ PP);
__ Bind(slow_path->exit_label());
__ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
}
@@ -3073,7 +3022,8 @@
__ TryAllocate(compiler->uint32x4_class(),
slow_path->entry_label(),
Assembler::kFarJump,
- out_reg);
+ out_reg,
+ PP);
__ Bind(slow_path->exit_label());
__ movups(FieldAddress(out_reg, Uint32x4::value_offset()), value);
}
@@ -3243,7 +3193,7 @@
XmmRegister v2 = locs()->in(2).fpu_reg();
XmmRegister v3 = locs()->in(3).fpu_reg();
ASSERT(v0 == locs()->out().fpu_reg());
- __ subq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(-16), PP);
__ cvtsd2ss(v0, v0);
__ movss(Address(RSP, 0), v0);
__ movsd(v0, v1);
@@ -3256,7 +3206,7 @@
__ cvtsd2ss(v0, v0);
__ movss(Address(RSP, 12), v0);
__ movups(v0, Address(RSP, 0));
- __ addq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(16), PP);
}
@@ -3501,47 +3451,47 @@
switch (op_kind()) {
case MethodRecognizer::kFloat32x4WithX:
__ cvtsd2ss(replacement, replacement);
- __ subq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(-16), PP);
// Move value to stack.
__ movups(Address(RSP, 0), value);
// Write over X value.
__ movss(Address(RSP, 0), replacement);
// Move updated value into output register.
__ movups(replacement, Address(RSP, 0));
- __ addq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(16), PP);
break;
case MethodRecognizer::kFloat32x4WithY:
__ cvtsd2ss(replacement, replacement);
- __ subq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(-16), PP);
// Move value to stack.
__ movups(Address(RSP, 0), value);
// Write over Y value.
__ movss(Address(RSP, 4), replacement);
// Move updated value into output register.
__ movups(replacement, Address(RSP, 0));
- __ addq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(16), PP);
break;
case MethodRecognizer::kFloat32x4WithZ:
__ cvtsd2ss(replacement, replacement);
- __ subq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(-16), PP);
// Move value to stack.
__ movups(Address(RSP, 0), value);
// Write over Z value.
__ movss(Address(RSP, 8), replacement);
// Move updated value into output register.
__ movups(replacement, Address(RSP, 0));
- __ addq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(16), PP);
break;
case MethodRecognizer::kFloat32x4WithW:
__ cvtsd2ss(replacement, replacement);
- __ subq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(-16), PP);
// Move value to stack.
__ movups(Address(RSP, 0), value);
// Write over W value.
__ movss(Address(RSP, 12), replacement);
// Move updated value into output register.
__ movups(replacement, Address(RSP, 0));
- __ addq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(16), PP);
break;
default: UNREACHABLE();
}
@@ -3629,46 +3579,46 @@
Label y_false, y_done;
Label z_false, z_done;
Label w_false, w_done;
- __ subq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(-16), PP);
- __ CompareObject(v0, Bool::True());
+ __ CompareObject(v0, Bool::True(), PP);
__ j(NOT_EQUAL, &x_false);
- __ movq(temp, Immediate(0xFFFFFFFF));
+ __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
__ jmp(&x_done);
__ Bind(&x_false);
- __ movq(temp, Immediate(0x0));
+ __ LoadImmediate(temp, Immediate(0x0), PP);
__ Bind(&x_done);
__ movl(Address(RSP, 0), temp);
- __ CompareObject(v1, Bool::True());
+ __ CompareObject(v1, Bool::True(), PP);
__ j(NOT_EQUAL, &y_false);
- __ movq(temp, Immediate(0xFFFFFFFF));
+ __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
__ jmp(&y_done);
__ Bind(&y_false);
- __ movq(temp, Immediate(0x0));
+ __ LoadImmediate(temp, Immediate(0x0), PP);
__ Bind(&y_done);
__ movl(Address(RSP, 4), temp);
- __ CompareObject(v2, Bool::True());
+ __ CompareObject(v2, Bool::True(), PP);
__ j(NOT_EQUAL, &z_false);
- __ movq(temp, Immediate(0xFFFFFFFF));
+ __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
__ jmp(&z_done);
__ Bind(&z_false);
- __ movq(temp, Immediate(0x0));
+ __ LoadImmediate(temp, Immediate(0x0), PP);
__ Bind(&z_done);
__ movl(Address(RSP, 8), temp);
- __ CompareObject(v3, Bool::True());
+ __ CompareObject(v3, Bool::True(), PP);
__ j(NOT_EQUAL, &w_false);
- __ movq(temp, Immediate(0xFFFFFFFF));
+ __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
__ jmp(&w_done);
__ Bind(&w_false);
- __ movq(temp, Immediate(0x0));
+ __ LoadImmediate(temp, Immediate(0x0), PP);
__ Bind(&w_done);
__ movl(Address(RSP, 12), temp);
__ movups(result, Address(RSP, 0));
- __ addq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(16), PP);
}
@@ -3688,7 +3638,7 @@
Register result = locs()->out().reg();
Label done;
Label non_zero;
- __ subq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(-16), PP);
// Move value to stack.
__ movups(Address(RSP, 0), value);
switch (op_kind()) {
@@ -3706,7 +3656,7 @@
break;
default: UNREACHABLE();
}
- __ addq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(16), PP);
__ testl(result, result);
__ j(NOT_ZERO, &non_zero, Assembler::kNearJump);
__ LoadObject(result, Bool::False(), PP);
@@ -3769,43 +3719,43 @@
Register flag = locs()->in(1).reg();
Register temp = locs()->temp(0).reg();
ASSERT(mask == locs()->out().fpu_reg());
- __ subq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(-16), PP);
// Copy mask to stack.
__ movups(Address(RSP, 0), mask);
Label falsePath, exitPath;
- __ CompareObject(flag, Bool::True());
+ __ CompareObject(flag, Bool::True(), PP);
__ j(NOT_EQUAL, &falsePath);
switch (op_kind()) {
case MethodRecognizer::kUint32x4WithFlagX:
- __ movq(temp, Immediate(0xFFFFFFFF));
+ __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
__ movl(Address(RSP, 0), temp);
__ jmp(&exitPath);
__ Bind(&falsePath);
- __ movq(temp, Immediate(0x0));
+ __ LoadImmediate(temp, Immediate(0x0), PP);
__ movl(Address(RSP, 0), temp);
break;
case MethodRecognizer::kUint32x4WithFlagY:
- __ movq(temp, Immediate(0xFFFFFFFF));
+ __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
__ movl(Address(RSP, 4), temp);
__ jmp(&exitPath);
__ Bind(&falsePath);
- __ movq(temp, Immediate(0x0));
+ __ LoadImmediate(temp, Immediate(0x0), PP);
__ movl(Address(RSP, 4), temp);
break;
case MethodRecognizer::kUint32x4WithFlagZ:
- __ movq(temp, Immediate(0xFFFFFFFF));
+ __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
__ movl(Address(RSP, 8), temp);
__ jmp(&exitPath);
__ Bind(&falsePath);
- __ movq(temp, Immediate(0x0));
+ __ LoadImmediate(temp, Immediate(0x0), PP);
__ movl(Address(RSP, 8), temp);
break;
case MethodRecognizer::kUint32x4WithFlagW:
- __ movq(temp, Immediate(0xFFFFFFFF));
+ __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
__ movl(Address(RSP, 12), temp);
__ jmp(&exitPath);
__ Bind(&falsePath);
- __ movq(temp, Immediate(0x0));
+ __ LoadImmediate(temp, Immediate(0x0), PP);
__ movl(Address(RSP, 12), temp);
break;
default: UNREACHABLE();
@@ -3813,7 +3763,7 @@
__ Bind(&exitPath);
// Copy mask back to register.
__ movups(mask, Address(RSP, 0));
- __ addq(RSP, Immediate(16));
+ __ AddImmediate(RSP, Immediate(16), PP);
}
@@ -3936,7 +3886,8 @@
}
case Token::kBIT_NOT:
__ notq(value);
- __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
+ // Remove inverted smi-tag.
+ __ AndImmediate(value, Immediate(~kSmiTagMask), PP);
break;
default:
UNREACHABLE();
@@ -4011,7 +3962,7 @@
__ Bind(&returns_nan);
static double kNaN = NAN;
- __ movq(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN)));
+ __ LoadImmediate(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN)), PP);
__ movsd(result, Address(temp, 0));
__ jmp(&done, Assembler::kNearJump);
@@ -4337,7 +4288,7 @@
Label* deopt = compiler->AddDeoptStub(deopt_id(),
kDeoptCheckClass);
__ CompareObject(locs()->in(0).reg(),
- Object::null_object());
+ Object::null_object(), PP);
__ j(EQUAL, deopt);
return;
}
@@ -4434,12 +4385,14 @@
if (index_loc.IsConstant()) {
Register length = length_loc.reg();
const Smi& index = Smi::Cast(index_loc.constant());
- __ cmpq(length, Immediate(reinterpret_cast<int64_t>(index.raw())));
+ __ CompareImmediate(
+ length, Immediate(reinterpret_cast<int64_t>(index.raw())), PP);
__ j(BELOW_EQUAL, deopt);
} else if (length_loc.IsConstant()) {
const Smi& length = Smi::Cast(length_loc.constant());
Register index = index_loc.reg();
- __ cmpq(index, Immediate(reinterpret_cast<int64_t>(length.raw())));
+ __ CompareImmediate(
+ index, Immediate(reinterpret_cast<int64_t>(length.raw())), PP);
__ j(ABOVE_EQUAL, deopt);
} else {
Register length = length_loc.reg();
@@ -4546,21 +4499,13 @@
void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
if (!compiler->is_optimizing()) {
+ compiler->EmitEdgeCounter();
+ // The deoptimization descriptor points after the edge counter code for
+ // uniformity with ARM and MIPS, where we can reuse pattern matching
+ // code that matches backwards from the end of the pattern.
compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
deopt_id_,
Scanner::kDummyTokenIndex);
- // Add an edge counter.
- const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
- counter.SetAt(0, Smi::Handle(Smi::New(0)));
- Label done;
- __ Comment("Edge counter");
- __ LoadObject(RAX, counter, PP);
- __ addq(FieldAddress(RAX, Array::element_offset(0)),
- Immediate(Smi::RawValue(1)));
- __ j(NO_OVERFLOW, &done);
- __ movq(FieldAddress(RAX, Array::element_offset(0)),
- Immediate(Smi::RawValue(Smi::kMaxValue)));
- __ Bind(&done);
}
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -4575,23 +4520,15 @@
void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
if (!compiler->is_optimizing()) {
- // Add deoptimization descriptor for deoptimizing instructions that may
- // be inserted before this instruction.
+ compiler->EmitEdgeCounter();
+ // Add a deoptimization descriptor for deoptimizing instructions that
+ // may be inserted before this instruction. This descriptor points
+ // after the edge counter for uniformity with ARM and MIPS, where we can
+ // reuse pattern matching that matches backwards from the end of the
+ // pattern.
compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
GetDeoptId(),
- 0); // No token position.
- // Add an edge counter.
- const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
- counter.SetAt(0, Smi::Handle(Smi::New(0)));
- Label done;
- __ Comment("Edge counter");
- __ LoadObject(RAX, counter, PP);
- __ addq(FieldAddress(RAX, Array::element_offset(0)),
- Immediate(Smi::RawValue(1)));
- __ j(NO_OVERFLOW, &done);
- __ movq(FieldAddress(RAX, Array::element_offset(0)),
- Immediate(Smi::RawValue(Smi::kMaxValue)));
- __ Bind(&done);
+ Scanner::kDummyTokenIndex);
}
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index e7edd62..fa3992b 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -69,7 +69,7 @@
// the class matches and the rest of the method name starting with
// the dot matches, we have found a match.
// We do not store the entire factory constructor name with the class
- // (e.g: _GrowableObjectArray.withData) because the actual function name
+ // (e.g: _GrowableList.withData) because the actual function name
// that we see here includes the private key.
if (test_function_name[0] == '.') {
function_name = strstr(function_name, ".");
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index de6d92e..e5d4dd2 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -31,20 +31,20 @@
V(_Double, get:isNegative, Double_getIsNegative, 1711391869) \
V(_Double, _mulFromInteger, Double_mulFromInteger, 1238321808) \
V(_Double, .fromInteger, Double_fromInteger, 82414734) \
- V(_ObjectArray, ., ObjectArray_Allocate, 1558200848) \
- V(_ObjectArray, get:length, Array_getLength, 259382695) \
- V(_ObjectArray, [], Array_getIndexed, 544020319) \
- V(_ObjectArray, []=, Array_setIndexed, 304306010) \
- V(_GrowableObjectArray, .withData, GrowableArray_Allocate, 619965861) \
- V(_GrowableObjectArray, get:length, GrowableArray_getLength, 1160417196) \
- V(_GrowableObjectArray, get:_capacity, GrowableArray_getCapacity, 1509841570)\
- V(_GrowableObjectArray, [], GrowableArray_getIndexed, 951312767) \
- V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 1366856519) \
- V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 1112774552) \
- V(_GrowableObjectArray, _setData, GrowableArray_setData, 1574432374) \
- V(_GrowableObjectArray, add, GrowableArray_add, 635801182) \
- V(_ImmutableArray, [], ImmutableArray_getIndexed, 1345387065) \
- V(_ImmutableArray, get:length, ImmutableArray_getLength, 1342001998) \
+ V(_List, ., List_Allocate, 1436567945) \
+ V(_List, get:length, Array_getLength, 215153395) \
+ V(_List, [], Array_getIndexed, 1079829188) \
+ V(_List, []=, Array_setIndexed, 748954698) \
+ V(_GrowableList, .withData, GrowableList_Allocate, 461305701) \
+ V(_GrowableList, get:length, GrowableList_getLength, 1654225242) \
+ V(_GrowableList, get:_capacity, GrowableList_getCapacity, 817090003) \
+ V(_GrowableList, [], GrowableList_getIndexed, 1686777561) \
+ V(_GrowableList, []=, GrowableList_setIndexed, 327404102) \
+ V(_GrowableList, _setLength, GrowableList_setLength, 1227678442) \
+ V(_GrowableList, _setData, GrowableList_setData, 1375509957) \
+ V(_GrowableList, add, GrowableList_add, 996912766) \
+ V(_ImmutableList, [], ImmutableList_getIndexed, 25983597) \
+ V(_ImmutableList, get:length, ImmutableList_getLength, 578733070) \
V(Object, ==, Object_equal, 936042315) \
V(_StringBase, get:hashCode, String_getHashCode, 654543028) \
V(_StringBase, get:isEmpty, String_getIsEmpty, 879849436) \
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 734b889..8770677 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -20,7 +20,7 @@
#define __ assembler->
-void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::List_Allocate(Assembler* assembler) {
const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
const intptr_t kArrayLengthOffset = 0 * kWordSize;
Label fall_through;
@@ -133,7 +133,7 @@
}
-void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
return Array_getLength(assembler);
}
@@ -160,7 +160,7 @@
}
-void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
return Array_getIndexed(assembler);
}
@@ -168,7 +168,7 @@
static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
const Library& core_lib = Library::Handle(Library::CoreLibrary());
const Class& cls = Class::Handle(
- core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
+ core_lib.LookupClassAllowPrivate(Symbols::_List()));
ASSERT(!cls.IsNull());
ASSERT(cls.HasTypeArguments());
ASSERT(cls.NumTypeArguments() == 1);
@@ -247,7 +247,7 @@
// Allocate a GrowableObjectArray using the backing array specified.
// On stack: type argument (+1), data (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
// The newly allocated object is returned in R0.
const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
const intptr_t kArrayOffset = 0 * kWordSize;
@@ -313,14 +313,14 @@
}
-void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
__ ldr(R0, Address(SP, 0 * kWordSize));
__ ldr(R0, FieldAddress(R0, GrowableObjectArray::length_offset()));
__ Ret();
}
-void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
__ ldr(R0, Address(SP, 0 * kWordSize));
__ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset()));
__ ldr(R0, FieldAddress(R0, Array::length_offset()));
@@ -328,7 +328,7 @@
}
-void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
Label fall_through;
__ ldr(R0, Address(SP, + 0 * kWordSize)); // Index
@@ -353,7 +353,7 @@
// Set value into growable object array at specified index.
// On stack: growable array (+2), index (+1), value (+0).
-void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return;
}
@@ -383,7 +383,7 @@
// Set length of growable object array. The length cannot
// be greater than the length of the data container.
// On stack: growable array (+1), length (+0).
-void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
__ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array.
__ ldr(R1, Address(SP, 0 * kWordSize)); // Length value.
__ tst(R1, ShifterOperand(kSmiTagMask)); // Check for Smi.
@@ -395,7 +395,7 @@
// Set data of growable object array.
// On stack: growable array (+1), data (+0).
-void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableList_setData(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return;
}
@@ -418,7 +418,7 @@
// Add an element to growable array if it doesn't need to grow, otherwise
// call into regular code.
// On stack: growable array (+1), value (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableList_add(Assembler* assembler) {
// In checked mode we need to type-check the incoming argument.
if (FLAG_enable_type_checks) return;
Label fall_through;
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 64758e6..f9634c8 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -28,7 +28,7 @@
#define __ assembler->
-void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::List_Allocate(Assembler* assembler) {
// This snippet of inlined code uses the following registers:
// EAX, EBX, EDI
// and the newly allocated object is returned in EAX.
@@ -142,7 +142,7 @@
}
-void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
return Array_getLength(assembler);
}
@@ -165,7 +165,7 @@
}
-void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
return Array_getIndexed(assembler);
}
@@ -173,7 +173,7 @@
static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
const Library& core_lib = Library::Handle(Library::CoreLibrary());
const Class& cls = Class::Handle(
- core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
+ core_lib.LookupClassAllowPrivate(Symbols::_List()));
ASSERT(!cls.IsNull());
ASSERT(cls.HasTypeArguments());
ASSERT(cls.NumTypeArguments() == 1);
@@ -245,7 +245,7 @@
// Allocate a GrowableObjectArray using the backing array specified.
// On stack: type argument (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
// This snippet of inlined code uses the following registers:
// EAX, EBX
// and the newly allocated object is returned in EAX.
@@ -312,7 +312,7 @@
// Get length of growable object array.
// On stack: growable array (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
__ movl(EAX, Address(ESP, + 1 * kWordSize));
__ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
__ ret();
@@ -321,7 +321,7 @@
// Get capacity of growable object array.
// On stack: growable array (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
__ movl(EAX, Address(ESP, + 1 * kWordSize));
__ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset()));
__ movl(EAX, FieldAddress(EAX, Array::length_offset()));
@@ -331,7 +331,7 @@
// Access growable object array at specified index.
// On stack: growable array (+2), index (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
Label fall_through;
__ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
__ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray.
@@ -353,7 +353,7 @@
// Set value into growable object array at specified index.
// On stack: growable array (+3), index (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return;
}
@@ -381,7 +381,7 @@
// Set length of growable object array. The length cannot
// be greater than the length of the data container.
// On stack: growable array (+2), length (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
Label fall_through;
__ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array.
__ movl(EBX, Address(ESP, + 1 * kWordSize)); // Length value.
@@ -395,7 +395,7 @@
// Set data of growable object array.
// On stack: growable array (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableList_setData(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return;
}
@@ -418,7 +418,7 @@
// Add an element to growable array if it doesn't need to grow, otherwise
// call into regular code.
// On stack: growable array (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableList_add(Assembler* assembler) {
// In checked mode we need to type-check the incoming argument.
if (FLAG_enable_type_checks) return;
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index de39ced8..3a12f24 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -20,7 +20,7 @@
#define __ assembler->
-void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::List_Allocate(Assembler* assembler) {
const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
const intptr_t kArrayLengthOffset = 0 * kWordSize;
Label fall_through;
@@ -140,7 +140,7 @@
}
-void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
return Array_getLength(assembler);
}
@@ -168,7 +168,7 @@
}
-void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
return Array_getIndexed(assembler);
}
@@ -176,7 +176,7 @@
static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
const Library& core_lib = Library::Handle(Library::CoreLibrary());
const Class& cls = Class::Handle(
- core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
+ core_lib.LookupClassAllowPrivate(Symbols::_List()));
ASSERT(!cls.IsNull());
ASSERT(cls.HasTypeArguments());
ASSERT(cls.NumTypeArguments() == 1);
@@ -252,7 +252,7 @@
// Allocate a GrowableObjectArray using the backing array specified.
// On stack: type argument (+1), data (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
// The newly allocated object is returned in V0.
const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
const intptr_t kArrayOffset = 0 * kWordSize;
@@ -317,7 +317,7 @@
}
-void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
__ lw(V0, Address(SP, 0 * kWordSize));
__ Ret();
__ delay_slot()->lw(V0,
@@ -325,7 +325,7 @@
}
-void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
__ lw(V0, Address(SP, 0 * kWordSize));
__ lw(V0, FieldAddress(V0, GrowableObjectArray::data_offset()));
__ Ret();
@@ -333,7 +333,7 @@
}
-void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
Label fall_through;
__ lw(T0, Address(SP, 0 * kWordSize)); // Index
@@ -360,7 +360,7 @@
// Set value into growable object array at specified index.
// On stack: growable array (+2), index (+1), value (+0).
-void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return;
}
@@ -390,7 +390,7 @@
// Set length of growable object array. The length cannot
// be greater than the length of the data container.
// On stack: growable array (+1), length (+0).
-void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
Label fall_through;
__ lw(T1, Address(SP, 0 * kWordSize)); // Length value.
__ andi(CMPRES, T1, Immediate(kSmiTagMask));
@@ -405,7 +405,7 @@
// Set data of growable object array.
// On stack: growable array (+1), data (+0).
-void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableList_setData(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return;
}
@@ -428,7 +428,7 @@
// Add an element to growable array if it doesn't need to grow, otherwise
// call into regular code.
// On stack: growable array (+1), value (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableList_add(Assembler* assembler) {
// In checked mode we need to type-check the incoming argument.
if (FLAG_enable_type_checks) return;
Label fall_through;
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 83180be..e976fd5 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -27,7 +27,7 @@
#define __ assembler->
-void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::List_Allocate(Assembler* assembler) {
// This snippet of inlined code uses the following registers:
// RAX, RCX, RDI, R13
// and the newly allocated object is returned in RAX.
@@ -141,7 +141,7 @@
}
-void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
return Array_getLength(assembler);
}
@@ -164,7 +164,7 @@
}
-void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
return Array_getIndexed(assembler);
}
@@ -197,7 +197,7 @@
// Allocate a GrowableObjectArray using the backing array specified.
// On stack: type argument (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
// This snippet of inlined code uses the following registers:
// RAX, RCX, R13
// and the newly allocated object is returned in RAX.
@@ -267,14 +267,14 @@
// Get length of growable object array.
// On stack: growable array (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
__ movq(RAX, Address(RSP, + 1 * kWordSize));
__ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
__ ret();
}
-void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
__ movq(RAX, Address(RSP, + 1 * kWordSize));
__ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
__ movq(RAX, FieldAddress(RAX, Array::length_offset()));
@@ -284,7 +284,7 @@
// Access growable object array at specified index.
// On stack: growable array (+2), index (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
Label fall_through;
__ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
__ movq(RAX, Address(RSP, + 2 * kWordSize)); // GrowableArray.
@@ -306,7 +306,7 @@
// Set value into growable object array at specified index.
// On stack: growable array (+3), index (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return;
}
@@ -334,7 +334,7 @@
// Set length of growable object array. The length cannot
// be greater than the length of the data container.
// On stack: growable array (+2), length (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
Label fall_through;
__ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array.
__ movq(RCX, Address(RSP, + 1 * kWordSize)); // Length value.
@@ -348,7 +348,7 @@
// Set data of growable object array.
// On stack: growable array (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableList_setData(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return;
}
@@ -370,7 +370,7 @@
// Add an element to growable array if it doesn't need to grow, otherwise
// call into regular code.
// On stack: growable array (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableList_add(Assembler* assembler) {
// In checked mode we need to check the incoming argument.
if (FLAG_enable_type_checks) return;
Label fall_through;
@@ -1101,7 +1101,8 @@
__ TryAllocate(double_class,
&fall_through,
Assembler::kNearJump,
- RAX); // Result register.
+ RAX, // Result register.
+ kNoRegister); // Pool pointer might not be loaded.
__ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
__ ret();
__ Bind(&fall_through);
@@ -1145,7 +1146,8 @@
__ TryAllocate(double_class,
&fall_through,
Assembler::kNearJump,
- RAX); // Result register.
+ RAX, // Result register.
+ kNoRegister); // Pool pointer might not be loaded.
__ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
__ ret();
__ Bind(&fall_through);
@@ -1166,7 +1168,8 @@
__ TryAllocate(double_class,
&fall_through,
Assembler::kNearJump,
- RAX); // Result register.
+ RAX, // Result register.
+ kNoRegister); // Pool pointer might not be loaded.
__ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
__ ret();
__ Bind(&fall_through);
@@ -1236,7 +1239,8 @@
__ TryAllocate(double_class,
&alloc_failed,
Assembler::kNearJump,
- RAX); // Result register.
+ RAX, // Result register.
+ kNoRegister); // Pool pointer might not be loaded.
__ fstpl(FieldAddress(RAX, Double::value_offset()));
__ ret();
@@ -1283,7 +1287,8 @@
__ TryAllocate(double_class,
&fall_through,
Assembler::kNearJump,
- RAX); // Result register.
+ RAX, // Result register.
+ kNoRegister); // Pool pointer might not be loaded.
__ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
__ ret();
__ Bind(&is_smi);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 5d12dc6..0e6ad03 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -14,6 +14,7 @@
#include "vm/dart_api_state.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
+#include "vm/deopt_instructions.h"
#include "vm/heap.h"
#include "vm/heap_histogram.h"
#include "vm/message_handler.h"
@@ -38,7 +39,6 @@
"Track function usage and report.");
DEFINE_FLAG(bool, trace_isolates, false,
"Trace isolate creation and shut down.");
-DECLARE_FLAG(bool, trace_deoptimization_verbose);
void Isolate::RegisterClass(const Class& cls) {
@@ -270,113 +270,6 @@
#endif
-void DeferredDouble::Materialize() {
- RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot());
- *double_slot = Double::New(value());
-
- if (FLAG_trace_deoptimization_verbose) {
- OS::PrintErr("materializing double at %" Px ": %g\n",
- reinterpret_cast<uword>(slot()), value());
- }
-}
-
-
-void DeferredMint::Materialize() {
- RawMint** mint_slot = reinterpret_cast<RawMint**>(slot());
- ASSERT(!Smi::IsValid64(value()));
- Mint& mint = Mint::Handle();
- mint ^= Integer::New(value());
- *mint_slot = mint.raw();
-
- if (FLAG_trace_deoptimization_verbose) {
- OS::PrintErr("materializing mint at %" Px ": %" Pd64 "\n",
- reinterpret_cast<uword>(slot()), value());
- }
-}
-
-
-void DeferredFloat32x4::Materialize() {
- RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(slot());
- RawFloat32x4* raw_float32x4 = Float32x4::New(value());
- *float32x4_slot = raw_float32x4;
-
- if (FLAG_trace_deoptimization_verbose) {
- float x = raw_float32x4->x();
- float y = raw_float32x4->y();
- float z = raw_float32x4->z();
- float w = raw_float32x4->w();
- OS::PrintErr("materializing Float32x4 at %" Px ": %g,%g,%g,%g\n",
- reinterpret_cast<uword>(slot()), x, y, z, w);
- }
-}
-
-
-void DeferredUint32x4::Materialize() {
- RawUint32x4** uint32x4_slot = reinterpret_cast<RawUint32x4**>(slot());
- RawUint32x4* raw_uint32x4 = Uint32x4::New(value());
- *uint32x4_slot = raw_uint32x4;
-
- if (FLAG_trace_deoptimization_verbose) {
- uint32_t x = raw_uint32x4->x();
- uint32_t y = raw_uint32x4->y();
- uint32_t z = raw_uint32x4->z();
- uint32_t w = raw_uint32x4->w();
- OS::PrintErr("materializing Uint32x4 at %" Px ": %x,%x,%x,%x\n",
- reinterpret_cast<uword>(slot()), x, y, z, w);
- }
-}
-
-
-void DeferredObjectRef::Materialize() {
- DeferredObject* obj = Isolate::Current()->GetDeferredObject(index());
- *slot() = obj->object();
- if (FLAG_trace_deoptimization_verbose) {
- OS::PrintErr("writing instance ref at %" Px ": %s\n",
- reinterpret_cast<uword>(slot()),
- Instance::Handle(obj->object()).ToCString());
- }
-}
-
-
-RawInstance* DeferredObject::object() {
- if (object_ == NULL) {
- Materialize();
- }
- return object_->raw();
-}
-
-
-void DeferredObject::Materialize() {
- Class& cls = Class::Handle();
- cls ^= GetClass();
-
- if (FLAG_trace_deoptimization_verbose) {
- OS::PrintErr("materializing instance of %s (%" Px ", %" Pd " fields)\n",
- cls.ToCString(),
- reinterpret_cast<uword>(args_),
- field_count_);
- }
-
- const Instance& obj = Instance::ZoneHandle(Instance::New(cls));
-
- Field& field = Field::Handle();
- Object& value = Object::Handle();
- for (intptr_t i = 0; i < field_count_; i++) {
- field ^= GetField(i);
- value = GetValue(i);
- obj.SetField(field, value);
-
- if (FLAG_trace_deoptimization_verbose) {
- OS::PrintErr(" %s <- %s\n",
- String::Handle(field.name()).ToCString(),
- value.ToCString());
- }
- }
-
- object_ = &obj;
-}
-
-
#define REUSABLE_HANDLE_INITIALIZERS(object) \
object##_handle_(NULL),
@@ -409,14 +302,7 @@
gc_prologue_callbacks_(),
gc_epilogue_callbacks_(),
defer_finalization_count_(0),
- deopt_cpu_registers_copy_(NULL),
- deopt_fpu_registers_copy_(NULL),
- deopt_frame_copy_(NULL),
- deopt_frame_copy_size_(0),
- deferred_boxes_(NULL),
- deferred_object_refs_(NULL),
- deferred_objects_count_(0),
- deferred_objects_(NULL),
+ deopt_context_(NULL),
stacktrace_(NULL),
stack_frame_index_(-1),
object_histogram_(NULL),
@@ -444,6 +330,7 @@
mutex_ = NULL; // Fail fast if interrupts are scheduled on a dead isolate.
delete message_handler_;
message_handler_ = NULL; // Fail fast if we send messages to a dead isolate.
+ ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted.
delete object_histogram_;
}
@@ -864,6 +751,11 @@
// Visit objects in the debugger.
debugger()->VisitObjectPointers(visitor);
+
+ // Visit objects that are being used for deoptimization.
+ if (deopt_context() != NULL) {
+ deopt_context()->VisitObjectPointers(visitor);
+ }
}
@@ -1079,31 +971,6 @@
}
-static void FillDeferredSlots(DeferredSlot** slot_list) {
- DeferredSlot* slot = *slot_list;
- *slot_list = NULL;
-
- while (slot != NULL) {
- DeferredSlot* current = slot;
- slot = slot->next();
-
- current->Materialize();
-
- delete current;
- }
-}
-
-
-void Isolate::MaterializeDeferredBoxes() {
- FillDeferredSlots(&deferred_boxes_);
-}
-
-
-void Isolate::MaterializeDeferredObjects() {
- FillDeferredSlots(&deferred_object_refs_);
-}
-
-
static char* GetRootScriptUri(Isolate* isolate) {
const Library& library =
Library::Handle(isolate->object_store()->root_library());
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 7a71eb4..128f7e2 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -25,6 +25,7 @@
class Class;
class CodeIndexTable;
class Debugger;
+class DeoptContext;
class Field;
class Function;
class HandleScope;
@@ -58,174 +59,6 @@
class ObjectIdRing;
-// Used by the deoptimization infrastructure to defer allocation of unboxed
-// objects until frame is fully rewritten and GC is safe.
-// Describes a stack slot that should be populated with a reference to the
-// materialized object.
-class DeferredSlot {
- public:
- DeferredSlot(RawInstance** slot, DeferredSlot* next)
- : slot_(slot), next_(next) { }
- virtual ~DeferredSlot() { }
-
- RawInstance** slot() const { return slot_; }
- DeferredSlot* next() const { return next_; }
-
- virtual void Materialize() = 0;
-
- private:
- RawInstance** const slot_;
- DeferredSlot* const next_;
-
- DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
-};
-
-
-class DeferredDouble : public DeferredSlot {
- public:
- DeferredDouble(double value, RawInstance** slot, DeferredSlot* next)
- : DeferredSlot(slot, next), value_(value) { }
-
- virtual void Materialize();
-
- double value() const { return value_; }
-
- private:
- const double value_;
-
- DISALLOW_COPY_AND_ASSIGN(DeferredDouble);
-};
-
-
-class DeferredMint : public DeferredSlot {
- public:
- DeferredMint(int64_t value, RawInstance** slot, DeferredSlot* next)
- : DeferredSlot(slot, next), value_(value) { }
-
- virtual void Materialize();
-
- int64_t value() const { return value_; }
-
- private:
- const int64_t value_;
-
- DISALLOW_COPY_AND_ASSIGN(DeferredMint);
-};
-
-
-class DeferredFloat32x4 : public DeferredSlot {
- public:
- DeferredFloat32x4(simd128_value_t value, RawInstance** slot,
- DeferredSlot* next)
- : DeferredSlot(slot, next), value_(value) { }
-
- virtual void Materialize();
-
- simd128_value_t value() const { return value_; }
-
- private:
- const simd128_value_t value_;
-
- DISALLOW_COPY_AND_ASSIGN(DeferredFloat32x4);
-};
-
-
-class DeferredUint32x4 : public DeferredSlot {
- public:
- DeferredUint32x4(simd128_value_t value, RawInstance** slot,
- DeferredSlot* next)
- : DeferredSlot(slot, next), value_(value) { }
-
- virtual void Materialize();
-
- simd128_value_t value() const { return value_; }
-
- private:
- const simd128_value_t value_;
-
- DISALLOW_COPY_AND_ASSIGN(DeferredUint32x4);
-};
-
-
-// Describes a slot that contains a reference to an object that had its
-// allocation removed by AllocationSinking pass.
-// Object itself is described and materialized by DeferredObject.
-class DeferredObjectRef : public DeferredSlot {
- public:
- DeferredObjectRef(intptr_t index, RawInstance** slot, DeferredSlot* next)
- : DeferredSlot(slot, next), index_(index) { }
-
- virtual void Materialize();
-
- intptr_t index() const { return index_; }
-
- private:
- const intptr_t index_;
-
- DISALLOW_COPY_AND_ASSIGN(DeferredObjectRef);
-};
-
-
-// Describes an object which allocation was removed by AllocationSinking pass.
-// Arguments for materialization are stored as a part of expression stack
-// for the bottommost deoptimized frame so that GC could discover them.
-// They will be removed from the stack at the very end of deoptimization.
-class DeferredObject {
- public:
- DeferredObject(intptr_t field_count, intptr_t* args)
- : field_count_(field_count),
- args_(reinterpret_cast<RawObject**>(args)),
- object_(NULL) { }
-
- intptr_t ArgumentCount() const {
- return kFieldsStartIndex + kFieldEntrySize * field_count_;
- }
-
- RawInstance* object();
-
- private:
- enum {
- kClassIndex = 0,
- kFieldsStartIndex = kClassIndex + 1
- };
-
- enum {
- kFieldIndex = 0,
- kValueIndex,
- kFieldEntrySize,
- };
-
- // Materializes the object. Returns amount of values that were consumed
- // and should be removed from the expression stack at the very end of
- // deoptimization.
- void Materialize();
-
- RawObject* GetClass() const {
- return args_[kClassIndex];
- }
-
- RawObject* GetField(intptr_t index) const {
- return args_[kFieldsStartIndex + kFieldEntrySize * index + kFieldIndex];
- }
-
- RawObject* GetValue(intptr_t index) const {
- return args_[kFieldsStartIndex + kFieldEntrySize * index + kValueIndex];
- }
-
- // Amount of fields that have to be initialized.
- const intptr_t field_count_;
-
- // Pointer to the first materialization argument on the stack.
- // The first argument is Class of the instance to materialize followed by
- // Field, value pairs.
- RawObject** args_;
-
- // Object materialized from this description.
- const Instance* object_;
-
- DISALLOW_COPY_AND_ASSIGN(DeferredObject);
-};
-
#define REUSABLE_HANDLE_LIST(V) \
V(Object) \
V(Array) \
@@ -503,29 +336,6 @@
return file_close_callback_;
}
- intptr_t* deopt_cpu_registers_copy() const {
- return deopt_cpu_registers_copy_;
- }
- void set_deopt_cpu_registers_copy(intptr_t* value) {
- ASSERT((value == NULL) || (deopt_cpu_registers_copy_ == NULL));
- deopt_cpu_registers_copy_ = value;
- }
- fpu_register_t* deopt_fpu_registers_copy() const {
- return deopt_fpu_registers_copy_;
- }
- void set_deopt_fpu_registers_copy(fpu_register_t* value) {
- ASSERT((value == NULL) || (deopt_fpu_registers_copy_ == NULL));
- deopt_fpu_registers_copy_ = value;
- }
- intptr_t* deopt_frame_copy() const { return deopt_frame_copy_; }
- void SetDeoptFrameCopy(intptr_t* value, intptr_t size) {
- ASSERT((value == NULL) || (size > 0));
- ASSERT((value == NULL) || (deopt_frame_copy_ == NULL));
- deopt_frame_copy_ = value;
- deopt_frame_copy_size_ = size;
- }
- intptr_t deopt_frame_copy_size() const { return deopt_frame_copy_size_; }
-
void set_object_id_ring(ObjectIdRing* ring) {
object_id_ring_ = ring;
}
@@ -533,79 +343,12 @@
return object_id_ring_;
}
- void PrepareForDeferredMaterialization(intptr_t count) {
- if (count > 0) {
- deferred_objects_ = new DeferredObject*[count];
- deferred_objects_count_ = count;
- }
+ DeoptContext* deopt_context() const { return deopt_context_; }
+ void set_deopt_context(DeoptContext* value) {
+ ASSERT(value == NULL || deopt_context_ == NULL);
+ deopt_context_ = value;
}
- void DeleteDeferredObjects() {
- for (intptr_t i = 0; i < deferred_objects_count_; i++) {
- delete deferred_objects_[i];
- }
- delete[] deferred_objects_;
- deferred_objects_ = NULL;
- deferred_objects_count_ = 0;
- }
-
- DeferredObject* GetDeferredObject(intptr_t idx) const {
- return deferred_objects_[idx];
- }
-
- void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) {
- deferred_objects_[idx] = object;
- }
-
- intptr_t DeferredObjectsCount() const {
- return deferred_objects_count_;
- }
-
- void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
- deferred_object_refs_ = new DeferredObjectRef(
- idx,
- reinterpret_cast<RawInstance**>(slot),
- deferred_object_refs_);
- }
-
- void DeferDoubleMaterialization(double value, RawDouble** slot) {
- deferred_boxes_ = new DeferredDouble(
- value,
- reinterpret_cast<RawInstance**>(slot),
- deferred_boxes_);
- }
-
- void DeferMintMaterialization(int64_t value, RawMint** slot) {
- deferred_boxes_ = new DeferredMint(
- value,
- reinterpret_cast<RawInstance**>(slot),
- deferred_boxes_);
- }
-
- void DeferFloat32x4Materialization(simd128_value_t value,
- RawFloat32x4** slot) {
- deferred_boxes_ = new DeferredFloat32x4(
- value,
- reinterpret_cast<RawInstance**>(slot),
- deferred_boxes_);
- }
-
- void DeferUint32x4Materialization(simd128_value_t value,
- RawUint32x4** slot) {
- deferred_boxes_ = new DeferredUint32x4(
- value,
- reinterpret_cast<RawInstance**>(slot),
- deferred_boxes_);
- }
-
- // Populate all deferred slots that contain boxes for double, mint, simd
- // values.
- void MaterializeDeferredBoxes();
-
- // Populate all slots containing references to objects which allocations
- // were eliminated by AllocationSinking pass.
- void MaterializeDeferredObjects();
-
static char* GetStatus(const char* request);
intptr_t BlockClassFinalization() {
@@ -668,17 +411,7 @@
GcPrologueCallbacks gc_prologue_callbacks_;
GcEpilogueCallbacks gc_epilogue_callbacks_;
intptr_t defer_finalization_count_;
-
- // Deoptimization support.
- intptr_t* deopt_cpu_registers_copy_;
- fpu_register_t* deopt_fpu_registers_copy_;
- intptr_t* deopt_frame_copy_;
- intptr_t deopt_frame_copy_size_;
- DeferredSlot* deferred_boxes_;
- DeferredSlot* deferred_object_refs_;
-
- intptr_t deferred_objects_count_;
- DeferredObject** deferred_objects_;
+ DeoptContext* deopt_context_;
// Status support.
char* stacktrace_;
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 20335cc..72a4833 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -87,46 +87,34 @@
Isolate* isolate() const { return isolate_; }
int ArgCount() const { return ArgcBits::decode(argc_tag_); }
- // Returns true if the arguments are those of an instance function call.
- bool ToInstanceFunction() const {
- return InstanceFunctionBit::decode(argc_tag_);
- }
-
- // Returns true if the arguments are those of a closure function call.
- bool ToClosureFunction() const {
- return ClosureFunctionBit::decode(argc_tag_);
- }
-
RawObject* ArgAt(int index) const {
ASSERT((index >= 0) && (index < ArgCount()));
return (*argv_)[-index];
}
- int NumHiddenArgs() const {
- // For static closure functions, the closure at index 0 is hidden.
- // In the instance closure function case, the receiver is accessed from
- // the context and the closure at index 0 is hidden, so the apparent
- // argument count remains unchanged.
- if (ToClosureFunction() && !ToInstanceFunction()) {
- return 1;
- }
- return 0;
+ int NativeArgCount() const {
+ int function_bits = FunctionBits::decode(argc_tag_);
+ return ArgCount() - NumHiddenArgs(function_bits);
}
- int NativeArgCount() const {
- return ArgCount() - NumHiddenArgs();
+ RawObject* NativeArg0() const {
+ int function_bits = FunctionBits::decode(argc_tag_);
+ if (function_bits == (kClosureFunctionBit | kInstanceFunctionBit)) {
+ // Retrieve the receiver from the context.
+ const Context& context = Context::Handle(isolate_->top_context());
+ return context.At(0);
+ }
+ return ArgAt(NumHiddenArgs(function_bits));
}
RawObject* NativeArgAt(int index) const {
ASSERT((index >= 0) && (index < NativeArgCount()));
- if ((index == 0) && ToClosureFunction() && ToInstanceFunction()) {
- // Retrieve the receiver from the context.
- const Context& context = Context::Handle(isolate_->top_context());
- return context.At(0);
- } else {
- const int actual_index = index + NumHiddenArgs();
- return ArgAt(actual_index);
+ if (index == 0) {
+ return NativeArg0();
}
+ int function_bits = FunctionBits::decode(argc_tag_);
+ const int actual_index = index + NumHiddenArgs(function_bits);
+ return ArgAt(actual_index);
}
void SetReturn(const Object& value) const {
@@ -162,21 +150,29 @@
ASSERT(function.is_native());
ASSERT(!function.IsConstructor()); // Not supported.
int tag = ArgcBits::encode(function.NumParameters());
- tag = InstanceFunctionBit::update(!function.is_static(), tag);
- tag = ClosureFunctionBit::update(function.IsClosureFunction(), tag);
- return tag;
+ int function_bits = 0;
+ if (!function.is_static()) {
+ function_bits |= kInstanceFunctionBit;
+ }
+ if (function.IsClosureFunction()) {
+ function_bits |= kClosureFunctionBit;
+ }
+ return FunctionBits::update(function_bits, tag);
}
private:
+ enum {
+ kInstanceFunctionBit = 1,
+ kClosureFunctionBit = 2,
+ };
enum ArgcTagBits {
kArgcBit = 0,
kArgcSize = 24,
- kInstanceFunctionBit = 24,
- kClosureFunctionBit = 25,
+ kFunctionBit = 24,
+ kFunctionSize = 2,
};
class ArgcBits : public BitField<int, kArgcBit, kArgcSize> {};
- class InstanceFunctionBit : public BitField<bool, kInstanceFunctionBit, 1> {};
- class ClosureFunctionBit : public BitField<bool, kClosureFunctionBit, 1> {};
+ class FunctionBits : public BitField<int, kFunctionBit, kFunctionSize> {};
friend class Api;
friend class BootstrapNatives;
friend class Simulator;
@@ -189,6 +185,27 @@
*retval_ = value;
}
+ // Returns true if the arguments are those of an instance function call.
+ bool ToInstanceFunction() const {
+ return (FunctionBits::decode(argc_tag_) & kInstanceFunctionBit);
+ }
+
+ // Returns true if the arguments are those of a closure function call.
+ bool ToClosureFunction() const {
+ return (FunctionBits::decode(argc_tag_) & kClosureFunctionBit);
+ }
+
+ int NumHiddenArgs(int function_bits) const {
+ // For static closure functions, the closure at index 0 is hidden.
+ // In the instance closure function case, the receiver is accessed from
+ // the context and the closure at index 0 is hidden, so the apparent
+ // argument count remains unchanged.
+ if (function_bits == kClosureFunctionBit) {
+ return 1;
+ }
+ return 0;
+ }
+
Isolate* isolate_; // Current isolate pointer.
int argc_tag_; // Encodes argument count and invoked native call type.
RawObject*(*argv_)[]; // Pointer to an array of arguments to runtime call.
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 421ff4a..e25cbe9 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -154,7 +154,7 @@
V(CoreLibrary, Object, _noSuchMethod) \
V(CoreLibrary, Object, _as) \
V(CoreLibrary, Object, _instanceOf) \
- V(CoreLibrary, _ObjectArray, _ObjectArray.) \
+ V(CoreLibrary, _List, _List.) \
V(CoreLibrary, AssertionError, _throwNew) \
V(CoreLibrary, TypeError, _throwNew) \
V(CoreLibrary, FallThroughError, _throwNew) \
@@ -696,7 +696,7 @@
// Set up names for object array and one byte string class which are
// pre-allocated in the vm isolate also.
cls = Dart::vm_isolate()->object_store()->array_class();
- cls.set_name(Symbols::ObjectArray());
+ cls.set_name(Symbols::_List());
cls = Dart::vm_isolate()->object_store()->one_byte_string_class();
cls.set_name(Symbols::OneByteString());
}
@@ -876,7 +876,7 @@
// remaining classes and register them by name in the dictionaries.
String& name = String::Handle();
cls = object_store->array_class(); // Was allocated above.
- RegisterPrivateClass(cls, Symbols::ObjectArray(), core_lib);
+ RegisterPrivateClass(cls, Symbols::_List(), core_lib);
pending_classes.Add(cls);
// We cannot use NewNonParameterizedType(cls), because Array is parameterized.
type ^= Type::New(Object::Handle(cls.raw()),
@@ -887,7 +887,7 @@
object_store->set_array_type(type);
cls = object_store->growable_object_array_class(); // Was allocated above.
- RegisterPrivateClass(cls, Symbols::GrowableObjectArray(), core_lib);
+ RegisterPrivateClass(cls, Symbols::_GrowableList(), core_lib);
pending_classes.Add(cls);
cls = Class::New<Array>(kImmutableArrayCid);
@@ -895,7 +895,7 @@
cls.set_type_arguments_field_offset(Array::type_arguments_offset());
ASSERT(object_store->immutable_array_class() != object_store->array_class());
cls.set_is_prefinalized();
- RegisterPrivateClass(cls, Symbols::ImmutableArray(), core_lib);
+ RegisterPrivateClass(cls, Symbols::_ImmutableList(), core_lib);
pending_classes.Add(cls);
cls = object_store->one_byte_string_class(); // Was allocated above.
@@ -1175,9 +1175,12 @@
ClassFinalizer::VerifyBootstrapClasses();
MarkInvisibleFunctions();
- // Set up the intrinsic state of all functions (core, math and scalar list).
+ // Set up the intrinsic state of all functions (core, math and typed data).
Intrinsifier::InitializeState();
+ // Set up recognized state of all functions (core, math and typed data).
+ MethodRecognizer::InitializeState();
+
return Error::null();
}
@@ -4165,6 +4168,11 @@
}
+void Function::set_is_recognized(bool value) const {
+ set_kind_tag(RecognizedBit::update(value, raw_ptr()->kind_tag_));
+}
+
+
void Function::set_is_static(bool value) const {
set_kind_tag(StaticBit::update(value, raw_ptr()->kind_tag_));
}
@@ -4738,6 +4746,7 @@
result.set_is_external(is_external);
result.set_is_visible(true); // Will be computed later.
result.set_is_intrinsic(false);
+ result.set_is_recognized(false);
result.set_owner(owner);
result.set_token_pos(token_pos);
result.set_end_token_pos(token_pos);
@@ -6173,7 +6182,7 @@
}
static const int kInitialTokenCount = 32;
- static const intptr_t kTableSize = 128;
+ static const intptr_t kTableSize = 1024;
uint8_t* buffer_;
WriteStream stream_;
@@ -8027,10 +8036,10 @@
-// Return Function::null() if function does not exist in lib.
-static RawFunction* GetFunction(const GrowableArray<Library*>& libs,
- const char* class_name,
- const char* function_name) {
+// Return Function::null() if function does not exist in libs.
+RawFunction* Library::GetFunction(const GrowableArray<Library*>& libs,
+ const char* class_name,
+ const char* function_name) {
Function& func = Function::Handle();
String& class_str = String::Handle();
String& func_str = String::Handle();
@@ -9833,7 +9842,6 @@
Array::Handle(arguments_descriptor()),
deopt_id(),
kNumArgsTested));
- result.set_deopt_reason(deopt_reason());
const intptr_t len = NumberOfChecks();
for (intptr_t i = 0; i < len; i++) {
const intptr_t class_id = GetClassIdAt(i, arg_nr);
@@ -9859,7 +9867,7 @@
}
}
// Copy deoptimization reason.
- result.set_deopt_reason(this->deopt_reason());
+ result.set_deopt_reason(deopt_reason());
return result.raw();
}
@@ -13315,8 +13323,18 @@
if (str.IsOneByteString()) {
return OneByteString::EscapeSpecialCharacters(str);
}
- ASSERT(str.IsTwoByteString());
- return TwoByteString::EscapeSpecialCharacters(str);
+ if (str.IsTwoByteString()) {
+ return TwoByteString::EscapeSpecialCharacters(str);
+ }
+ if (str.IsExternalOneByteString()) {
+ return ExternalOneByteString::EscapeSpecialCharacters(str);
+ }
+ ASSERT(str.IsExternalTwoByteString());
+ // If EscapeSpecialCharacters is frequently called on external two byte
+ // strings, we should implement it directly on ExternalTwoByteString rather
+ // than first converting to a TwoByteString.
+ return TwoByteString::EscapeSpecialCharacters(
+ String::Handle(TwoByteString::New(str, Heap::kNew)));
}
@@ -13358,14 +13376,24 @@
RawString* String::ConcatAll(const Array& strings,
Heap::Space space) {
+ return ConcatAllRange(strings, 0, strings.Length(), space);
+}
+
+
+RawString* String::ConcatAllRange(const Array& strings,
+ intptr_t start,
+ intptr_t end,
+ Heap::Space space) {
ASSERT(!strings.IsNull());
+ ASSERT(start >= 0);
+ ASSERT(end <= strings.Length());
intptr_t result_len = 0;
- intptr_t strings_len = strings.Length();
String& str = String::Handle();
intptr_t char_size = kOneByteChar;
- for (intptr_t i = 0; i < strings_len; i++) {
+ // Compute 'char_size' and 'result_len'.
+ for (intptr_t i = start; i < end; i++) {
str ^= strings.At(i);
- intptr_t str_len = str.Length();
+ const intptr_t str_len = str.Length();
if ((kMaxElements - result_len) < str_len) {
Isolate* isolate = Isolate::Current();
const Instance& exception =
@@ -13377,10 +13405,10 @@
char_size = Utils::Maximum(char_size, str.CharSize());
}
if (char_size == kOneByteChar) {
- return OneByteString::ConcatAll(strings, result_len, space);
+ return OneByteString::ConcatAll(strings, start, end, result_len, space);
}
ASSERT(char_size == kTwoByteChar);
- return TwoByteString::ConcatAll(strings, result_len, space);
+ return TwoByteString::ConcatAll(strings, start, end, result_len, space);
}
@@ -13721,7 +13749,6 @@
intptr_t len = str.Length();
if (len > 0) {
intptr_t num_escapes = 0;
- intptr_t index = 0;
for (intptr_t i = 0; i < len; i++) {
if (IsSpecialCharacter(*CharAddr(str, i))) {
num_escapes += 1;
@@ -13729,6 +13756,7 @@
}
const String& dststr = String::Handle(
OneByteString::New(len + num_escapes, Heap::kNew));
+ intptr_t index = 0;
for (intptr_t i = 0; i < len; i++) {
if (IsSpecialCharacter(*CharAddr(str, i))) {
*(CharAddr(dststr, index)) = '\\';
@@ -13741,7 +13769,36 @@
}
return OneByteString::raw(dststr);
}
- return OneByteString::null();
+ return OneByteString::raw(Symbols::Empty());
+}
+
+RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters(
+ const String& str) {
+ intptr_t len = str.Length();
+ if (len > 0) {
+ intptr_t num_escapes = 0;
+ for (intptr_t i = 0; i < len; i++) {
+ if (IsSpecialCharacter(*CharAddr(str, i))) {
+ num_escapes += 1;
+ }
+ }
+ const String& dststr = String::Handle(
+ OneByteString::New(len + num_escapes, Heap::kNew));
+ intptr_t index = 0;
+ for (intptr_t i = 0; i < len; i++) {
+ if (IsSpecialCharacter(*CharAddr(str, i))) {
+ *(OneByteString::CharAddr(dststr, index)) = '\\';
+ *(OneByteString::CharAddr(dststr, index + 1)) =
+ SpecialCharacter(*CharAddr(str, i));
+ index += 2;
+ } else {
+ *(OneByteString::CharAddr(dststr, index)) = *CharAddr(str, i);
+ index += 1;
+ }
+ }
+ return OneByteString::raw(dststr);
+ }
+ return OneByteString::raw(Symbols::Empty());
}
@@ -13842,15 +13899,19 @@
RawOneByteString* OneByteString::ConcatAll(const Array& strings,
+ intptr_t start,
+ intptr_t end,
intptr_t len,
Heap::Space space) {
+ ASSERT(!strings.IsNull());
+ ASSERT(start >= 0);
+ ASSERT(end <= strings.Length());
const String& result = String::Handle(OneByteString::New(len, space));
String& str = String::Handle();
- intptr_t strings_len = strings.Length();
intptr_t pos = 0;
- for (intptr_t i = 0; i < strings_len; i++) {
+ for (intptr_t i = start; i < end; i++) {
str ^= strings.At(i);
- intptr_t str_len = str.Length();
+ const intptr_t str_len = str.Length();
String::Copy(result, pos, str, 0, str_len);
ASSERT((kMaxElements - pos) >= str_len);
pos += str_len;
@@ -13918,7 +13979,6 @@
intptr_t len = str.Length();
if (len > 0) {
intptr_t num_escapes = 0;
- intptr_t index = 0;
for (intptr_t i = 0; i < len; i++) {
if (IsSpecialCharacter(*CharAddr(str, i))) {
num_escapes += 1;
@@ -13926,6 +13986,7 @@
}
const String& dststr = String::Handle(
TwoByteString::New(len + num_escapes, Heap::kNew));
+ intptr_t index = 0;
for (intptr_t i = 0; i < len; i++) {
if (IsSpecialCharacter(*CharAddr(str, i))) {
*(CharAddr(dststr, index)) = '\\';
@@ -13938,7 +13999,7 @@
}
return TwoByteString::raw(dststr);
}
- return TwoByteString::null();
+ return TwoByteString::New(0, Heap::kNew);
}
@@ -14024,15 +14085,19 @@
RawTwoByteString* TwoByteString::ConcatAll(const Array& strings,
+ intptr_t start,
+ intptr_t end,
intptr_t len,
Heap::Space space) {
+ ASSERT(!strings.IsNull());
+ ASSERT(start >= 0);
+ ASSERT(end <= strings.Length());
const String& result = String::Handle(TwoByteString::New(len, space));
String& str = String::Handle();
- intptr_t strings_len = strings.Length();
intptr_t pos = 0;
- for (intptr_t i = 0; i < strings_len; i++) {
+ for (intptr_t i = start; i < end; i++) {
str ^= strings.At(i);
- intptr_t str_len = str.Length();
+ const intptr_t str_len = str.Length();
String::Copy(result, pos, str, 0, str_len);
ASSERT((kMaxElements - pos) >= str_len);
pos += str_len;
@@ -14255,10 +14320,10 @@
const char* Array::ToCString() const {
if (IsNull()) {
- return IsImmutable() ? "ImmutableArray NULL" : "Array NULL";
+ return IsImmutable() ? "_ImmutableList NULL" : "_List NULL";
}
- const char* format = !IsImmutable() ? "Array len:%" Pd "" :
- "Immutable Array len:%" Pd "";
+ const char* format = IsImmutable() ?
+ "_ImmutableList len:%" Pd : "_List len:%" Pd;
intptr_t len = OS::SNPrint(NULL, 0, format, Length()) + 1;
char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
OS::SNPrint(chars, len, format, Length());
@@ -14466,9 +14531,9 @@
const char* GrowableObjectArray::ToCString() const {
if (IsNull()) {
- return "GrowableObjectArray NULL";
+ return "_GrowableList NULL";
}
- const char* format = "GrowableObjectArray len:%" Pd "";
+ const char* format = "_GrowableList len:%" Pd "";
intptr_t len = OS::SNPrint(NULL, 0, format, Length()) + 1;
char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
OS::SNPrint(chars, len, format, Length());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2caf67d..30ce9f7 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -858,6 +858,9 @@
void SetFunctions(const Array& value) const;
void AddFunction(const Function& function) const;
+ RawGrowableObjectArray* closures() const {
+ return raw_ptr()->closure_functions_;
+ }
void AddClosureFunction(const Function& function) const;
RawFunction* LookupClosureFunction(intptr_t token_pos) const;
@@ -1691,6 +1694,11 @@
}
void set_is_intrinsic(bool value) const;
+ bool is_recognized() const {
+ return RecognizedBit::decode(raw_ptr()->kind_tag_);
+ }
+ void set_is_recognized(bool value) const;
+
bool HasOptimizedCode() const;
// Returns true if the argument counts are valid for calling this function.
@@ -1849,7 +1857,8 @@
kExternalBit = 7,
kVisibleBit = 8,
kIntrinsicBit = 9,
- kKindTagBit = 10,
+ kRecognizedBit = 10,
+ kKindTagBit = 11,
kKindTagSize = 4,
};
class StaticBit : public BitField<bool, kStaticBit, 1> {};
@@ -1862,6 +1871,7 @@
class ExternalBit : public BitField<bool, kExternalBit, 1> {};
class VisibleBit : public BitField<bool, kVisibleBit, 1> {};
class IntrinsicBit : public BitField<bool, kIntrinsicBit, 1> {};
+ class RecognizedBit : public BitField<bool, kRecognizedBit, 1> {};
class KindBits :
public BitField<RawFunction::Kind, kKindTagBit, kKindTagSize> {}; // NOLINT
@@ -2510,6 +2520,11 @@
static bool IsPrivate(const String& name);
+ // Return Function::null() if function does not exist in libs.
+ static RawFunction* GetFunction(const GrowableArray<Library*>& libs,
+ const char* class_name,
+ const char* function_name);
+
private:
static const int kInitialImportsCapacity = 4;
static const int kImportsCapacityIncrement = 8;
@@ -4778,6 +4793,11 @@
Heap::Space space = Heap::kNew);
static RawString* ConcatAll(const Array& strings,
Heap::Space space = Heap::kNew);
+ // Concat all strings in 'strings' from 'start' to 'end' (excluding).
+ static RawString* ConcatAllRange(const Array& strings,
+ intptr_t start,
+ intptr_t end,
+ Heap::Space space = Heap::kNew);
static RawString* SubString(const String& str,
intptr_t begin_index,
@@ -4898,6 +4918,8 @@
const String& str2,
Heap::Space space);
static RawOneByteString* ConcatAll(const Array& strings,
+ intptr_t start,
+ intptr_t end,
intptr_t len,
Heap::Space space);
@@ -4947,6 +4969,7 @@
friend class Class;
friend class String;
+ friend class ExternalOneByteString;
friend class SnapshotReader;
};
@@ -4993,6 +5016,8 @@
const String& str2,
Heap::Space space);
static RawTwoByteString* ConcatAll(const Array& strings,
+ intptr_t start,
+ intptr_t end,
intptr_t len,
Heap::Space space);
@@ -5068,6 +5093,8 @@
return reinterpret_cast<RawExternalOneByteString*>(Object::null());
}
+ static RawOneByteString* EscapeSpecialCharacters(const String& str);
+
static const ClassId kClassId = kExternalOneByteStringCid;
private:
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 78a3d0c..cba6d44 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -1529,6 +1529,100 @@
}
+TEST_CASE(EscapeSpecialCharactersOneByteString) {
+ uint8_t characters[] =
+ { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
+ intptr_t len = ARRAY_SIZE(characters);
+
+ const String& str =
+ String::Handle(
+ OneByteString::New(characters, len, Heap::kNew));
+ EXPECT(str.IsOneByteString());
+ EXPECT_EQ(str.Length(), len);
+ EXPECT(str.Equals("a\n\f\b\t\v\r\\$z"));
+ const String& escaped_str =
+ String::Handle(String::EscapeSpecialCharacters(str));
+ EXPECT(escaped_str.Equals("a\\n\\f\\b\\t\\v\\r\\\\\\$z"));
+
+ const String& escaped_empty_str =
+ String::Handle(String::EscapeSpecialCharacters(Symbols::Empty()));
+ EXPECT_EQ(escaped_empty_str.Length(), 0);
+}
+
+
+TEST_CASE(EscapeSpecialCharactersExternalOneByteString) {
+ uint8_t characters[] =
+ { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
+ intptr_t len = ARRAY_SIZE(characters);
+
+ const String& str =
+ String::Handle(
+ ExternalOneByteString::New(characters, len, NULL, NULL, Heap::kNew));
+ EXPECT(!str.IsOneByteString());
+ EXPECT(str.IsExternalOneByteString());
+ EXPECT_EQ(str.Length(), len);
+ EXPECT(str.Equals("a\n\f\b\t\v\r\\$z"));
+ const String& escaped_str =
+ String::Handle(String::EscapeSpecialCharacters(str));
+ EXPECT(escaped_str.Equals("a\\n\\f\\b\\t\\v\\r\\\\\\$z"));
+
+ const String& empty_str =
+ String::Handle(
+ ExternalOneByteString::New(characters, 0, NULL, NULL, Heap::kNew));
+ const String& escaped_empty_str =
+ String::Handle(String::EscapeSpecialCharacters(empty_str));
+ EXPECT_EQ(empty_str.Length(), 0);
+ EXPECT_EQ(escaped_empty_str.Length(), 0);
+}
+
+TEST_CASE(EscapeSpecialCharactersTwoByteString) {
+ uint16_t characters[] =
+ { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
+ intptr_t len = ARRAY_SIZE(characters);
+
+ const String& str =
+ String::Handle(TwoByteString::New(characters, len, Heap::kNew));
+ EXPECT(str.IsTwoByteString());
+ EXPECT_EQ(str.Length(), len);
+ EXPECT(str.Equals("a\n\f\b\t\v\r\\$z"));
+ const String& escaped_str =
+ String::Handle(String::EscapeSpecialCharacters(str));
+ EXPECT(escaped_str.Equals("a\\n\\f\\b\\t\\v\\r\\\\\\$z"));
+
+ const String& empty_str =
+ String::Handle(TwoByteString::New(static_cast<intptr_t>(0), Heap::kNew));
+ const String& escaped_empty_str =
+ String::Handle(String::EscapeSpecialCharacters(empty_str));
+ EXPECT_EQ(empty_str.Length(), 0);
+ EXPECT_EQ(escaped_empty_str.Length(), 0);
+}
+
+
+TEST_CASE(EscapeSpecialCharactersExternalTwoByteString) {
+ uint16_t characters[] =
+ { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
+ intptr_t len = ARRAY_SIZE(characters);
+
+ const String& str =
+ String::Handle(
+ ExternalTwoByteString::New(characters, len, NULL, NULL, Heap::kNew));
+ EXPECT(str.IsExternalTwoByteString());
+ EXPECT_EQ(str.Length(), len);
+ EXPECT(str.Equals("a\n\f\b\t\v\r\\$z"));
+ const String& escaped_str =
+ String::Handle(String::EscapeSpecialCharacters(str));
+ EXPECT(escaped_str.Equals("a\\n\\f\\b\\t\\v\\r\\\\\\$z"));
+
+ const String& empty_str =
+ String::Handle(
+ ExternalTwoByteString::New(characters, 0, NULL, NULL, Heap::kNew));
+ const String& escaped_empty_str =
+ String::Handle(String::EscapeSpecialCharacters(empty_str));
+ EXPECT_EQ(empty_str.Length(), 0);
+ EXPECT_EQ(escaped_empty_str.Length(), 0);
+}
+
+
TEST_CASE(ExternalTwoByteString) {
uint16_t characters[] = { 0x1E6B, 0x1E85, 0x1E53 };
intptr_t len = ARRAY_SIZE(characters);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 11ce280..22ec97e 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -308,7 +308,7 @@
}
-void Parser::SetScript(const Script & script, intptr_t token_pos) {
+void Parser::SetScript(const Script& script, intptr_t token_pos) {
script_ = script.raw();
tokens_iterator_.SetStream(TokenStream::Handle(script.tokens()), token_pos);
token_kind_ = Token::kILLEGAL;
@@ -1019,7 +1019,7 @@
if (field.is_const()) {
// This getter will only be called once at compile time.
if (expr->EvalConstExpr() == NULL) {
- ErrorMsg(expr_pos, "initializer must be a compile-time constant");
+ ErrorMsg(expr_pos, "initializer is not a valid compile-time constant");
}
ReturnNode* return_node = new ReturnNode(ident_pos, expr);
current_block_->statements->Add(return_node);
@@ -1923,55 +1923,7 @@
op_arguments = BuildNoSuchMethodArguments(
operator_pos, operator_function_name, *op_arguments);
}
- if (super_operator.name() == Symbols::EqualOperator().raw()) {
- // Expand super.== call to match correct == semantics into:
- // Let t1 = left, t2 = right {
- // (t1 === null || t2 === null) ? t1 === t2
- // : static_call(super.==, t1, t2)
- // }
- // Normal == calls are not expanded at the AST level to produce
- // more compact code and enable more optimization opportunities.
- ASSERT(!is_no_such_method); // == is always found.
- EnsureExpressionTemp(); // Needed for ConditionalExprNode.
- LetNode* result = new LetNode(operator_pos);
- AstNode* left =
- new LoadLocalNode(operator_pos,
- result->AddInitializer(op_arguments->NodeAt(0)));
- AstNode* right =
- new LoadLocalNode(operator_pos,
- result->AddInitializer(op_arguments->NodeAt(1)));
- LiteralNode* null_operand =
- new LiteralNode(operator_pos, Instance::ZoneHandle());
- ComparisonNode* is_left_null = new ComparisonNode(operator_pos,
- Token::kEQ_STRICT,
- left,
- null_operand);
- ComparisonNode* is_right_null = new ComparisonNode(operator_pos,
- Token::kEQ_STRICT,
- right,
- null_operand);
- BinaryOpNode* null_check = new BinaryOpNode(operator_pos,
- Token::kOR,
- is_left_null,
- is_right_null);
- ArgumentListNode* new_arguments = new ArgumentListNode(operator_pos);
- new_arguments->Add(left);
- new_arguments->Add(right);
- StaticCallNode* call = new StaticCallNode(operator_pos,
- super_operator,
- new_arguments);
- ComparisonNode* strict_eq = new ComparisonNode(operator_pos,
- Token::kEQ_STRICT,
- left,
- right);
- result->AddNode(new ConditionalExprNode(operator_pos,
- null_check,
- strict_eq,
- call));
- super_op = result;
- } else {
- super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
- }
+ super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
if (negate_result) {
super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op);
}
@@ -2879,17 +2831,35 @@
intptr_t end_token_pos = 0;
if (CurrentToken() == Token::kLBRACE) {
ConsumeToken();
+ if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+ const Class& owner = Class::Handle(func.Owner());
+ if (!owner.IsObjectClass()) {
+ AddEqualityNullCheck();
+ }
+ }
ParseStatementSequence();
end_token_pos = TokenPos();
ExpectToken(Token::kRBRACE);
} else if (CurrentToken() == Token::kARROW) {
ConsumeToken();
+ if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+ const Class& owner = Class::Handle(func.Owner());
+ if (!owner.IsObjectClass()) {
+ AddEqualityNullCheck();
+ }
+ }
const intptr_t expr_pos = TokenPos();
AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
ASSERT(expr != NULL);
current_block_->statements->Add(new ReturnNode(expr_pos, expr));
end_token_pos = TokenPos();
} else if (IsLiteral("native")) {
+ if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+ const Class& owner = Class::Handle(func.Owner());
+ if (!owner.IsObjectClass()) {
+ AddEqualityNullCheck();
+ }
+ }
ParseNativeFunctionBlock(¶ms, func);
end_token_pos = TokenPos();
ExpectSemicolon();
@@ -2924,6 +2894,31 @@
}
+void Parser::AddEqualityNullCheck() {
+ const intptr_t token_pos = Scanner::kDummyTokenIndex;
+ AstNode* argument =
+ new LoadLocalNode(token_pos,
+ current_block_->scope->parent()->VariableAt(1));
+ LiteralNode* null_operand =
+ new LiteralNode(token_pos, Instance::ZoneHandle());
+ ComparisonNode* check_arg = new ComparisonNode(token_pos,
+ Token::kEQ_STRICT,
+ argument,
+ null_operand);
+ ComparisonNode* result = new ComparisonNode(token_pos,
+ Token::kEQ_STRICT,
+ LoadReceiver(token_pos),
+ null_operand);
+ SequenceNode* arg_is_null = new SequenceNode(token_pos, NULL);
+ arg_is_null->Add(new ReturnNode(token_pos, result));
+ IfNode* if_arg_null = new IfNode(token_pos,
+ check_arg,
+ arg_is_null,
+ NULL);
+ current_block_->statements->Add(if_arg_null);
+}
+
+
void Parser::SkipIf(Token::Kind token) {
if (CurrentToken() == token) {
ConsumeToken();
@@ -3123,7 +3118,7 @@
// Replace the type with a malformed type and compile a throw when called.
redirection_type = ClassFinalizer::NewFinalizedMalformedType(
Error::Handle(), // No previous error.
- current_class(),
+ script_,
type_pos,
"factory '%s' may not redirect to type parameter '%s'",
method->name->ToCString(),
@@ -6047,8 +6042,20 @@
}
+// Return true if the type class of the given value implements the
+// == operator.
+static bool ImplementsEqualOperator(const Instance& value) {
+ Class& cls = Class::Handle(value.clazz());
+ const Function& equal_op = Function::Handle(
+ Resolver::ResolveDynamicAnyArgs(cls, Symbols::EqualOperator()));
+ ASSERT(!equal_op.IsNull());
+ cls = equal_op.Owner();
+ return !cls.IsObjectClass();
+}
+
+
// Check that all case expressions are of the same type, either int, String,
-// double or any other class that does not override the == operator.
+// 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) {
@@ -6072,23 +6079,21 @@
}
continue;
}
- if (first_value.IsDouble()) {
- if (!val.IsDouble()) {
- ErrorMsg(val_pos, "expected case expression of type double");
- }
- continue;
+ if (val.IsDouble()) {
+ ErrorMsg(val_pos, "case expression may not be of type double");
}
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 ==");
+ if (i == 0) {
+ // The value is of some type other than int, String or double.
+ // Check that the type class does not override the == operator.
+ // Check this only in the first loop iteration since all values
+ // are of the same type, which we check above.
+ if (ImplementsEqualOperator(val)) {
+ ErrorMsg(val_pos,
+ "type class of case expression must not implement operator ==");
+ }
}
}
}
@@ -7652,7 +7657,7 @@
return expr;
}
if (expr->EvalConstExpr() == NULL) {
- ErrorMsg(expr_pos, "expression must be a compile-time constant");
+ ErrorMsg(expr_pos, "expression is not a valid compile-time constant");
}
return new LiteralNode(expr_pos, EvaluateConstExpr(expr));
}
@@ -7822,7 +7827,7 @@
ConsumeToken();
const intptr_t right_expr_pos = TokenPos();
if (require_compiletime_const && (assignment_op != Token::kASSIGN)) {
- ErrorMsg(right_expr_pos, "expression must be a compile-time constant");
+ ErrorMsg(right_expr_pos, "expression is not a valid compile-time constant");
}
AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades);
if (assignment_op != Token::kASSIGN) {
@@ -8530,7 +8535,7 @@
FLAG_error_on_bad_type) {
*type = ClassFinalizer::NewFinalizedMalformedType(
Error::Handle(), // No previous error.
- scope_class,
+ script_,
type->token_pos(),
"type parameter '%s' cannot be referenced "
"from static member",
@@ -8548,7 +8553,7 @@
FLAG_error_on_bad_type) {
*type = ClassFinalizer::NewFinalizedMalformedType(
Error::Handle(), // No previous error.
- scope_class,
+ script_,
type_parameter.token_pos(),
"type parameter '%s' cannot be parameterized",
String::Handle(type_parameter.name()).ToCString());
@@ -8586,7 +8591,7 @@
FLAG_error_on_bad_type) {
ClassFinalizer::FinalizeMalformedType(
Error::Handle(), // No previous error.
- scope_class,
+ script_,
parameterized_type,
"type '%s' is not loaded",
String::Handle(parameterized_type.UserVisibleName()).ToCString());
@@ -9181,7 +9186,7 @@
if (finalization == ClassFinalizer::kCanonicalizeWellFormed) {
return ClassFinalizer::NewFinalizedMalformedType(
Error::Handle(), // No previous error.
- current_class(),
+ script_,
type_name.ident_pos,
"using '%s' in this context is invalid",
type_name.ident->ToCString());
@@ -9502,6 +9507,18 @@
key_type,
Symbols::ListLiteralElement());
}
+ if (is_const) {
+ ASSERT(key->IsLiteralNode());
+ const Instance& key_value = key->AsLiteralNode()->literal();
+ if (key_value.IsDouble()) {
+ ErrorMsg(key_pos, "key value must not be of type double");
+ }
+ if (!key_value.IsInteger() &&
+ !key_value.IsString() &&
+ ImplementsEqualOperator(key_value)) {
+ ErrorMsg(key_pos, "key value must not implement operator ==");
+ }
+ }
ExpectToken(Token::kCOLON);
const intptr_t value_pos = TokenPos();
AstNode* value = ParseExpr(is_const, kConsumeCascades);
@@ -9744,7 +9761,7 @@
// Replace the type with a malformed type.
type = ClassFinalizer::NewFinalizedMalformedType(
Error::Handle(), // No previous error.
- current_class(),
+ script_,
type_pos,
"%s'%s' cannot be instantiated",
type.IsTypeParameter() ? "type parameter " : "",
@@ -9756,7 +9773,7 @@
// Replace the type with a malformed type.
type = ClassFinalizer::NewFinalizedMalformedType(
bound_error,
- current_class(),
+ script_,
type_pos,
"malbounded type '%s' cannot be instantiated",
String::Handle(type.UserVisibleName()).ToCString());
@@ -9821,7 +9838,7 @@
if (is_const) {
type = ClassFinalizer::NewFinalizedMalformedType(
Error::Handle(), // No previous error.
- current_class(),
+ script_,
call_pos,
"class '%s' has no constructor or factory named '%s'",
String::Handle(type_class.Name()).ToCString(),
@@ -9947,7 +9964,7 @@
&malformed_error)) {
type_bound = ClassFinalizer::NewFinalizedMalformedType(
malformed_error,
- current_class(),
+ script_,
new_pos,
"const factory result is not an instance of '%s'",
String::Handle(type_bound.UserVisibleName()).ToCString());
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 4abfda0..16b9322 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -662,6 +662,8 @@
const Function& constructor,
ArgumentListNode* arguments);
+ void AddEqualityNullCheck();
+
RawInstance* TryCanonicalize(const Instance& instance, intptr_t token_pos);
Isolate* isolate() const { return isolate_; }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 32f5d83..3ccbe98 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -628,7 +628,7 @@
int16_t num_fixed_parameters_;
int16_t num_optional_parameters_; // > 0: positional; < 0: named.
int16_t deoptimization_counter_;
- uint16_t kind_tag_;
+ uint16_t kind_tag_; // See Function::KindTagBits.
uint16_t optimized_instruction_count_;
uint16_t optimized_call_site_count_;
};
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 3e185ee..a8351cd 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -67,7 +67,6 @@
V(TwoArgsUnoptimizedStaticCall) \
V(OptimizeFunction) \
V(BreakpointDynamic) \
- V(EqualityWithNullArg) \
// class StubEntry is used to describe stub methods generated in dart to
// abstract out common code executed from generated dart code.
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 596af42..0c35d5b 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1758,7 +1758,15 @@
void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
- __ Unimplemented("BreakpointRuntime stub");
+ __ Comment("BreakpointRuntime stub");
+ __ EnterStubFrame();
+ __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
+ // Preserve arguments descriptor and make room for result.
+ __ PushList((1 << R0) | (1 << R4) | (1 << R5));
+ __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+ __ PopList((1 << R0) | (1 << R4) | (1 << R5));
+ __ LeaveStubFrame();
+ __ bx(R0);
}
@@ -1958,92 +1966,6 @@
}
-// Implements equality operator when one of the arguments is null
-// (identity check) and updates ICData if necessary.
-// LR: return address.
-// R1: left argument.
-// R0: right argument.
-// R5: ICData.
-// R0: result.
-// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
-void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
- __ EnterStubFrame();
- static const intptr_t kNumArgsTested = 2;
-#if defined(DEBUG)
- { Label ok;
- __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset()));
- __ cmp(IP, ShifterOperand(kNumArgsTested));
- __ b(&ok, EQ);
- __ Stop("Incorrect ICData for equality");
- __ Bind(&ok);
- }
-#endif // DEBUG
- // Check IC data, update if needed.
- // R5: IC data object (preserved).
- __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
- // R6: ic_data_array with check entries: classes and target functions.
- __ AddImmediate(R6, Array::data_offset() - kHeapObjectTag);
- // R6: points directly to the first ic data array element.
-
- Label get_class_id_as_smi, no_match, loop, found;
- __ Bind(&loop);
- // Check left.
- __ mov(R2, ShifterOperand(R1));
- __ bl(&get_class_id_as_smi);
- __ ldr(R3, Address(R6, 0 * kWordSize));
- __ cmp(R2, ShifterOperand(R3)); // Class id match?
- __ b(&no_match, NE);
- // Check right.
- __ mov(R2, ShifterOperand(R0));
- __ bl(&get_class_id_as_smi);
- __ ldr(R3, Address(R6, 1 * kWordSize));
- __ cmp(R2, ShifterOperand(R3)); // Class id match?
- __ b(&found, EQ);
- __ Bind(&no_match);
- // Next check group.
- __ AddImmediate(R6, kWordSize * ICData::TestEntryLengthFor(kNumArgsTested));
- __ CompareImmediate(R3, Smi::RawValue(kIllegalCid)); // Done?
- __ b(&loop, NE);
- Label update_ic_data;
- __ b(&update_ic_data);
-
- __ Bind(&found);
- const intptr_t count_offset =
- ICData::CountIndexFor(kNumArgsTested) * kWordSize;
- __ ldr(IP, Address(R6, count_offset));
- __ adds(IP, IP, ShifterOperand(Smi::RawValue(1)));
- __ LoadImmediate(IP, Smi::RawValue(Smi::kMaxValue), VS); // If overflow.
- __ str(IP, Address(R6, count_offset));
-
- Label compute_result;
- __ Bind(&compute_result);
- __ cmp(R0, ShifterOperand(R1));
- __ LoadObject(R0, Bool::False(), NE);
- __ LoadObject(R0, Bool::True(), EQ);
- __ LeaveStubFrame();
- __ Ret();
-
- __ Bind(&get_class_id_as_smi);
- // Test if Smi -> load Smi class for comparison.
- __ tst(R2, ShifterOperand(kSmiTagMask));
- __ mov(R2, ShifterOperand(Smi::RawValue(kSmiCid)), EQ);
- __ bx(LR, EQ);
- __ LoadClassId(R2, R2);
- __ SmiTag(R2);
- __ bx(LR);
-
- __ Bind(&update_ic_data);
- // R5: ICData
- __ PushList((1 << R0) | (1 << R1));
- __ PushObject(Symbols::EqualOperator()); // Target's name.
- __ Push(R5); // ICData
- __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4); // Clobbers R4, R5.
- __ Drop(2);
- __ PopList((1 << R0) | (1 << R1));
- __ b(&compute_result);
-}
-
-
// Calls to the runtime to optimize the given function.
// R6: function to be reoptimized.
// R4: argument descriptor (preserved).
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index f2ba2ea..4df92d7 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1796,7 +1796,7 @@
}
-// EDX, EXC: May contain arguments to runtime stub.
+// EDX, ECX: May contain arguments to runtime stub.
void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
__ EnterStubFrame();
// Save runtime args.
@@ -2032,105 +2032,6 @@
}
-// Implements equality operator when one of the arguments is null
-// (identity check) and updates ICData if necessary.
-// TOS + 0: return address
-// TOS + 1: right argument
-// TOS + 2: left argument
-// ECX: ICData.
-// EAX: result.
-// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
-void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
- static const intptr_t kNumArgsTested = 2;
-#if defined(DEBUG)
- { Label ok;
- __ movl(EAX, FieldAddress(ECX, ICData::num_args_tested_offset()));
- __ cmpl(EAX, Immediate(kNumArgsTested));
- __ j(EQUAL, &ok, Assembler::kNearJump);
- __ Stop("Incorrect ICData for equality");
- __ Bind(&ok);
- }
-#endif // DEBUG
- // Check IC data, update if needed.
- // ECX: IC data object (preserved).
- __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
- // EBX: ic_data_array with check entries: classes and target functions.
- __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
- // EBX: points directly to the first ic data array element.
-
- Label get_class_id_as_smi, no_match, loop, compute_result, found;
- __ Bind(&loop);
- // Check left.
- __ movl(EAX, Address(ESP, 2 * kWordSize));
- __ call(&get_class_id_as_smi);
- __ movl(EDI, Address(EBX, 0 * kWordSize));
- __ cmpl(EAX, EDI); // Class id match?
- __ j(NOT_EQUAL, &no_match, Assembler::kNearJump);
- // Check right.
- __ movl(EAX, Address(ESP, 1 * kWordSize));
- __ call(&get_class_id_as_smi);
- __ movl(EDI, Address(EBX, 1 * kWordSize));
- __ cmpl(EAX, EDI); // Class id match?
- __ j(EQUAL, &found, Assembler::kNearJump);
- __ Bind(&no_match);
- // Next check group.
- __ addl(EBX, Immediate(
- kWordSize * ICData::TestEntryLengthFor(kNumArgsTested)));
- __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done?
- __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
- Label update_ic_data;
- __ jmp(&update_ic_data);
-
- __ Bind(&found);
- const intptr_t count_offset =
- ICData::CountIndexFor(kNumArgsTested) * kWordSize;
- __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
- __ j(NO_OVERFLOW, &compute_result);
- __ movl(Address(EBX, count_offset),
- Immediate(Smi::RawValue(Smi::kMaxValue)));
-
- __ Bind(&compute_result);
- Label true_label;
- __ movl(EAX, Address(ESP, 1 * kWordSize));
- __ cmpl(EAX, Address(ESP, 2 * kWordSize));
- __ j(EQUAL, &true_label, Assembler::kNearJump);
- __ LoadObject(EAX, Bool::False());
- __ ret();
- __ Bind(&true_label);
- __ LoadObject(EAX, Bool::True());
- __ ret();
-
- __ Bind(&get_class_id_as_smi);
- Label not_smi;
- // Test if Smi -> load Smi class for comparison.
- __ testl(EAX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump);
- __ movl(EAX, Immediate(Smi::RawValue(kSmiCid)));
- __ ret();
-
- __ Bind(¬_smi);
- __ LoadClassId(EAX, EAX);
- __ SmiTag(EAX);
- __ ret();
-
- __ Bind(&update_ic_data);
-
- // ECX: ICData
- __ movl(EAX, Address(ESP, 1 * kWordSize));
- __ movl(EDI, Address(ESP, 2 * kWordSize));
- __ EnterStubFrame();
- __ pushl(EDI); // arg 0
- __ pushl(EAX); // arg 1
- __ PushObject(Symbols::EqualOperator()); // Target's name.
- __ pushl(ECX); // ICData
- __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4);
- __ Drop(4);
- __ LeaveFrame();
-
- __ jmp(&compute_result, Assembler::kNearJump);
-}
-
-
// Calls to the runtime to optimize the given function.
// EDI: function to be reoptimized.
// EDX: argument descriptor (preserved).
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 83990b8..0928f0a 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -2000,7 +2000,22 @@
void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
- __ Unimplemented("BreakpointRuntime stub");
+ __ Comment("BreakpointRuntime stub");
+ __ EnterStubFrame();
+ __ addiu(SP, SP, Immediate(-3 * kWordSize));
+ __ sw(S5, Address(SP, 2 * kWordSize));
+ __ sw(S4, Address(SP, 1 * kWordSize));
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
+ __ sw(TMP, Address(SP, 0 * kWordSize));
+
+ __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+
+ __ lw(S5, Address(SP, 2 * kWordSize));
+ __ lw(S4, Address(SP, 1 * kWordSize));
+ __ lw(T0, Address(SP, 0 * kWordSize));
+ __ addiu(SP, SP, Immediate(3 * kWordSize));
+ __ LeaveStubFrame();
+ __ jr(T0);
}
@@ -2217,110 +2232,6 @@
}
-// Implements equality operator when one of the arguments is null
-// (identity check) and updates ICData if necessary.
-// RA: return address.
-// A1: left argument.
-// A0: right argument.
-// T0: ICData.
-// V0: result.
-// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
-void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
- __ TraceSimMsg("EqualityWithNullArgStub");
- __ Comment("EqualityWithNullArgStub");
- __ EnterStubFrame();
- static const intptr_t kNumArgsTested = 2;
-#if defined(DEBUG)
- { Label ok;
- __ lw(CMPRES1, FieldAddress(T0, ICData::num_args_tested_offset()));
- __ BranchEqual(CMPRES1, kNumArgsTested, &ok);
- __ Stop("Incorrect ICData for equality");
- __ Bind(&ok);
- }
-#endif // DEBUG
- // Check IC data, update if needed.
- // T0: IC data object (preserved).
- __ lw(T6, FieldAddress(T0, ICData::ic_data_offset()));
- // T6: ic_data_array with check entries: classes and target functions.
- __ AddImmediate(T6, Array::data_offset() - kHeapObjectTag);
- // T6: points directly to the first ic data array element.
-
- Label get_class_id_as_smi, no_match, loop, found;
- __ Bind(&loop);
- // Check left.
- __ bal(&get_class_id_as_smi);
- __ delay_slot()->mov(T2, A1);
- __ lw(T3, Address(T6, 0 * kWordSize));
- __ bne(T2, T3, &no_match); // Class id match?
-
- // Check right.
- __ bal(&get_class_id_as_smi);
- __ delay_slot()->mov(T2, A0);
- __ lw(T3, Address(T6, 1 * kWordSize));
- __ beq(T2, T3, &found); // Class id match?
- __ Bind(&no_match);
- // Next check group.
- intptr_t entry_bytes = kWordSize * ICData::TestEntryLengthFor(kNumArgsTested);
- if (Utils::IsInt(kImmBits, entry_bytes)) {
- __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop); // Done?
- __ delay_slot()->addiu(T6, T6, Immediate(entry_bytes));
- } else {
- __ AddImmediate(T6, entry_bytes);
- __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop); // Done?
- }
-
- Label update_ic_data;
- __ b(&update_ic_data);
-
- __ Bind(&found);
- const intptr_t count_offset =
- ICData::CountIndexFor(kNumArgsTested) * kWordSize;
- Label no_overflow;
- __ lw(T1, Address(T6, count_offset));
- __ AddImmediateDetectOverflow(T1, T1, Smi::RawValue(1), CMPRES, T5);
- __ bgez(CMPRES, &no_overflow);
- __ delay_slot()->sw(T1, Address(T6, count_offset));
- __ LoadImmediate(TMP1, Smi::RawValue(Smi::kMaxValue));
- __ sw(TMP1, Address(T6, count_offset)); // If overflow.
- __ Bind(&no_overflow);
-
- Label compute_result;
- __ Bind(&compute_result);
- __ LoadObject(T4, Bool::True());
- __ LoadObject(T5, Bool::False());
- __ subu(CMPRES, A0, A1);
- __ movz(V0, T4, CMPRES);
- __ movn(V0, T5, CMPRES);
- __ LeaveStubFrameAndReturn();
-
- __ Bind(&get_class_id_as_smi);
- // Test if Smi -> load Smi class for comparison.
- Label not_smi;
- __ andi(CMPRES, T2, Immediate(kSmiTagMask));
- __ bne(CMPRES, ZR, ¬_smi);
- __ jr(RA);
- __ delay_slot()->addiu(T2, ZR, Immediate(Smi::RawValue(kSmiCid)));
- __ Bind(¬_smi);
- __ LoadClassId(T2, T2);
- __ jr(RA);
- __ delay_slot()->SmiTag(T2);
-
- __ Bind(&update_ic_data);
- // T0: ICData
- __ addiu(SP, SP, Immediate(-4 * kWordSize));
- __ sw(A1, Address(SP, 3 * kWordSize));
- __ sw(A0, Address(SP, 2 * kWordSize));
- __ LoadObject(TMP1, Symbols::EqualOperator()); // Target's name.
- __ sw(TMP1, Address(SP, 1 * kWordSize));
- __ sw(T0, Address(SP, 0 * kWordSize)); // ICData.
- __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4);
- __ lw(A0, Address(SP, 2 * kWordSize));
- __ lw(A1, Address(SP, 3 * kWordSize));
- __ b(&compute_result);
- __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
-}
-
-
// Calls to the runtime to optimize the given function.
// T0: function to be reoptimized.
// S4: argument descriptor (preserved).
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 7d47618..d2d304f 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -60,7 +60,7 @@
__ movq(CTX, RAX);
// Reserve space for arguments and align frame before entering C++ world.
- __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
+ __ subq(RSP, Immediate(sizeof(NativeArguments)));
if (OS::ActivationFrameAlignment() > 1) {
__ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
}
@@ -149,7 +149,7 @@
// Reserve space for the native arguments structure passed on the stack (the
// outgoing pointer parameter to the native arguments structure is passed in
// RDI) and align frame before entering the C++ world.
- __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
+ __ subq(RSP, Immediate(sizeof(NativeArguments)));
if (OS::ActivationFrameAlignment() > 1) {
__ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
}
@@ -217,7 +217,7 @@
// Reserve space for the native arguments structure passed on the stack (the
// outgoing pointer parameter to the native arguments structure is passed in
// RDI) and align frame before entering the C++ world.
- __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
+ __ subq(RSP, Immediate(sizeof(NativeArguments)));
if (OS::ActivationFrameAlignment() > 1) {
__ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
}
@@ -255,7 +255,7 @@
__ EnterStubFrame();
__ pushq(R10); // Preserve arguments descriptor array.
// Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ PushObject(Object::null_object(), PP);
__ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
__ popq(RAX); // Get Code object result.
__ popq(R10); // Restore arguments descriptor array.
@@ -275,7 +275,7 @@
__ EnterStubFrame();
__ pushq(R10); // Preserve arguments descriptor array.
// Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ PushObject(Object::null_object(), PP);
__ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
__ popq(RAX); // Get Code object.
__ popq(R10); // Restore arguments descriptor array.
@@ -308,8 +308,8 @@
__ Bind(&loop);
__ movq(RAX, Address(R12, 0));
__ movq(Address(RBX, 0), RAX);
- __ AddImmediate(RBX, Immediate(kWordSize));
- __ AddImmediate(R12, Immediate(-kWordSize));
+ __ addq(RBX, Immediate(kWordSize));
+ __ subq(R12, Immediate(kWordSize));
__ Bind(&loop_condition);
__ decq(R10);
__ j(POSITIVE, &loop, Assembler::kNearJump);
@@ -324,7 +324,7 @@
// when trying to resolve the call.
void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
__ EnterStubFrameWithPP();
- __ PushObject(Object::null_object()); // Space for the return value.
+ __ PushObject(Object::null_object(), PP); // Space for the return value.
// Push the receiver as an argument. Load the smi-tagged argument
// count into R13 to index the receiver in the stack. There are
@@ -504,7 +504,7 @@
__ pushq(R10);
// Space for the result of the runtime call.
- __ PushObject(Object::null_object());
+ __ PushObject(Object::null_object(), PP);
__ pushq(RAX); // Receiver.
__ pushq(RBX); // IC data.
__ pushq(R10); // Arguments descriptor.
@@ -519,7 +519,7 @@
__ LeaveFrameWithPP();
Label lookup;
- __ CompareObject(RAX, Object::null_object());
+ __ CompareObject(RAX, Object::null_object(), PP);
__ j(EQUAL, &lookup, Assembler::kNearJump);
__ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
__ jmp(RAX);
@@ -650,7 +650,7 @@
// calling into the runtime.
__ EnterStubFrame();
// Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ PushObject(Object::null_object(), PP);
__ pushq(R10); // Array length as Smi.
__ pushq(RBX); // Element type.
__ CallRuntime(kAllocateArrayRuntimeEntry, 2);
@@ -1228,7 +1228,7 @@
// Create a stub frame.
__ EnterStubFrameWithPP();
__ pushq(R12); // Setup space on stack for return value.
- __ PushObject(cls); // Push class of object to be allocated.
+ __ PushObject(cls, PP); // Push class of object to be allocated.
if (is_cls_parameterized) {
__ pushq(RAX); // Push type arguments of object to be allocated.
__ pushq(RDX); // Push type arguments of instantiator.
@@ -1364,7 +1364,7 @@
}
__ pushq(R12); // Setup space on stack for the return value.
- __ PushObject(func);
+ __ PushObject(func, PP);
if (is_implicit_instance_closure) {
__ pushq(RAX); // Receiver.
}
@@ -2003,104 +2003,6 @@
}
-// Implements equality operator when one of the arguments is null
-// (identity check) and updates ICData if necessary.
-// TOS + 0: return address
-// TOS + 1: right argument
-// TOS + 2: left argument
-// RBX: ICData.
-// RAX: result.
-// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
-void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
- static const intptr_t kNumArgsTested = 2;
-#if defined(DEBUG)
- { Label ok;
- __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
- __ cmpq(RCX, Immediate(kNumArgsTested));
- __ j(EQUAL, &ok, Assembler::kNearJump);
- __ Stop("Incorrect ICData for equality");
- __ Bind(&ok);
- }
-#endif // DEBUG
- // Check IC data, update if needed.
- // RBX: IC data object (preserved).
- __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
- // R12: ic_data_array with check entries: classes and target functions.
- __ leaq(R12, FieldAddress(R12, Array::data_offset()));
- // R12: points directly to the first ic data array element.
-
- Label get_class_id_as_smi, no_match, loop, compute_result, found;
- __ Bind(&loop);
- // Check left.
- __ movq(RAX, Address(RSP, 2 * kWordSize));
- __ call(&get_class_id_as_smi);
- __ movq(R13, Address(R12, 0 * kWordSize));
- __ cmpq(RAX, R13); // Class id match?
- __ j(NOT_EQUAL, &no_match, Assembler::kNearJump);
- // Check right.
- __ movq(RAX, Address(RSP, 1 * kWordSize));
- __ call(&get_class_id_as_smi);
- __ movq(R13, Address(R12, 1 * kWordSize));
- __ cmpq(RAX, R13); // Class id match?
- __ j(EQUAL, &found, Assembler::kNearJump);
- __ Bind(&no_match);
- // Next check group.
- __ addq(R12, Immediate(
- kWordSize * ICData::TestEntryLengthFor(kNumArgsTested)));
- __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done?
- __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
- Label update_ic_data;
- __ jmp(&update_ic_data);
-
- __ Bind(&found);
- const intptr_t count_offset =
- ICData::CountIndexFor(kNumArgsTested) * kWordSize;
- __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1)));
- __ j(NO_OVERFLOW, &compute_result);
- __ movq(Address(R12, count_offset),
- Immediate(Smi::RawValue(Smi::kMaxValue)));
-
- __ Bind(&compute_result);
- Label true_label;
- __ movq(RAX, Address(RSP, 1 * kWordSize));
- __ cmpq(RAX, Address(RSP, 2 * kWordSize));
- __ j(EQUAL, &true_label, Assembler::kNearJump);
- __ LoadObject(RAX, Bool::False(), PP);
- __ ret();
- __ Bind(&true_label);
- __ LoadObject(RAX, Bool::True(), PP);
- __ ret();
-
- __ Bind(&get_class_id_as_smi);
- Label not_smi;
- // Test if Smi -> load Smi class for comparison.
- __ testq(RAX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump);
- __ movq(RAX, Immediate(Smi::RawValue(kSmiCid)));
- __ ret();
-
- __ Bind(¬_smi);
- __ LoadClassId(RAX, RAX);
- __ SmiTag(RAX);
- __ ret();
-
- __ Bind(&update_ic_data);
-
- // RBX: ICData
- __ movq(RAX, Address(RSP, 1 * kWordSize));
- __ movq(R13, Address(RSP, 2 * kWordSize));
- __ EnterStubFrame();
- __ pushq(R13); // arg 0
- __ pushq(RAX); // arg 1
- __ PushObject(Symbols::EqualOperator()); // Target's name.
- __ pushq(RBX); // ICData
- __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4);
- __ Drop(4);
- __ LeaveFrame();
-
- __ jmp(&compute_result, Assembler::kNearJump);
-}
-
// Calls to the runtime to optimize the given function.
// RDI: function to be reoptimized.
// R10: argument descriptor (preserved).
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index 3efc152..cc0e3fb 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -47,12 +47,12 @@
ASSERT(context.isolate() == Isolate::Current());
__ EnterStubFrameWithPP();
__ LoadObject(CTX, context, PP);
- __ PushObject(result); // Push Null object for return value.
- __ PushObject(smi1); // Push argument 1 smi1.
- __ PushObject(smi2); // Push argument 2 smi2.
+ __ PushObject(result, PP); // Push Null object for return value.
+ __ PushObject(smi1, PP); // Push argument 1 smi1.
+ __ PushObject(smi2, PP); // Push argument 2 smi2.
ASSERT(kTestSmiSubRuntimeEntry.argument_count() == argc);
__ CallRuntime(kTestSmiSubRuntimeEntry, argc); // Call SmiSub runtime func.
- __ AddImmediate(RSP, Immediate(argc * kWordSize));
+ __ AddImmediate(RSP, Immediate(argc * kWordSize), PP);
__ popq(RAX); // Pop return value from return slot.
__ LeaveFrameWithPP();
__ ret();
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 987eb45..723263c 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -116,12 +116,12 @@
V(_Bigint, "_Bigint") \
V(_Double, "_Double") \
V(Bool, "bool") \
- V(ObjectArray, "_ObjectArray") \
- V(ObjectArrayFactory, "_ObjectArray.") \
- V(GrowableObjectArray, "_GrowableObjectArray") \
- V(GrowableObjectArrayFactory, "_GrowableObjectArray.") \
- V(GrowableObjectArrayWithData, "_GrowableObjectArray.withData") \
- V(ImmutableArray, "_ImmutableArray") \
+ V(_List, "_List") \
+ V(_ListFactory, "_List.") \
+ V(_GrowableList, "_GrowableList") \
+ V(_GrowableListFactory, "_GrowableList.") \
+ V(_GrowableListWithData, "_GrowableList.withData") \
+ V(_ImmutableList, "_ImmutableList") \
V(OneByteString, "_OneByteString") \
V(TwoByteString, "_TwoByteString") \
V(ExternalOneByteString, "_ExternalOneByteString") \
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index edcd75d..921078b 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -116,6 +116,8 @@
'debuginfo.h',
'debuginfo_android.cc',
'debuginfo_linux.cc',
+ 'deferred_objects.cc',
+ 'deferred_objects.h',
'deopt_instructions.cc',
'deopt_instructions.h',
'disassembler.cc',
diff --git a/sdk/lib/_internal/compiler/implementation/common.dart b/sdk/lib/_internal/compiler/implementation/common.dart
new file mode 100644
index 0000000..3c069ca
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/common.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.
+
+library dart2js.common;
+
+export 'dart2jslib.dart' show
+ CompilerTask,
+ Compiler,
+ Constant,
+ ConstantHandler,
+ InterceptorConstant,
+ MessageKind,
+ NullConstant,
+ Selector,
+ SourceString,
+ TreeElements,
+ TypeConstant,
+ invariant;
+
+export 'dart_types.dart' show
+ DartType,
+ FunctionType,
+ InterfaceType,
+ TypeVariableType,
+ Types;
+
+export 'elements/elements.dart' show
+ ClassElement,
+ ClosureFieldElement,
+ Element,
+ Elements,
+ FunctionElement,
+ FunctionSignature,
+ LibraryElement,
+ MetadataAnnotation,
+ MixinApplicationElement,
+ TypedefElement,
+ VariableElement;
+
+export 'tree/tree.dart' show
+ Node;
+
+export 'types/types.dart' show
+ TypeMask;
+
+export 'universe/universe.dart' show
+ SelectorKind;
+
+export 'util/util.dart' show
+ Link,
+ SpannableAssertionFailure;
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index 48bc9f4..8ae51fa 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -29,12 +29,6 @@
/** Caches the statics where the initial value cannot be eagerly compiled. */
final Set<VariableElement> lazyStatics;
- /** Caches the createRuntimeType function if registered. */
- Element createRuntimeTypeFunction = null;
-
- /** Caches the setRuntimeTypeInfo function if registered. */
- Element setRuntimeTypeInfoFunction = null;
-
ConstantHandler(Compiler compiler, this.constantSystem,
{ bool this.isMetadata: false })
: initialVariableValues = new Map<VariableElement, dynamic>(),
@@ -45,90 +39,12 @@
String get name => 'ConstantHandler';
- void registerCompileTimeConstant(Constant constant, TreeElements elements) {
- registerInstantiatedType(constant.computeType(compiler), elements);
- if (constant.isFunction()) {
- FunctionConstant function = constant;
- registerGetOfStaticFunction(function.element);
- } else if (constant.isInterceptor()) {
- // An interceptor constant references the class's prototype chain.
- InterceptorConstant interceptor = constant;
- registerInstantiatedType(interceptor.dispatchedType, elements);
- }
+ void addCompileTimeConstantForEmission(Constant constant) {
compiledConstants.add(constant);
}
- void registerInstantiatedType(DartType type, TreeElements elements) {
- if (isMetadata) {
- compiler.backend.registerMetadataInstantiatedType(type, elements);
- return;
- }
- compiler.enqueuer.codegen.registerInstantiatedType(type, elements);
- if (type is InterfaceType &&
- !type.isRaw &&
- compiler.backend.classNeedsRti(type.element)) {
- registerSetRuntimeTypeInfoFunction();
- }
- }
-
- void registerStaticUse(Element element) {
- if (isMetadata) {
- compiler.backend.registerMetadataStaticUse(element);
- return;
- }
- compiler.analyzeElement(element.declaration);
- compiler.enqueuer.codegen.registerStaticUse(element);
- }
-
- void registerGetOfStaticFunction(FunctionElement element) {
- if (isMetadata) {
- compiler.backend.registerMetadataGetOfStaticFunction(element);
- return;
- }
- compiler.analyzeElement(element.declaration);
- compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
- }
-
- void registerStringInstance(TreeElements elements) {
- registerInstantiatedType(compiler.stringClass.rawType, elements);
- }
-
- void registerSetRuntimeTypeInfoFunction() {
- if (setRuntimeTypeInfoFunction != null) return;
- SourceString helperName = const SourceString('setRuntimeTypeInfo');
- setRuntimeTypeInfoFunction = compiler.findHelper(helperName);
- registerStaticUse(setRuntimeTypeInfoFunction);
- }
-
- void registerCreateRuntimeTypeFunction() {
- if (createRuntimeTypeFunction != null) return;
- SourceString helperName = const SourceString('createRuntimeType');
- createRuntimeTypeFunction = compiler.findHelper(helperName);
- registerStaticUse(createRuntimeTypeFunction);
- }
-
- /**
- * Compiles the initial value of the given field and stores it in an internal
- * map. Returns the initial value (a constant) if it can be computed
- * statically. Returns [:null:] if the variable must be initialized lazily.
- *
- * [work] must contain a [VariableElement] refering to a global or
- * static field.
- */
- Constant compileWorkItem(CodegenWorkItem work) {
- return measure(() {
- assert(work.element.kind == ElementKind.FIELD
- || work.element.kind == ElementKind.PARAMETER
- || work.element.kind == ElementKind.FIELD_PARAMETER);
- VariableElement element = work.element;
- // Shortcut if it has already been compiled.
- Constant result = initialVariableValues[element];
- if (result != null) return result;
- if (lazyStatics.contains(element)) return null;
- result = compileVariableWithDefinitions(element, work.resolutionTree);
- assert(pendingVariables.isEmpty);
- return result;
- });
+ Constant getConstantForVariable(VariableElement element) {
+ return initialVariableValues[element];
}
/**
@@ -175,9 +91,6 @@
TreeElements definitions,
{bool isConst: false}) {
return measure(() {
- // Initializers for parameters must be const.
- isConst = isConst || element.modifiers.isConst()
- || !Elements.isStaticOrTopLevel(element);
if (!isConst && lazyStatics.contains(element)) return null;
Node node = element.parseNode(compiler);
@@ -235,23 +148,17 @@
{bool isConst: false}) {
return measure(() {
assert(node != null);
+ Constant constant = definitions.getConstant(node);
+ if (constant != null) {
+ return constant;
+ }
CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
this, definitions, compiler, isConst: isConst);
- return evaluator.evaluate(node);
- });
- }
-
- /** Attempts to compile a constant expression. Returns null if not possible */
- Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) {
- return measure(() {
- assert(node != null);
- try {
- TryCompileTimeConstantEvaluator evaluator =
- new TryCompileTimeConstantEvaluator(this, definitions, compiler);
- return evaluator.evaluate(node);
- } on CompileTimeConstantError catch (exn) {
- return null;
+ constant = evaluator.evaluate(node);
+ if (constant != null) {
+ definitions.setConstant(node, constant);
}
+ return constant;
});
}
@@ -358,17 +265,14 @@
}
Constant visitLiteralBool(LiteralBool node) {
- handler.registerInstantiatedType(compiler.boolClass.rawType, elements);
return constantSystem.createBool(node.value);
}
Constant visitLiteralDouble(LiteralDouble node) {
- handler.registerInstantiatedType(compiler.doubleClass.rawType, elements);
return constantSystem.createDouble(node.value);
}
Constant visitLiteralInt(LiteralInt node) {
- handler.registerInstantiatedType(compiler.intClass.rawType, elements);
return constantSystem.createInt(node.value);
}
@@ -383,10 +287,7 @@
arguments.add(evaluateConstant(link.head));
}
DartType type = elements.getType(node);
- handler.registerInstantiatedType(type, elements);
- Constant constant = new ListConstant(type, arguments);
- handler.registerCompileTimeConstant(constant, elements);
- return constant;
+ return new ListConstant(type, arguments);
}
Constant visitLiteralMap(LiteralMap node) {
@@ -422,13 +323,15 @@
bool hasProtoKey = (protoValue != null);
List<Constant> values = map.values.toList();
InterfaceType sourceType = elements.getType(node);
- Link<DartType> arguments =
- new Link<DartType>.fromList([compiler.stringClass.rawType]);
- DartType keysType = new InterfaceType(compiler.listClass, arguments);
- ListConstant keysList = new ListConstant(keysType, keys);
- if (onlyStringKeys) {
- handler.registerCompileTimeConstant(keysList, elements);
+ DartType keysType;
+ if (sourceType.treatAsRaw) {
+ keysType = compiler.listClass.rawType;
+ } else {
+ Link<DartType> arguments =
+ new Link<DartType>.fromList([sourceType.typeArguments.head]);
+ keysType = new InterfaceType(compiler.listClass, arguments);
}
+ ListConstant keysList = new ListConstant(keysType, keys);
SourceString className = onlyStringKeys
? (hasProtoKey ? MapConstant.DART_PROTO_CLASS
: MapConstant.DART_STRING_CLASS)
@@ -436,12 +339,13 @@
ClassElement classElement = compiler.jsHelperLibrary.find(className);
classElement.ensureResolved(compiler);
Link<DartType> typeArgument = sourceType.typeArguments;
- InterfaceType type = new InterfaceType(classElement, typeArgument);
- handler.registerInstantiatedType(type, elements);
- Constant constant =
- new MapConstant(type, keysList, values, protoValue, onlyStringKeys);
- handler.registerCompileTimeConstant(constant, elements);
- return constant;
+ InterfaceType type;
+ if (sourceType.treatAsRaw) {
+ type = classElement.rawType;
+ } else {
+ type = new InterfaceType(classElement, typeArgument);
+ }
+ return new MapConstant(type, keysList, values, protoValue, onlyStringKeys);
}
Constant visitLiteralNull(LiteralNull node) {
@@ -449,7 +353,6 @@
}
Constant visitLiteralString(LiteralString node) {
- handler.registerStringInstance(elements);
return constantSystem.createString(node.dartString, node);
}
@@ -457,7 +360,6 @@
StringConstant left = evaluate(node.first);
StringConstant right = evaluate(node.second);
if (left == null || right == null) return null;
- handler.registerStringInstance(elements);
return constantSystem.createString(
new DartString.concat(left.value, right.value), node);
}
@@ -485,12 +387,10 @@
if (partString == null) return null;
accumulator = new DartString.concat(accumulator, partString.value);
};
- handler.registerStringInstance(elements);
return constantSystem.createString(accumulator, node);
}
Constant visitLiteralSymbol(LiteralSymbol node) {
- handler.registerStringInstance(elements);
InterfaceType type = compiler.symbolClass.computeType(compiler);
List<Constant> createArguments(_) {
return [constantSystem.createString(
@@ -502,17 +402,9 @@
Constant makeTypeConstant(Element element) {
DartType elementType = element.computeType(compiler).asRaw();
- compiler.backend.registerTypeLiteral(
- element, compiler.enqueuer.codegen, elements);
DartType constantType =
compiler.backend.typeImplementation.computeType(compiler);
- Constant constant = new TypeConstant(elementType, constantType);
- // If we use a type literal in a constant, the compile time
- // constant emitter will generate a call to the createRuntimeType
- // helper so we register a use of that.
- handler.registerCreateRuntimeTypeFunction();
- handler.registerCompileTimeConstant(constant, elements);
- return constant;
+ return new TypeConstant(elementType, constantType);
}
// TODO(floitsch): provide better error-messages.
@@ -520,9 +412,7 @@
Element element = elements[send];
if (send.isPropertyAccess) {
if (Elements.isStaticOrTopLevelFunction(element)) {
- Constant constant = new FunctionConstant(element);
- handler.registerCompileTimeConstant(constant, elements);
- return constant;
+ return new FunctionConstant(element);
} else if (Elements.isStaticOrTopLevelField(element)) {
Constant result;
if (element.modifiers.isConst()) {
@@ -532,6 +422,7 @@
}
if (result != null) return result;
} else if (Elements.isClass(element) || Elements.isTypedef(element)) {
+ assert(elements.isTypeLiteral(send));
return makeTypeConstant(element);
} else if (send.receiver != null) {
// Fall through to error handling.
@@ -550,7 +441,10 @@
Constant result = constantSystem.identity.fold(left, right);
if (result != null) return result;
} else if (Elements.isClass(element) || Elements.isTypedef(element)) {
- return makeTypeConstant(element);
+ // The node itself is not a constant but we register the selector (the
+ // identifier that refers to the class/typedef) as a constant.
+ Constant typeConstant = makeTypeConstant(element);
+ elements.setConstant(send.selector, typeConstant);
}
return signalNotCompileTimeConstant(send);
} else if (send.isPrefix) {
@@ -668,6 +562,25 @@
return signalNotCompileTimeConstant(send);
}
+ Constant visitConditional(Conditional node) {
+ Constant condition = evaluate(node.condition);
+ if (condition == null) {
+ return null;
+ } else if (!condition.isBool()) {
+ DartType conditionType = condition.computeType(compiler);
+ if (isEvaluatingConstant) {
+ compiler.reportFatalError(
+ node.condition, MessageKind.NOT_ASSIGNABLE.error,
+ {'fromType': conditionType, 'toType': compiler.boolClass.rawType});
+ }
+ return null;
+ }
+ Constant thenExpression = evaluate(node.thenExpression);
+ Constant elseExpression = evaluate(node.elseExpression);
+ BoolConstant boolCondition = condition;
+ return boolCondition.value ? thenExpression : elseExpression;
+ }
+
Constant visitSendSet(SendSet node) {
return signalNotCompileTimeConstant(node);
}
@@ -744,10 +657,7 @@
evaluator.evaluateConstructorFieldValues(arguments);
List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
- handler.registerInstantiatedType(type, elements);
- Constant constant = new ConstructedConstant(type, jsNewArguments);
- handler.registerCompileTimeConstant(constant, elements);
- return constant;
+ return new ConstructedConstant(type, jsNewArguments);
}
Constant visitParenthesizedExpression(ParenthesizedExpression node) {
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 04c0df0..6f673a3 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -123,6 +123,13 @@
bool classNeedsRti(ClassElement cls);
bool methodNeedsRti(FunctionElement function);
+
+ /// Called during codegen when [constant] has been used.
+ void registerCompileTimeConstant(Constant constant, TreeElements elements) {}
+
+ /// Called during post-processing when [constant] has been evaluated.
+ void registerMetadataConstant(Constant constant, TreeElements elements) {}
+
/// Called during resolution to notify to the backend that a class is
/// being instantiated.
void registerInstantiatedClass(ClassElement cls,
@@ -257,10 +264,6 @@
return new Future.value();
}
- void registerMetadataInstantiatedType(DartType type, TreeElements elements) {}
- void registerMetadataStaticUse(Element element) {}
- void registerMetadataGetOfStaticFunction(FunctionElement element) {}
-
/// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed
/// annotations. The arguments corresponds to the unions of the corresponding
/// fields of the annotations.
@@ -529,11 +532,9 @@
ti.TypesTask typesTask;
Backend backend;
ConstantHandler constantHandler;
- ConstantHandler metadataHandler;
EnqueueTask enqueuer;
DeferredLoadTask deferredLoadTask;
MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask;
- ContainerTracer containerTracer;
String buildId;
static const SourceString MAIN = const SourceString('main');
@@ -639,15 +640,12 @@
closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer),
checker = new TypeCheckerTask(this),
typesTask = new ti.TypesTask(this),
- containerTracer = new ContainerTracer(this),
constantHandler = new ConstantHandler(this, backend.constantSystem),
deferredLoadTask = new DeferredLoadTask(this),
mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this),
enqueuer = new EnqueueTask(this)];
tasks.addAll(backend.tasks);
- metadataHandler = new ConstantHandler(
- this, backend.constantSystem, isMetadata: true);
}
Universe get resolverWorld => enqueuer.resolution.universe;
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index bca6524..a8ac524 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -45,6 +45,7 @@
bool isNaN() => false;
bool isMinusZero() => false;
+ // TODO(johnniwinther): Replace with a 'type' getter.
DartType computeType(Compiler compiler);
List<Constant> getDependencies();
@@ -295,6 +296,10 @@
int get length => value.length;
accept(ConstantVisitor visitor) => visitor.visitString(this);
+
+ String toString() {
+ return 'StringConstant(${Error.safeToString(value.slowToString())})';
+ }
}
abstract class ObjectConstant extends Constant {
@@ -323,6 +328,8 @@
List<Constant> getDependencies() => const <Constant>[];
accept(ConstantVisitor visitor) => visitor.visitType(this);
+
+ String toString() => 'TypeConstant(${Error.safeToString(representedType)})';
}
class ListConstant extends ObjectConstant {
@@ -362,6 +369,17 @@
int get length => entries.length;
accept(ConstantVisitor visitor) => visitor.visitList(this);
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.write('ListConstant([');
+ for (int i = 0 ; i < entries.length ; i++) {
+ if (i > 0) sb.write(',');
+ sb.write(Error.safeToString(entries[i]));
+ }
+ sb.write('])');
+ return sb.toString();
+ }
}
class MapConstant extends ObjectConstant {
@@ -437,6 +455,19 @@
int get length => keys.length;
accept(ConstantVisitor visitor) => visitor.visitMap(this);
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.write('MapConstant({');
+ for (int i = 0 ; i < keys.entries.length ; i++) {
+ if (i > 0) sb.write(',');
+ sb.write(Error.safeToString(keys.entries[i]));
+ sb.write(':');
+ sb.write(Error.safeToString(values[i]));
+ }
+ sb.write('})');
+ return sb.toString();
+ }
}
class InterceptorConstant extends Constant {
@@ -460,6 +491,10 @@
accept(ConstantVisitor visitor) => visitor.visitInterceptor(this);
DartType computeType(Compiler compiler) => compiler.types.dynamicType;
+
+ String toString() {
+ return 'InterceptorConstant(${Error.safeToString(dispatchedType)})';
+ }
}
class ConstructedConstant extends ObjectConstant {
@@ -510,4 +545,21 @@
}, includeSuperAndInjectedMembers: true);
return result;
}
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.write('ConstructedConstant(');
+ sb.write(type);
+ sb.write('(');
+ int i = 0;
+ fieldElements.forEach((Element field, Constant value) {
+ if (i > 0) sb.write(',');
+ sb.write(Error.safeToString(field.name.slowToString()));
+ sb.write('=');
+ sb.write(Error.safeToString(value));
+ i++;
+ });
+ sb.write('))');
+ return sb.toString();
+ }
}
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index 47febfa..7d825c0 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -32,7 +32,6 @@
import 'source_file.dart' show SourceFile;
import 'js/js.dart' as js;
import 'deferred_load.dart' show DeferredLoadTask;
-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 6dea904..bbf3c20 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -619,7 +619,7 @@
}
}
-compareBy(f) => (x, y) => f(x).compareTo(f(y));
+Comparator compareBy(f) => (x, y) => f(x).compareTo(f(y));
List sorted(Iterable l, comparison) {
final result = new List.from(l);
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index f842ac3..bcaa080 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -4,7 +4,7 @@
part of dart_backend;
-Function get _compareNodes =>
+Comparator get _compareNodes =>
compareBy((n) => n.getBeginToken().charOffset);
typedef String _Renamer(Renamable renamable);
@@ -90,7 +90,7 @@
StringBuffer result = new StringBuffer(renameElement(type.element));
if (type is InterfaceType) {
InterfaceType interfaceType = type;
- if (!interfaceType.isRaw) {
+ if (!interfaceType.treatAsRaw) {
result.write('<');
Link<DartType> argumentsLink = interfaceType.typeArguments;
result.write(renameType(argumentsLink.head, renameElement));
@@ -306,53 +306,54 @@
}
}
-/** Always tries to return original identifier name unless it is forbidden. */
-String conservativeGenerator(
- String originalName, bool isForbidden(String name)) {
- String newName = originalName;
- while (isForbidden(newName)) {
- newName = 'p_$newName';
+/**
+ * Generates mini ID based on index.
+ * In other words, it converts index to visual representation
+ * as if digits are given characters.
+ */
+String generateMiniId(int index) {
+ const String firstCharAlphabet =
+ r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+ const String otherCharsAlphabet =
+ r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$';
+ // It's like converting index in decimal to [chars] radix.
+ if (index < firstCharAlphabet.length) return firstCharAlphabet[index];
+ StringBuffer resultBuilder = new StringBuffer();
+ resultBuilder.writeCharCode(
+ firstCharAlphabet.codeUnitAt(index % firstCharAlphabet.length));
+ index ~/= firstCharAlphabet.length;
+ int length = otherCharsAlphabet.length;
+ while (index >= length) {
+ resultBuilder.writeCharCode(otherCharsAlphabet.codeUnitAt(index % length));
+ index ~/= length;
}
- return newName;
+ resultBuilder.write(otherCharsAlphabet[index]);
+ return resultBuilder.toString();
}
+
+/** Always tries to return original identifier name unless it is forbidden. */
+String conservativeGenerator(String name, bool isForbidden(String name)) {
+ String result = name;
+ int index = 0;
+ while (isForbidden(result)) {
+ result = '${generateMiniId(index++)}_$name';
+ }
+ return result;
+}
+
+
/** Always tries to generate the most compact identifier. */
class MinifyingGenerator {
- static const String firstCharAlphabet =
- r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
- static const String otherCharsAlphabet =
- r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$';
- int nextIdIndex;
+ int index = 0;
- MinifyingGenerator() : nextIdIndex = 0;
+ MinifyingGenerator();
String generate(bool isForbidden(String name)) {
- String newName;
+ String result;
do {
- newName = getNextId();
- } while(isForbidden(newName));
- return newName;
+ result = generateMiniId(index++);
+ } while (isForbidden(result));
+ return result;
}
-
- /**
- * Generates next mini ID with current index and alphabet.
- * Advances current index.
- * In other words, it converts index to visual representation
- * as if digits are given characters.
- */
- String getNextId() {
- // It's like converting index in decimal to [chars] radix.
- int index = nextIdIndex++;
- StringBuffer resultBuilder = new StringBuffer();
- if (index < firstCharAlphabet.length) return firstCharAlphabet[index];
- resultBuilder.write(firstCharAlphabet[index % firstCharAlphabet.length]);
- index ~/= firstCharAlphabet.length;
- int length = otherCharsAlphabet.length;
- while (index >= length) {
- resultBuilder.write(otherCharsAlphabet[index % length]);
- index ~/= length;
- }
- resultBuilder.write(otherCharsAlphabet[index]);
- return resultBuilder.toString();
- }
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index f301f9b..f70517e 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -93,6 +93,9 @@
/// Returns the raw version of this type.
DartType asRaw() => this;
+ /// Is [: true :] if this type has no non-dynamic type arguments.
+ bool get treatAsRaw => isRaw;
+
/// Is [: true :] if this type should be treated as the dynamic type.
bool get treatAsDynamic => false;
@@ -424,6 +427,14 @@
bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
GenericType asRaw() => element.rawType;
+
+ bool get treatAsRaw {
+ if (isRaw) return true;
+ for (Link<DartType> link = typeArguments; !link.isEmpty; link = link.tail) {
+ if (!link.head.treatAsDynamic) return false;
+ }
+ return true;
+ }
}
class InterfaceType extends GenericType {
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 42ef97c..394d4e4 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -1574,6 +1574,7 @@
bool get isUnnamedMixinApplication => false;
+ // TODO(johnniwinther): Add [thisType] getter similar to [rawType].
InterfaceType computeType(Compiler compiler) {
if (thisType == null) {
if (origin == null) {
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index d1ee2cc..e489fb1 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -4,6 +4,8 @@
part of dart2js;
+typedef ItemCompilationContext ItemCompilationContextCreator();
+
class EnqueueTask extends CompilerTask {
final ResolutionEnqueuer resolution;
final CodegenEnqueuer codegen;
@@ -71,7 +73,7 @@
abstract class Enqueuer {
final String name;
final Compiler compiler; // TODO(ahe): Remove this dependency.
- final Function itemCompilationContextCreator;
+ final ItemCompilationContextCreator itemCompilationContextCreator;
final Map<String, Link<Element>> instanceMembersByName
= new Map<String, Link<Element>>();
final Map<String, Link<Element>> instanceFunctionsByName
@@ -85,9 +87,7 @@
bool hasEnqueuedEverything = false;
- Enqueuer(this.name, this.compiler,
- ItemCompilationContext itemCompilationContextCreator())
- : this.itemCompilationContextCreator = itemCompilationContextCreator;
+ Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator);
Queue<WorkItem> get queue;
@@ -104,7 +104,6 @@
*/
void addToWorkList(Element element) {
assert(invariant(element, element.isDeclaration));
- if (element.isForeign(compiler)) return;
internalAddToWorkList(element);
}
@@ -614,7 +613,7 @@
if (getCachedElements(element) != null) return;
if (queueIsClosed) {
throw new SpannableAssertionFailure(element,
- "Resolution work list is closed.");
+ "Resolution work list is closed. Trying to add $element.");
}
compiler.world.registerUsedElement(element);
@@ -681,11 +680,14 @@
* The action is performed as part of the post-processing immediately after
* the resolution queue has been closed. As a consequence, [action] must not
* add elements to the resolution queue.
+ *
+ * The queue is processed in FIFO order.
*/
void addPostProcessAction(Element element, PostProcessAction action) {
if (queueIsClosed) {
throw new SpannableAssertionFailure(element,
- "Resolution work list is closed.");
+ "Resolution work list is closed. "
+ "Trying to add post process action for $element");
}
postQueue.add(new PostProcessTask(element, action));
}
@@ -720,13 +722,16 @@
member.isAbstract(compiler) || generatedCode.containsKey(member);
void internalAddToWorkList(Element element) {
+ // Don't generate code for foreign elements.
+ if (element.isForeign(compiler)) return;
+
// Codegen inlines field initializers, so it does not need to add
// individual fields in the work list.
if (element.isField() && element.isInstanceMember()) return;
if (queueIsClosed) {
throw new SpannableAssertionFailure(element,
- "Codegen work list is closed.");
+ "Codegen work list is closed. Trying to add $element");
}
CodegenWorkItem workItem = new CodegenWorkItem(
element, itemCompilationContextCreator());
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
index d491aa4..2325cd9 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
@@ -2,17 +2,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.
-library container_tracer;
-
-import '../dart2jslib.dart' hide Selector, TypedSelector;
-import '../elements/elements.dart';
-import '../tree/tree.dart';
-import '../universe/universe.dart';
-import '../util/util.dart' show Link;
-import 'simple_types_inferrer.dart'
- show InferrerEngine, InferrerVisitor, LocalsHandler, TypeMaskSystem;
-import '../types/types.dart';
-import 'inferrer_visitor.dart';
+part of type_graph_inferrer;
/**
* A set of selector names that [List] implements, that we know do not
@@ -136,672 +126,154 @@
bool _VERBOSE = false;
-class InferrerEngineForContainerTracer
- implements MinimalInferrerEngine<TypeMask> {
+class ContainerTracerVisitor implements TypeInformationVisitor {
+ final ContainerTypeInformation container;
+ final TypeGraphInferrerEngine inferrer;
final Compiler compiler;
- InferrerEngineForContainerTracer(this.compiler);
+ // The set of [TypeInformation] where the traced container could
+ // flow in, and operations done on them.
+ final Set<TypeInformation> allUsers = new Set<TypeInformation>();
- TypeMask typeOfElement(Element element) {
- return compiler.typesTask.getGuaranteedTypeOfElement(element);
- }
+ // The list of found assignments to the container.
+ final List<TypeInformation> assignments = <TypeInformation>[];
- TypeMask returnTypeOfElement(Element element) {
- return compiler.typesTask.getGuaranteedReturnTypeOfElement(element);
- }
-
- TypeMask returnTypeOfSelector(Selector selector) {
- return compiler.typesTask.getGuaranteedTypeOfSelector(selector);
- }
-
- TypeMask typeOfNode(Node node) {
- return compiler.typesTask.getGuaranteedTypeOfNode(null, node);
- }
-
- Iterable<Element> getCallersOf(Element element) {
- return compiler.typesTask.typesInferrer.getCallersOf(element);
- }
-
- void recordTypeOfNonFinalField(Node node,
- Element field,
- TypeMask type) {}
-}
-
-/**
- * Global analysis phase that traces container instantiations in order to
- * find their element type.
- */
-class ContainerTracer extends CompilerTask {
- ContainerTracer(Compiler compiler) : super(compiler);
-
- String get name => 'List tracer';
-
- bool analyze() {
- measure(() {
- if (compiler.disableTypeInference) return;
- TypesInferrer inferrer = compiler.typesTask.typesInferrer;
- InferrerEngineForContainerTracer engine =
- new InferrerEngineForContainerTracer(compiler);
-
- // Walk over all created [ContainerTypeMask].
- inferrer.containerTypes.forEach((ContainerTypeMask mask) {
- // The element type has already been set for const containers.
- if (mask.elementType != null) return;
- new TracerForConcreteContainer(mask, this, compiler, engine).run();
- });
- });
- }
-}
-
-/**
- * A tracer for a specific container.
- */
-class TracerForConcreteContainer {
- final Compiler compiler;
- final ContainerTracer tracer;
- final InferrerEngineForContainerTracer inferrer;
- final ContainerTypeMask mask;
-
- final Node analyzedNode;
- final Element startElement;
-
- final List<Element> workList = <Element>[];
-
- /**
- * A set of elements where this list might escape.
- */
- final Set<Element> escapingElements = new Set<Element>();
-
- /**
- * A set of selectors that both use and update the list, for example
- * [: list[0]++; :] or [: list[0] |= 42; :].
- */
- final Set<Selector> constraints = new Set<Selector>();
-
- /**
- * A cache of setters that were already seen. Caching these
- * selectors avoid the filtering done in [addSettersToAnalysis].
- */
- final Set<Selector> seenSetterSelectors = new Set<Selector>();
-
- static const int MAX_ANALYSIS_COUNT = 11;
-
- TypeMask potentialType;
- int potentialLength;
- bool isLengthTrackingDisabled = false;
+ bool enableLengthTracking = true;
bool continueAnalyzing = true;
- TracerForConcreteContainer(ContainerTypeMask mask,
- this.tracer,
- this.compiler,
- this.inferrer)
- : analyzedNode = mask.allocationNode,
- startElement = mask.allocationElement,
- this.mask = mask;
+ static const int MAX_ANALYSIS_COUNT = 11;
+ final Set<Element> analyzedElements = new Set<Element>();
+
+ ContainerTracerVisitor(this.container, inferrer)
+ : this.inferrer = inferrer, this.compiler = inferrer.compiler;
void run() {
- int analysisCount = 0;
- workList.add(startElement);
+ // Add the assignments found at allocation site.
+ assignments.addAll(container.elementType.assignments);
+
+ // Collect the [TypeInformation] where the container can flow in,
+ // as well as the operations done on all these [TypeInformation]s.
+ List<TypeInformation> workList = <TypeInformation>[];
+ allUsers.add(container);
+ workList.add(container);
while (!workList.isEmpty) {
- if (workList.length + analysisCount > MAX_ANALYSIS_COUNT) {
+ TypeInformation user = workList.removeLast();
+ user.users.forEach((TypeInformation info) {
+ if (allUsers.contains(info)) return;
+ allUsers.add(info);
+ analyzedElements.add(info.owner);
+ if (info.reachedBy(user, inferrer)) {
+ workList.add(info);
+ }
+ });
+ if (analyzedElements.length > MAX_ANALYSIS_COUNT) {
bailout('Too many users');
break;
}
- Element currentElement = workList.removeLast().implementation;
- new ContainerTracerVisitor(currentElement, this).run();
- if (!continueAnalyzing) break;
- analysisCount++;
}
- if (!continueAnalyzing) {
- if (mask.forwardTo == compiler.typesTask.fixedListType) {
- mask.length = potentialLength;
+ if (continueAnalyzing) {
+ for (TypeInformation info in allUsers) {
+ info.accept(this);
+ if (!continueAnalyzing) break;
}
- mask.elementType = compiler.typesTask.dynamicType;
- return;
}
- // [potentialType] can be null if we did not find any instruction
- // that adds elements to the list.
- if (potentialType == null) {
- if (_VERBOSE) {
- print('Found empty type for $analyzedNode $startElement');
- }
- mask.elementType = new TypeMask.nonNullEmpty();
- return;
+ ContainerTypeMask mask = container.type;
+ if (!enableLengthTracking
+ && (mask.forwardTo != compiler.typesTask.fixedListType)) {
+ mask.length = null;
}
- // Walk over the found constraints and update the type according
- // to the selectors of these constraints.
- for (Selector constraint in constraints) {
- assert(constraint.isOperator());
- constraint = new TypedSelector(potentialType, constraint);
- potentialType = potentialType.union(
- inferrer.returnTypeOfSelector(constraint), compiler);
- }
+ TypeMask result = continueAnalyzing
+ ? inferrer.types.computeTypeMask(assignments)
+ : inferrer.types.dynamicType.type;
+
+ mask.elementType = result;
if (_VERBOSE) {
- print('$potentialType and $potentialLength '
- 'for $analyzedNode $startElement');
- }
- mask.elementType = potentialType;
- mask.length = potentialLength;
- }
-
- void disableLengthTracking() {
- if (mask.forwardTo == compiler.typesTask.fixedListType) {
- // Bogus update to a fixed list.
- return;
- }
- isLengthTrackingDisabled = true;
- potentialLength = null;
- }
-
- void setPotentialLength(int value) {
- if (isLengthTrackingDisabled) return;
- potentialLength = value;
- }
-
- void unionPotentialTypeWith(TypeMask newType) {
- assert(newType != null);
- potentialType = potentialType == null
- ? newType
- : newType.union(potentialType, compiler);
- if (potentialType == compiler.typesTask.dynamicType) {
- bailout('Moved to dynamic');
+ print('$result and ${mask.length} '
+ 'for ${mask.allocationNode} ${mask.allocationElement}');
}
}
- void addEscapingElement(element) {
- element = element.implementation;
- if (escapingElements.contains(element)) return;
- escapingElements.add(element);
- if (element.isField() || element.isGetter() || element.isFunction()) {
- for (Element e in inferrer.getCallersOf(element)) {
- addElementToAnalysis(e);
- }
- } else if (element.isParameter()) {
- addElementToAnalysis(element.enclosingElement);
- } else if (element.isFieldParameter()) {
- addEscapingElement(element.fieldElement);
- }
- }
-
- void addSettersToAnalysis(Selector selector) {
- assert(selector.isSetter());
- if (seenSetterSelectors.contains(selector)) return;
- seenSetterSelectors.add(selector);
- for (var e in compiler.world.allFunctions.filter(selector)) {
- e = e.implementation;
- if (e.isField()) {
- addEscapingElement(e);
- } else {
- FunctionSignature signature = e.computeSignature(compiler);
- signature.forEachRequiredParameter((Element e) {
- addEscapingElement(e);
- });
- }
- }
- }
-
- void addElementToAnalysis(Element element) {
- workList.add(element);
- }
-
- TypeMask bailout(String reason) {
+ void bailout(String reason) {
if (_VERBOSE) {
- print('Bailout on $analyzedNode $startElement because of $reason');
+ ContainerTypeMask mask = container.type;
+ print('Bailing out on ${mask.allocationNode} ${mask.allocationElement} '
+ 'because: $reason');
}
continueAnalyzing = false;
- return compiler.typesTask.dynamicType;
+ enableLengthTracking = false;
}
- bool couldBeTheList(resolved) {
- if (resolved is Selector) {
- return escapingElements.any((e) {
- return e.isInstanceMember() && resolved.applies(e, compiler);
- });
- } else if (resolved is Node) {
- return analyzedNode == resolved;
- } else {
- assert(resolved is Element);
- return escapingElements.contains(resolved);
+ visitNarrowTypeInformation(NarrowTypeInformation info) {}
+ visitPhiElementTypeInformation(PhiElementTypeInformation info) {}
+ visitElementInContainerTypeInformation(
+ ElementInContainerTypeInformation info) {}
+ visitContainerTypeInformation(ContainerTypeInformation info) {}
+ visitConcreteTypeInformation(ConcreteTypeInformation info) {}
+
+ visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
+ bailout('Passed to a closure');
+ }
+
+ visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+ analyzedElements.add(info.caller);
+ Element called = info.calledElement;
+ if (called.isForeign(compiler) && called.name == const SourceString('JS')) {
+ bailout('Used in JS ${info.call}');
}
}
- void recordConstraint(Selector selector) {
- constraints.add(selector);
- }
-}
-
-class ContainerTracerVisitor
- extends InferrerVisitor<TypeMask, InferrerEngineForContainerTracer> {
- final Element analyzedElement;
- final TracerForConcreteContainer tracer;
- final bool visitingClosure;
-
- ContainerTracerVisitor(element, tracer, [LocalsHandler<TypeMask> locals])
- : super(element, tracer.inferrer, new TypeMaskSystem(tracer.compiler),
- tracer.compiler, locals),
- this.analyzedElement = element,
- this.tracer = tracer,
- visitingClosure = locals != null;
-
- bool escaping = false;
- bool visitingInitializers = false;
-
- void run() {
- compiler.withCurrentElement(analyzedElement, () {
- visit(analyzedElement.parseNode(compiler));
- });
- }
-
- /**
- * Executes [f] and returns whether it triggered the list to escape.
- */
- bool visitAndCatchEscaping(Function f) {
- bool oldEscaping = escaping;
- escaping = false;
- f();
- bool foundEscaping = escaping;
- escaping = oldEscaping;
- return foundEscaping;
- }
-
- /**
- * Visits the [arguments] of [callee], and records the parameters
- * that could hold the container as escaping.
- *
- * Returns whether the container escaped.
- */
- bool visitArguments(Link<Node> arguments, /* Element or Selector */ callee) {
- List<int> indices = [];
- int index = 0;
- for (Node node in arguments) {
- if (visitAndCatchEscaping(() { visit(node); })) {
- indices.add(index);
- }
- index++;
- }
- if (!indices.isEmpty) {
- Iterable<Element> callees;
- if (callee is Element) {
- // No need to go further, we know the call will throw.
- if (callee.isErroneous()) return false;
- callees = [callee];
- } else {
- assert(callee is Selector);
- callees = compiler.world.allFunctions.filter(callee);
- }
- for (var e in callees) {
- e = e.implementation;
- if (e.isField()) {
- tracer.bailout('Passed to a closure');
- break;
- }
- FunctionSignature signature = e.computeSignature(compiler);
- index = 0;
- int parameterIndex = 0;
- signature.forEachRequiredParameter((Element parameter) {
- if (index < indices.length && indices[index] == parameterIndex) {
- tracer.addEscapingElement(parameter);
- index++;
- }
- parameterIndex++;
- });
- if (index != indices.length) {
- tracer.bailout('Used in a named parameter or closure');
- }
- }
- return true;
- } else {
- return false;
- }
- }
-
- TypeMask visitFunctionExpression(FunctionExpression node) {
- FunctionElement function = elements[node];
- if (function != analyzedElement) {
- // Visiting a closure.
- LocalsHandler closureLocals = new LocalsHandler<TypeMask>.from(
- locals, node, useOtherTryBlock: false);
- new ContainerTracerVisitor(function, tracer, closureLocals).run();
- return types.functionType;
- } else {
- // Visiting [analyzedElement].
- FunctionSignature signature = function.computeSignature(compiler);
- signature.forEachParameter((element) {
- locals.update(element, inferrer.typeOfElement(element), node);
- });
- visitingInitializers = true;
- visit(node.initializers);
- visitingInitializers = false;
- visit(node.body);
- return null;
- }
- }
-
- TypeMask visitLiteralList(LiteralList node) {
- if (node.isConst()) {
- return inferrer.typeOfNode(node);
- }
- if (tracer.couldBeTheList(node)) {
- escaping = true;
- int length = 0;
- for (Node element in node.elements.nodes) {
- tracer.unionPotentialTypeWith(visit(element));
- length++;
- }
- tracer.setPotentialLength(length);
- } else {
- node.visitChildren(this);
- }
- return types.growableListType;
- }
-
- TypeMask visitSendSet(SendSet node) {
- bool isReceiver = visitAndCatchEscaping(() {
- visit(node.receiver);
- });
- return handleSendSet(node, isReceiver);
- }
-
- TypeMask handleSendSet(SendSet node, bool isReceiver) {
- TypeMask rhsType;
- TypeMask indexType;
-
- 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 == '--';
- bool isIndexEscaping = false;
- bool isValueEscaping = false;
- if (isIncrementOrDecrement) {
- rhsType = types.intType;
- if (node.isIndex) {
- isIndexEscaping = visitAndCatchEscaping(() {
- indexType = visit(node.arguments.head);
- });
- }
- } else if (node.isIndex) {
- isIndexEscaping = visitAndCatchEscaping(() {
- indexType = visit(node.arguments.head);
- });
- isValueEscaping = visitAndCatchEscaping(() {
- rhsType = visit(node.arguments.tail.head);
- });
- } else {
- isValueEscaping = visitAndCatchEscaping(() {
- rhsType = visit(node.arguments.head);
- });
- }
-
- Element element = elements[node];
-
- if (node.isIndex) {
- if (isReceiver) {
- if (op == '=') {
- tracer.unionPotentialTypeWith(rhsType);
- } else {
- tracer.recordConstraint(operatorSelector);
- }
- } else if (isIndexEscaping || isValueEscaping) {
- // If the index or value is escaping, iterate over all
- // potential targets, and mark their parameter as escaping.
- for (var e in compiler.world.allFunctions.filter(setterSelector)) {
- e = e.implementation;
- FunctionSignature signature = e.computeSignature(compiler);
- int index = 0;
- signature.forEachRequiredParameter((Element parameter) {
- if (index == 0 && isIndexEscaping) {
- tracer.addEscapingElement(parameter);
- }
- if (index == 1 && isValueEscaping) {
- tracer.addEscapingElement(parameter);
- }
- index++;
- });
- }
- }
- } else if (isReceiver) {
- if (setterSelector.name == const SourceString('length')) {
- tracer.disableLengthTracking();
- tracer.unionPotentialTypeWith(compiler.typesTask.nullType);
- }
- } else if (isValueEscaping) {
- if (element != null
- && element.isField()
- && setterSelector == null
- && !visitingInitializers) {
- // Initializer at declaration of a field.
- assert(analyzedElement.isField());
- tracer.addEscapingElement(analyzedElement);
- } else if (element != null
- && (!element.isInstanceMember() || visitingInitializers)) {
- // A local, a static element, or a field in an initializer.
- tracer.addEscapingElement(element);
- } else {
- tracer.addSettersToAnalysis(setterSelector);
- }
- }
-
- TypeMask result;
- if (node.isPostfix) {
- // We don't check if [getterSelector] could be the container because
- // a list++ will always throw.
- result = inferrer.returnTypeOfSelector(getterSelector);
- } else if (op != '=') {
- // We don't check if [getterSelector] could be the container because
- // a list += 42 will always throw.
- result = inferrer.returnTypeOfSelector(operatorSelector);
- } else {
- if (isValueEscaping) {
- escaping = true;
- }
- result = rhsType;
- }
-
- if (Elements.isLocal(element)) {
- locals.update(element, result, node);
- }
-
- return result;
- }
-
- TypeMask visitSuperSend(Send node) {
- Element element = elements[node];
- if (!node.isPropertyAccess) {
- visitArguments(node.arguments, element);
- }
-
- if (tracer.couldBeTheList(element)) {
- escaping = true;
- }
-
- if (element.isField()) {
- return inferrer.typeOfElement(element);
- } else if (element.isFunction()) {
- return inferrer.returnTypeOfElement(element);
- } else {
- return types.dynamicType;
- }
- }
-
- TypeMask visitStaticSend(Send node) {
- Element element = elements[node];
-
- if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
- visitArguments(node.arguments, element);
- if (tracer.couldBeTheList(node)) {
- escaping = true;
- }
- return inferrer.typeOfNode(node);
- } else if (Elements.isFixedListConstructorCall(element, node, compiler)) {
- visitArguments(node.arguments, element);
- if (tracer.couldBeTheList(node)) {
- tracer.unionPotentialTypeWith(types.nullType);
- escaping = true;
- LiteralInt length = node.arguments.head.asLiteralInt();
- if (length != null) {
- tracer.setPotentialLength(length.value);
- }
- }
- return inferrer.typeOfNode(node);
- } else if (Elements.isFilledListConstructorCall(element, node, compiler)) {
- if (tracer.couldBeTheList(node)) {
- escaping = true;
- visit(node.arguments.head);
- TypeMask fillWithType = visit(node.arguments.tail.head);
- tracer.unionPotentialTypeWith(fillWithType);
- LiteralInt length = node.arguments.head.asLiteralInt();
- if (length != null) {
- tracer.setPotentialLength(length.value);
- }
- } else {
- visitArguments(node.arguments, element);
- }
- return inferrer.typeOfNode(node);
- }
-
- bool isEscaping = visitArguments(node.arguments, element);
-
- if (element.isForeign(compiler)) {
- if (isEscaping) return tracer.bailout('Used in a JS');
- }
-
- if (tracer.couldBeTheList(element)) {
- escaping = true;
- }
-
- if (element.isFunction() || element.isConstructor()) {
- return inferrer.returnTypeOfElement(element);
- } else {
- // Closure call or unresolved.
- return types.dynamicType;
- }
- }
-
- TypeMask visitGetterSend(Send node) {
- Element element = elements[node];
- Selector selector = elements.getSelector(node);
- if (Elements.isStaticOrTopLevelField(element)) {
- if (tracer.couldBeTheList(element)) {
- escaping = true;
- }
- return inferrer.typeOfElement(element);
- } else if (Elements.isInstanceSend(node, elements)) {
- return visitDynamicSend(node);
- } else if (Elements.isStaticOrTopLevelFunction(element)) {
- return types.functionType;
- } else if (Elements.isErroneousElement(element)) {
- return types.dynamicType;
- } else if (Elements.isLocal(element)) {
- if (tracer.couldBeTheList(element)) {
- escaping = true;
- }
- return locals.use(element);
- } else {
- node.visitChildren(this);
- return types.dynamicType;
- }
- }
-
- TypeMask visitClosureSend(Send node) {
- assert(node.receiver == null);
- visit(node.selector);
- bool isEscaping =
- visitArguments(node.arguments, elements.getSelector(node));
-
- if (isEscaping) return tracer.bailout('Passed to a closure');
- return types.dynamicType;
- }
-
- TypeMask visitDynamicSend(Send node) {
- bool isReceiver = visitAndCatchEscaping(() {
- visit(node.receiver);
- });
- return handleDynamicSend(node, isReceiver);
- }
-
- TypeMask handleDynamicSend(Send node, bool isReceiver) {
- Selector selector = elements.getSelector(node);
+ visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
+ Selector selector = info.selector;
String selectorName = selector.name.slowToString();
- if (isReceiver && !okSelectorsSet.contains(selectorName)) {
- if (selector.isCall()
- && (selectorName == 'add' || selectorName == 'insert')) {
- TypeMask argumentType;
- if (node.arguments.isEmpty
- || (selectorName == 'insert' && node.arguments.tail.isEmpty)) {
- return tracer.bailout('Invalid "add" or "insert" call on a list');
- }
- bool isEscaping = visitAndCatchEscaping(() {
- argumentType = visit(node.arguments.head);
- if (selectorName == 'insert') {
- argumentType = visit(node.arguments.tail.head);
+ if (allUsers.contains(info.receiver)) {
+ if (!okSelectorsSet.contains(selectorName)) {
+ if (selector.isCall()) {
+ int positionalLength = info.arguments.positional.length;
+ if (selectorName == 'add') {
+ if (positionalLength == 1) {
+ assignments.add(info.arguments.positional[0]);
+ }
+ } else if (selectorName == 'insert') {
+ if (positionalLength == 2) {
+ assignments.add(info.arguments.positional[1]);
+ }
+ } else {
+ bailout('Used in a not-ok selector');
+ return;
}
- });
- if (isEscaping) {
- return tracer.bailout('List containing itself');
+ } else if (selector.isIndexSet()) {
+ assignments.add(info.arguments.positional[1]);
+ } else if (!selector.isIndex()) {
+ bailout('Used in a not-ok selector');
+ return;
}
- tracer.unionPotentialTypeWith(argumentType);
- } else {
- return tracer.bailout('Send with the node as receiver $node');
}
- } else if (!node.isPropertyAccess) {
- visitArguments(node.arguments, selector);
+ if (!doNotChangeLengthSelectorsSet.contains(selectorName)) {
+ enableLengthTracking = false;
+ }
+ if (selectorName == 'length' && selector.isSetter()) {
+ enableLengthTracking = false;
+ assignments.add(inferrer.types.nullType);
+ }
+ } else if (selector.isCall()
+ && !info.targets.every((element) => element.isFunction())) {
+ bailout('Passed to a closure');
+ return;
}
- if (isReceiver && !doNotChangeLengthSelectorsSet.contains(selectorName)) {
- tracer.disableLengthTracking();
- }
- if (tracer.couldBeTheList(selector)) {
- escaping = true;
- }
- return inferrer.returnTypeOfSelector(selector);
}
- TypeMask visitReturn(Return node) {
- if (node.expression == null) {
- return types.nullType;
- }
-
- TypeMask type;
- bool isEscaping = visitAndCatchEscaping(() {
- type = visit(node.expression);
- });
-
- if (isEscaping) {
- if (visitingClosure) {
- tracer.bailout('Return from closure');
- } else {
- tracer.addEscapingElement(analyzedElement);
- }
- }
- return type;
+ bool isClosure(Element element) {
+ if (!element.isFunction()) return false;
+ Element outermost = element.getOutermostEnclosingMemberOrTopLevel();
+ return outermost.declaration != element.declaration;
}
- TypeMask visitForIn(ForIn node) {
- visit(node.expression);
- Selector iteratorSelector = elements.getIteratorSelector(node);
- Selector currentSelector = elements.getCurrentSelector(node);
-
- TypeMask iteratorType = inferrer.returnTypeOfSelector(iteratorSelector);
- TypeMask currentType = inferrer.returnTypeOfSelector(currentSelector);
-
- // We nullify the type in case there is no element in the
- // iterable.
- currentType = currentType.nullable();
-
- Node identifier = node.declaredIdentifier;
- Element element = elements[identifier];
- if (Elements.isLocal(element)) {
- locals.update(element, currentType, node);
+ visitElementTypeInformation(ElementTypeInformation info) {
+ if (isClosure(info.element)) {
+ bailout('Returned from a closure');
}
-
- return handleLoop(node, () {
- visit(node.body);
- });
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
index bc58690..2a9d49b 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
@@ -31,10 +31,11 @@
T get stringType;
T get typeType;
- T nonNullSubtype(DartType type);
- T nonNullSubclass(DartType type);
- T nonNullExact(DartType type);
+ T nonNullSubtype(ClassElement type);
+ T nonNullSubclass(ClassElement type);
+ T nonNullExact(ClassElement type);
T nonNullEmpty();
+ bool isNull(T type);
Selector newTypedSelector(T receiver, Selector selector);
T allocateContainer(T type,
@@ -680,7 +681,7 @@
// 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);
+ return types.nonNullSubtype(compiler.symbolClass);
}
T visitTypeReferenceSend(Send node) {
@@ -701,11 +702,11 @@
if (_thisType != null) return _thisType;
ClassElement cls = outermostElement.getEnclosingClass();
if (compiler.world.isUsedAsMixin(cls)) {
- return _thisType = types.nonNullSubtype(cls.rawType);
+ return _thisType = types.nonNullSubtype(cls);
} else if (compiler.world.hasAnySubclass(cls)) {
- return _thisType = types.nonNullSubclass(cls.rawType);
+ return _thisType = types.nonNullSubclass(cls);
} else {
- return _thisType = types.nonNullExact(cls.rawType);
+ return _thisType = types.nonNullExact(cls);
}
}
@@ -713,7 +714,7 @@
T get superType {
if (_superType != null) return _superType;
return _superType = types.nonNullExact(
- outermostElement.getEnclosingClass().superclass.rawType);
+ outermostElement.getEnclosingClass().superclass);
}
T visitIdentifier(Identifier node) {
@@ -730,20 +731,54 @@
isChecks.add(node);
}
+ void potentiallyAddNullCheck(Send node, Node receiver) {
+ if (!accumulateIsChecks) return;
+ if (!Elements.isLocal(elements[receiver])) return;
+ isChecks.add(node);
+ }
+
void updateIsChecks(List<Node> tests, {bool usePositive}) {
- if (tests == null) return;
- for (Send node in tests) {
- if (node.isIsNotCheck) {
- if (usePositive) continue;
- } else {
- if (!usePositive) continue;
- }
- DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
- Element element = elements[node.receiver];
+ void narrow(Element element, DartType type, Node node) {
T existing = locals.use(element);
T newType = types.narrowType(existing, type, isNullable: false);
locals.update(element, newType, node);
}
+
+ if (tests == null) return;
+ for (Send node in tests) {
+ if (node.isTypeTest) {
+ if (node.isIsNotCheck) {
+ if (usePositive) continue;
+ } else {
+ if (!usePositive) continue;
+ }
+ DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
+ narrow(elements[node.receiver], type, node);
+ } else {
+ Element receiverElement = elements[node.receiver];
+ Element argumentElement = elements[node.arguments.first];
+ String operator = node.selector.asOperator().source.stringValue;
+ if ((operator == '==' && usePositive)
+ || (operator == '!=' && !usePositive)) {
+ // Type the elements as null.
+ if (Elements.isLocal(receiverElement)) {
+ locals.update(receiverElement, types.nullType, node);
+ }
+ if (Elements.isLocal(argumentElement)) {
+ locals.update(argumentElement, types.nullType, node);
+ }
+ } else {
+ // Narrow the elements to a non-null type.
+ DartType objectType = compiler.objectClass.rawType;
+ if (Elements.isLocal(receiverElement)) {
+ narrow(receiverElement, objectType, node);
+ }
+ if (Elements.isLocal(argumentElement)) {
+ narrow(argumentElement, objectType, node);
+ }
+ }
+ }
+ }
}
T visitOperatorSend(Send node) {
@@ -979,7 +1014,7 @@
DartType type = elements.getType(node.type);
T mask = type == null || type.treatAsDynamic
? types.dynamicType
- : types.nonNullSubtype(type.asRaw());
+ : types.nonNullSubtype(type.element);
locals.update(elements[exception], mask, node);
}
Node trace = node.trace;
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
index 6cdbd1f..932eb33 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
@@ -44,7 +44,7 @@
return type;
} else {
assert(annotation.kind == TypeKind.INTERFACE);
- otherType = new TypeMask.nonNullSubtype(annotation);
+ otherType = new TypeMask.nonNullSubtype(annotation.element);
}
if (isNullable) otherType = otherType.nullable();
if (type == null) return otherType;
@@ -85,10 +85,14 @@
TypeMask get constMapType => compiler.typesTask.constMapType;
TypeMask get stringType => compiler.typesTask.stringType;
TypeMask get typeType => compiler.typesTask.typeType;
+ bool isNull(TypeMask mask) => mask.isEmpty && mask.isNullable;
- 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 nonNullSubtype(ClassElement type)
+ => new TypeMask.nonNullSubtype(type.declaration);
+ TypeMask nonNullSubclass(ClassElement type)
+ => new TypeMask.nonNullSubclass(type.declaration);
+ TypeMask nonNullExact(ClassElement type)
+ => new TypeMask.nonNullExact(type.declaration);
TypeMask nonNullEmpty() => new TypeMask.nonNullEmpty();
TypeMask allocateContainer(TypeMask type,
@@ -296,7 +300,7 @@
for (var type in typesReturned) {
T mappedType;
if (type == native.SpecialType.JsObject) {
- mappedType = types.nonNullExact(compiler.objectClass.rawType);
+ mappedType = types.nonNullExact(compiler.objectClass);
} else if (type.element == compiler.stringClass) {
mappedType = types.stringType;
} else if (type.element == compiler.intClass) {
@@ -314,15 +318,15 @@
} else if (type.isDynamic) {
return types.dynamicType;
} else if (!compiler.world.hasAnySubtype(type.element)) {
- mappedType = types.nonNullExact(type.element.rawType);
+ mappedType = types.nonNullExact(type.element);
} 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);
+ mappedType = types.nonNullSubclass(element);
} else {
- mappedType = types.nonNullSubtype(element.rawType);
+ mappedType = types.nonNullSubtype(element);
}
}
returnType = types.computeLUB(returnType, mappedType);
@@ -474,7 +478,7 @@
}
});
}
- returnType = types.nonNullExact(cls.rawType);
+ returnType = types.nonNullExact(cls);
} else {
signature.forEachParameter((element) {
locals.update(element, inferrer.typeOfElement(element), node);
@@ -535,38 +539,31 @@
}
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++;
- }
+ // 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.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);
- });
- }
+ ? types.allocatePhi(null, null, type)
+ : types.addPhiInput(null, elementType, type);
+ length++;
+ }
+ elementType = elementType == null
+ ? types.nonNullEmpty()
+ : types.simplifyPhi(null, null, elementType);
+ T containerType = node.isConst()
+ ? types.constListType
+ : types.growableListType;
+ return types.allocateContainer(
+ containerType,
+ node,
+ outermostElement,
+ elementType,
+ length);
+ });
}
bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
@@ -823,12 +820,31 @@
if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
return inferrer.concreteTypes.putIfAbsent(
node, () => types.allocateContainer(
- types.growableListType, node, outermostElement));
+ types.growableListType, node, outermostElement,
+ types.nonNullEmpty(), 0));
} else if (Elements.isFixedListConstructorCall(element, node, compiler)
|| Elements.isFilledListConstructorCall(element, node, compiler)) {
+
+ int initialLength;
+ T elementType;
+ if (Elements.isFixedListConstructorCall(element, node, compiler)) {
+ LiteralInt length = node.arguments.head.asLiteralInt();
+ if (length != null) {
+ initialLength = length.value;
+ }
+ elementType = types.nullType;
+ } else {
+ LiteralInt length = node.arguments.head.asLiteralInt();
+ if (length != null) {
+ initialLength = length.value;
+ }
+ elementType = arguments.positional[1];
+ }
+
return inferrer.concreteTypes.putIfAbsent(
node, () => types.allocateContainer(
- types.fixedListType, node, outermostElement));
+ types.fixedListType, node, outermostElement,
+ elementType, initialLength));
} else if (element.isFunction() || element.isConstructor()) {
return returnType;
} else {
@@ -983,6 +999,16 @@
ArgumentsTypes arguments = node.isPropertyAccess
? null
: analyzeArguments(node.arguments);
+ if (selector.name == const SourceString('==')
+ || selector.name == const SourceString('!=')) {
+ if (types.isNull(receiverType)) {
+ potentiallyAddNullCheck(node, node.arguments.head);
+ return types.boolType;
+ } else if (types.isNull(arguments.positional[0])) {
+ potentiallyAddNullCheck(node, node.receiver);
+ return types.boolType;
+ }
+ }
return handleDynamicSend(node, selector, receiverType, arguments);
}
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
index fc8e211..2eb6270 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -7,7 +7,7 @@
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 '../tree/tree.dart' show LiteralList, Node;
import '../types/types.dart' show TypeMask, ContainerTypeMask, TypesInferrer;
import '../universe/universe.dart' show Selector, TypedSelector, SideEffects;
import '../dart2jslib.dart' show Compiler, SourceString, TreeElementMapping;
@@ -18,27 +18,28 @@
import '../dart2jslib.dart' show invariant;
part 'type_graph_nodes.dart';
+part 'container_tracer.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'
+Set<Selector> returnsElementTypeSet = new Set<Selector>.from(
+ <Selector>[
+ new Selector.getter(const SourceString('first'), null),
+ new Selector.getter(const SourceString('last'), null),
+ new Selector.getter(const SourceString('single'), null),
+ new Selector.call(const SourceString('singleWhere'), null, 1),
+ new Selector.call(const SourceString('elementAt'), null, 1),
+ new Selector.index(),
+ new Selector.call(const SourceString('removeAt'), null, 1),
+ new Selector.call(const SourceString('removeLast'), null, 0)
]);
bool returnsElementType(Selector selector) {
return (selector.mask != null)
&& selector.mask.isContainer
- && returnsElementTypeSet.contains(selector.name.slowToString());
+ && returnsElementTypeSet.contains(selector.asUntyped);
}
class TypeInformationSystem extends TypeSystem<TypeInformation> {
@@ -203,7 +204,7 @@
return type;
} else {
assert(annotation.kind == TypeKind.INTERFACE);
- otherType = new TypeMask.nonNullSubtype(annotation);
+ otherType = new TypeMask.nonNullSubtype(annotation.element);
}
if (isNullable) otherType = otherType.nullable();
if (type.type.isExact) {
@@ -228,28 +229,36 @@
});
}
- TypeInformation nonNullSubtype(DartType type) {
- return getConcreteTypeFor(new TypeMask.nonNullSubtype(type));
+ TypeInformation nonNullSubtype(ClassElement type) {
+ return getConcreteTypeFor(new TypeMask.nonNullSubtype(type.declaration));
}
- TypeInformation nonNullSubclass(DartType type) {
- return getConcreteTypeFor(new TypeMask.nonNullSubclass(type));
+ TypeInformation nonNullSubclass(ClassElement type) {
+ return getConcreteTypeFor(new TypeMask.nonNullSubclass(type.declaration));
}
- TypeInformation nonNullExact(DartType type) {
- return getConcreteTypeFor(new TypeMask.nonNullExact(type));
+ TypeInformation nonNullExact(ClassElement type) {
+ return getConcreteTypeFor(new TypeMask.nonNullExact(type.declaration));
}
TypeInformation nonNullEmpty() {
return nonNullEmptyType;
}
+ bool isNull(TypeInformation type) {
+ return type == nullType;
+ }
+
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;
+ // Set the element type now for const lists, so that the inferrer
+ // can use it.
+ mask.elementType = (type.type == compiler.typesTask.constListType)
+ ? elementType.type
+ : null;
mask.length = length;
TypeInformation element =
new ElementInContainerTypeInformation(elementType, mask);
@@ -388,7 +397,7 @@
compiler.log('Added $addedInGraph elements in inferencing graph.');
compiler.progress.reset();
}
- // Force the creation of the [ElementTypeInformation] to ensure it is
+ // Force the creation of the [ElementTypeInformation] to ensure it is
// in the graph.
types.getInferredTypeOf(element);
@@ -460,6 +469,7 @@
}
processLoopInformation();
+ types.allocatedContainers.values.forEach(analyzeContainer);
}
void processLoopInformation() {
@@ -498,6 +508,11 @@
}
}
+ void analyzeContainer(ContainerTypeInformation info) {
+ if (info.elementType.isInConstContainer) return;
+ new ContainerTracerVisitor(info, this).run();
+ }
+
void buildWorkQueue() {
workQueue.addAll(types.typeInformations.values);
workQueue.addAll(types.allocatedTypes);
@@ -506,7 +521,7 @@
/**
* Update the assignments to parameters in the graph. [remove] tells
- * wheter assignments must be added or removed. If [init] is true,
+ * wheter assignments must be added or removed. If [init] is false,
* parameters are added to the work queue.
*/
void updateParameterAssignments(TypeInformation caller,
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
index fc7bfb5..539db8a 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -48,7 +48,7 @@
TypeInformation([users, assignments])
: users = (users == null) ? new Set<TypeInformation>() : users,
assignments = (assignments == null) ? <TypeInformation>[] : assignments;
-
+
void addUser(TypeInformation user) {
assert(!user.isConcrete);
@@ -61,10 +61,14 @@
}
void addAssignment(TypeInformation assignment) {
- if (abandonInferencing) return;
// Cheap one-level cycle detection.
if (assignment == this) return;
- assignments.add(assignment);
+ if (!abandonInferencing) {
+ assignments.add(assignment);
+ }
+ // Even if we abandon inferencing on this [TypeInformation] we
+ // need to collect the users, so that phases that track where
+ // elements flow in still work.
assignment.addUser(this);
}
@@ -92,6 +96,17 @@
assignments = const <TypeInformation>[];
users = const <TypeInformation>[];
}
+
+ bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
+ return true;
+ }
+
+ accept(TypeInformationVisitor visitor);
+
+ /// The [Element] where this [TypeInformation] was created. May be
+ /// for some [TypeInformation] nodes, where we do not need to store
+ /// the information.
+ Element get owner => null;
}
/**
@@ -157,7 +172,7 @@
* - 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;
@@ -227,7 +242,7 @@
InterfaceType rawType = element.computeType(inferrer.compiler).asRaw();
return rawType.treatAsDynamic
? inferrer.types.dynamicType.type
- : new TypeMask.subtype(rawType);
+ : new TypeMask.subtype(rawType.element);
} else {
assert(element.isFunction()
|| element.isGetter()
@@ -268,6 +283,12 @@
}
String toString() => 'Element $element $type';
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitElementTypeInformation(this);
+ }
+
+ Element get owner => element.getOutermostEnclosingMemberOrTopLevel();
}
/**
@@ -301,6 +322,8 @@
/// Return an iterable over the targets of this call.
Iterable<Element> get callees;
+
+ Element get owner => caller;
}
class StaticCallSiteTypeInformation extends CallSiteTypeInformation {
@@ -344,6 +367,14 @@
}
Iterable<Element> get callees => [calledElement.implementation];
+
+ bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
+ return info == inferrer.types.getInferredTypeOf(calledElement);
+ }
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitStaticCallSiteTypeInformation(this);
+ }
}
class DynamicCallSiteTypeInformation extends CallSiteTypeInformation {
@@ -454,7 +485,7 @@
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
@@ -506,7 +537,17 @@
super.giveUp(inferrer);
}
- String toString() => 'Call site $call ${receiver.type} $type';
+ bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
+ return targets
+ .map((element) => inferrer.types.getInferredTypeOf(element))
+ .any((other) => other == info);
+ }
+
+ String toString() => 'Call site $call on ${receiver.type} $type';
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitDynamicCallSiteTypeInformation(this);
+ }
}
class ClosureCallSiteTypeInformation extends CallSiteTypeInformation {
@@ -529,10 +570,14 @@
}
Iterable<Element> get callees {
- throw new UnsupportedError("Cannot compute callees of a closure.");
+ throw new UnsupportedError("Cannot compute callees of a closure call.");
}
String toString() => 'Closure call $call on $closure';
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitClosureCallSiteTypeInformation(this);
+ }
}
/**
@@ -569,6 +614,10 @@
}
String toString() => 'Type $type';
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitConcreteTypeInformation(this);
+ }
}
/**
@@ -602,23 +651,28 @@
}
String toString() => 'Narrow ${assignments.first} to $typeAnnotation $type';
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitNarrowTypeInformation(this);
+ }
}
/**
- * A [ContainerTypeInformation] is a [ConcreteTypeInformation] created
+ * A [ContainerTypeInformation] is a [TypeInformation] created
* for each `List` instantiations.
*/
-class ContainerTypeInformation extends ConcreteTypeInformation {
- final TypeInformation elementType;
+class ContainerTypeInformation extends TypeInformation {
+ final ElementInContainerTypeInformation elementType;
- ContainerTypeInformation(containerType, this.elementType)
- : super(containerType);
-
- void addUser(TypeInformation user) {
- elementType.addUser(user);
+ ContainerTypeInformation(containerType, this.elementType) {
+ type = containerType;
}
String toString() => 'Container type $type';
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitContainerTypeInformation(this);
+ }
}
/**
@@ -629,17 +683,27 @@
final ContainerTypeMask container;
ElementInContainerTypeInformation(elementType, this.container) {
- // [elementType] is not null for const lists.
if (elementType != null) addAssignment(elementType);
}
+ bool get isInConstContainer {
+ LiteralList literal = container.allocationNode.asLiteralList();
+ return (literal != null) && literal.isConst();
+ }
+
TypeMask refine(TypeGraphInferrerEngine inferrer) {
- if (assignments.isEmpty) return inferrer.types.dynamicType.type;
+ if (!isInConstContainer) {
+ return inferrer.types.dynamicType.type;
+ }
return container.elementType =
inferrer.types.computeTypeMask(assignments);
}
String toString() => 'Element in container $type';
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitElementInContainerTypeInformation(this);
+ }
}
/**
@@ -658,4 +722,21 @@
}
String toString() => 'Phi $element $type';
+
+ accept(TypeInformationVisitor visitor) {
+ return visitor.visitPhiElementTypeInformation(this);
+ }
+}
+
+abstract class TypeInformationVisitor<T> {
+ T visitNarrowTypeInformation(NarrowTypeInformation info);
+ T visitPhiElementTypeInformation(PhiElementTypeInformation info);
+ T visitElementInContainerTypeInformation(
+ ElementInContainerTypeInformation info);
+ T visitContainerTypeInformation(ContainerTypeInformation info);
+ T visitConcreteTypeInformation(ConcreteTypeInformation info);
+ T visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info);
+ T visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info);
+ T visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info);
+ T visitElementTypeInformation(ElementTypeInformation info);
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index b2cd1d9..754e5aa 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -319,17 +319,9 @@
/// True if there isn't sufficient @MirrorsUsed data.
bool hasInsufficientMirrorsUsed = false;
- /// List of instantiated types from metadata. If metadata must be preserved,
- /// these types must registered.
- final List<Dependency> metadataInstantiatedTypes = <Dependency>[];
-
- /// List of elements used from metadata. If metadata must be preserved,
- /// these elements must be compiled.
- final List<Element> metadataStaticUse = <Element>[];
-
- /// List of tear-off functions referenced from metadata. If metadata must be
- /// preserved, these elements must be compiled.
- final List<FunctionElement> metadataGetOfStaticFunction = <FunctionElement>[];
+ /// List of constants from metadata. If metadata must be preserved,
+ /// these constants must be registered.
+ final List<Dependency> metadataConstants = <Dependency>[];
/// List of symbols that the user has requested for reflection.
final Set<String> symbolsUsed = new Set<String>();
@@ -660,17 +652,17 @@
validateInterceptorImplementsAllObjectMethods(jsInterceptorClass);
stringType = new HBoundedType(
- new TypeMask.nonNullExact(jsStringClass.rawType));
+ new TypeMask.nonNullExact(jsStringClass));
indexablePrimitiveType = new HBoundedType(
- new TypeMask.nonNullSubtype(jsIndexableClass.rawType));
+ new TypeMask.nonNullSubtype(jsIndexableClass));
readableArrayType = new HBoundedType(
- new TypeMask.nonNullSubclass(jsArrayClass.rawType));
+ new TypeMask.nonNullSubclass(jsArrayClass));
mutableArrayType = new HBoundedType(
- new TypeMask.nonNullSubclass(jsMutableArrayClass.rawType));
+ new TypeMask.nonNullSubclass(jsMutableArrayClass));
fixedArrayType = new HBoundedType(
- new TypeMask.nonNullExact(jsFixedArrayClass.rawType));
+ new TypeMask.nonNullExact(jsFixedArrayClass));
extendableArrayType = new HBoundedType(
- new TypeMask.nonNullExact(jsExtendableArrayClass.rawType));
+ new TypeMask.nonNullExact(jsExtendableArrayClass));
}
void validateInterceptorImplementsAllObjectMethods(
@@ -745,6 +737,56 @@
}
}
+ Constant registerCompileTimeConstant(Constant constant,
+ TreeElements elements) {
+ registerCompileTimeConstantInternal(constant, elements);
+ for (Constant dependency in constant.getDependencies()) {
+ registerCompileTimeConstant(dependency, elements);
+ }
+ }
+
+ void registerCompileTimeConstantInternal(Constant constant,
+ TreeElements elements) {
+ DartType type = constant.computeType(compiler);
+ registerInstantiatedConstantType(type, elements);
+
+ if (constant.isFunction()) {
+ FunctionConstant function = constant;
+ compiler.enqueuer.codegen.registerGetOfStaticFunction(function.element);
+ } else if (constant.isInterceptor()) {
+ // An interceptor constant references the class's prototype chain.
+ InterceptorConstant interceptor = constant;
+ registerInstantiatedConstantType(interceptor.dispatchedType, elements);
+ } else if (constant.isType()) {
+ TypeConstant typeConstant = constant;
+ registerTypeLiteral(typeConstant.representedType.element,
+ compiler.enqueuer.codegen, elements);
+ }
+ }
+
+ void registerInstantiatedConstantType(DartType type, TreeElements elements) {
+ Enqueuer enqueuer = compiler.enqueuer.codegen;
+ enqueuer.registerInstantiatedType(type, elements);
+ if (type is InterfaceType && !type.treatAsRaw &&
+ classNeedsRti(type.element)) {
+ enqueuer.registerStaticUse(getSetRuntimeTypeInfo());
+ }
+ if (type.element == typeImplementation) {
+ // If we use a type literal in a constant, the compile time
+ // constant emitter will generate a call to the createRuntimeType
+ // helper so we register a use of that.
+ enqueuer.registerStaticUse(getCreateRuntimeType());
+ }
+ }
+
+ void registerMetadataConstant(Constant constant, TreeElements elements) {
+ if (mustRetainMetadata) {
+ registerCompileTimeConstant(constant, elements);
+ } else {
+ metadataConstants.add(new Dependency(constant, elements));
+ }
+ }
+
void registerInstantiatedClass(ClassElement cls,
Enqueuer enqueuer,
TreeElements elements) {
@@ -990,7 +1032,7 @@
}
}
bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE;
- if (!type.isRaw || type.containsTypeVariables) {
+ if (!type.treatAsRaw || type.containsTypeVariables) {
enqueueInResolution(getSetRuntimeTypeInfo(), elements);
enqueueInResolution(getGetRuntimeTypeInfo(), elements);
enqueueInResolution(getGetRuntimeTypeArgument(), elements);
@@ -1187,8 +1229,12 @@
return;
}
if (kind.category == ElementCategory.VARIABLE) {
- Constant initialValue = compiler.constantHandler.compileWorkItem(work);
+ Constant initialValue =
+ compiler.constantHandler.getConstantForVariable(element);
if (initialValue != null) {
+ registerCompileTimeConstant(initialValue, work.resolutionTree);
+ compiler.constantHandler.addCompileTimeConstantForEmission(
+ initialValue);
return;
} else {
// If the constant-handler was not able to produce a result we have to
@@ -1372,7 +1418,7 @@
: 'stringSuperTypeCheck';
}
} else if ((element == compiler.listClass || element == jsArrayClass) &&
- type.isRaw) {
+ type.treatAsRaw) {
if (nativeCheckOnly) return null;
return typeCast
? 'listTypeCast'
@@ -1396,7 +1442,7 @@
? 'interceptedTypeCast'
: 'interceptedTypeCheck';
} else {
- if (type.kind == TypeKind.INTERFACE && !type.isRaw) {
+ if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) {
return typeCast
? 'subtypeCast'
: 'assertSubtype';
@@ -1612,8 +1658,9 @@
if (mustRetainMetadata) hasRetainedMetadata = true;
if (mustRetainMetadata && isNeededForReflection(element)) {
for (MetadataAnnotation metadata in element.metadata) {
- metadata.ensureResolved(compiler)
- .value.accept(new ConstantCopier(compiler.constantHandler));
+ metadata.ensureResolved(compiler);
+ compiler.constantHandler.addCompileTimeConstantForEmission(
+ metadata.value);
}
return true;
}
@@ -1633,30 +1680,6 @@
return new Future.value();
}
- void registerMetadataInstantiatedType(DartType type, TreeElements elements) {
- if (mustRetainMetadata) {
- compiler.constantHandler.registerInstantiatedType(type, elements);
- } else {
- metadataInstantiatedTypes.add(new Dependency(type, elements));
- }
- }
-
- void registerMetadataStaticUse(Element element) {
- if (mustRetainMetadata) {
- compiler.constantHandler.registerStaticUse(element);
- } else {
- metadataStaticUse.add(element);
- }
- }
-
- void registerMetadataGetOfStaticFunction(FunctionElement element) {
- if (mustRetainMetadata) {
- compiler.constantHandler.registerGetOfStaticFunction(element);
- } else {
- metadataGetOfStaticFunction.add(element);
- }
- }
-
void registerMirrorUsage(Set<String> symbols,
Set<Element> targets,
Set<Element> metaTargets) {
@@ -1777,28 +1800,21 @@
compiler.log('Retaining metadata.');
compiler.libraries.values.forEach(retainMetadataOf);
- for (Dependency dependency in metadataInstantiatedTypes) {
- registerMetadataInstantiatedType(dependency.type, dependency.user);
+ for (Dependency dependency in metadataConstants) {
+ registerCompileTimeConstant(
+ dependency.constant, dependency.user);
}
- metadataInstantiatedTypes.clear();
- for (Element e in metadataStaticUse) {
- registerMetadataStaticUse(e);
- }
- metadataStaticUse.clear();
- for (Element e in metadataGetOfStaticFunction) {
- registerMetadataGetOfStaticFunction(e);
- }
- metadataGetOfStaticFunction.clear();
+ metadataConstants.clear();
}
}
}
-/// Records that [type] is used by [user.element].
+/// Records that [constant] is used by [user.element].
class Dependency {
- final DartType type;
+ final Constant constant;
final TreeElements user;
- const Dependency(this.type, this.user);
+ const Dependency(this.constant, this.user);
}
/// Used to copy metadata to the the actual constant handler.
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index 16ffce5..bd5c8aa 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -332,7 +332,7 @@
jsAst.Expression maybeAddTypeArguments(InterfaceType type,
jsAst.Expression value) {
if (type is InterfaceType &&
- !type.isRaw &&
+ !type.treatAsRaw &&
backend.classNeedsRti(type.element)) {
InterfaceType interface = type;
RuntimeTypes rti = backend.rti;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
index bee8ea9..b7cf4f2 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
@@ -11,6 +11,7 @@
import '../../compiler.dart' as api;
import '../elements/elements.dart';
import '../elements/modelx.dart' show FunctionElementX;
+import '../js_emitter/js_emitter.dart' show Emitter, CodeEmitterTask, ClassBuilder;
// TODO(ahe): There seems to be a bug in the VM, so we have to hide "js".
import '../dart2jslib.dart' hide Selector, TypedSelector, js;
@@ -31,7 +32,6 @@
part 'backend.dart';
part 'constant_emitter.dart';
part 'constant_system_javascript.dart';
-part 'emitter.dart';
part 'minify_namer.dart';
part 'namer.dart';
part 'native_emitter.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 141cd89..f11ac3b 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -352,21 +352,16 @@
? library
: shortPrivateNameOwners.putIfAbsent(nameString, () => library);
- // If a private name could clash with a mangled private name we don't
- // use the short name. For example a private name "_lib3_foo" would
- // clash with "_foo" from "lib3".
- if (owner == library &&
- !nameString.startsWith('_$LIBRARY_PREFIX') &&
- !shouldMinify) {
+ if (owner == library && !shouldMinify && !nameString.contains('\$')) {
+ // Since the name doesn't contain $ it doesn't clash with any
+ // of the private names that have the library name as the prefix.
return nameString;
+ } else {
+ // Make sure to return a private name that starts with _ so it
+ // cannot clash with any public names.
+ String libraryName = getNameOfLibrary(library);
+ return '_$libraryName\$$nameString';
}
-
- // If a library name does not start with the [LIBRARY_PREFIX] then our
- // assumptions about clashing with mangled private members do not hold.
- String libraryName = getNameOfLibrary(library);
- assert(shouldMinify || libraryName.startsWith(LIBRARY_PREFIX));
- // TODO(erikcorry): Fix this with other manglings to avoid clashes.
- return '_lib$libraryName\$$nameString';
}
String instanceMethodName(FunctionElement element) {
@@ -563,8 +558,6 @@
return new SourceString("${name.slowToString()}_$id");
}
- static const String LIBRARY_PREFIX = "lib";
-
/**
* Returns a preferred JS-id for the given top-level or static element.
* The returned id is guaranteed to be a valid JS-id.
@@ -589,7 +582,16 @@
name = element.name.slowToString().replaceAll('+', '_');
}
} else if (element.isLibrary()) {
- name = LIBRARY_PREFIX;
+ LibraryElement library = element;
+ name = library.getLibraryOrScriptName();
+ if (name.contains('.')) {
+ // For libraries that have a library tag, we use the last part
+ // of the fully qualified name as their base name. For all other
+ // libraries, we use the first part of their filename.
+ name = library.hasLibraryName()
+ ? name.substring(name.lastIndexOf('.') + 1)
+ : name.substring(0, name.indexOf('.'));
+ }
} else {
name = element.name.slowToString();
}
@@ -777,9 +779,6 @@
kind == ElementKind.TYPEDEF ||
kind == ElementKind.LIBRARY) {
bool fixedName = false;
- if (kind == ElementKind.CLASS) {
- ClassElement classElement = element;
- }
if (Elements.isInstanceField(element)) {
fixedName = element.hasFixedBackendName();
}
@@ -803,10 +802,14 @@
String getNameOfField(VariableElement field) => getNameX(field);
+ // TODO(ahe): Remove this method. Use get getNameOfMember instead.
String getNameOfInstanceMember(Element member) => getNameX(member);
+ String getNameOfMember(Element member) => getNameX(member);
+
String getNameOfGlobalField(VariableElement field) => getNameX(field);
+ // TODO(ahe): Remove this method. Use get getNameOfMember instead.
String getNameOfGlobalFunction(FunctionElement element) => getNameX(element);
/// Returns true if [element] is stored on CURRENT_ISOLATE ('$'). We intend
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
index 1153082..1f83c5f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -35,7 +35,7 @@
Compiler get compiler => emitter.compiler;
JavaScriptBackend get backend => compiler.backend;
- String get _ => emitter._;
+ String get _ => emitter.space;
String get n => emitter.n;
String get N => emitter.N;
@@ -325,7 +325,9 @@
}
ClassBuilder generateNativeClass(ClassElement classElement) {
- assert(!classElement.hasBackendMembers);
+ // TODO(sra): Issue #13731- this is commented out as part of custom element
+ // constructor work.
+ //assert(!classElement.hasBackendMembers);
nativeClasses.add(classElement);
ClassElement superclass = classElement.superclass;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index 6a52399..fbb9da7 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -162,7 +162,7 @@
compiler.resolverWorld.isChecks.forEach((DartType type) {
if (type.kind == TypeKind.INTERFACE) {
InterfaceType itf = type;
- if (!itf.isRaw) {
+ if (!itf.treatAsRaw) {
potentiallyAddForRti(itf.element);
}
} else {
@@ -559,7 +559,7 @@
static bool hasTypeArguments(DartType type) {
if (type is InterfaceType) {
InterfaceType interfaceType = type;
- return !interfaceType.isRaw;
+ return !interfaceType.treatAsRaw;
}
return false;
}
@@ -613,7 +613,7 @@
visitInterfaceType(InterfaceType type, _) {
jsAst.Expression name = getJavaScriptClassName(type.element);
- return type.isRaw ? name : visitList(type.typeArguments, head: name);
+ return type.treatAsRaw ? name : visitList(type.typeArguments, head: name);
}
jsAst.Expression visitList(Link<DartType> types, {jsAst.Expression head}) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/class_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/class_builder.dart
new file mode 100644
index 0000000..626de96
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/class_builder.dart
@@ -0,0 +1,35 @@
+// 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 dart2js.js_emitter;
+
+/**
+ * A data structure for collecting fragments of a class definition.
+ */
+class ClassBuilder {
+ final List<jsAst.Property> properties = <jsAst.Property>[];
+
+ /// Set to true by user if class is indistinguishable from its superclass.
+ bool isTrivial = false;
+
+ // Has the same signature as [DefineStubFunction].
+ void addProperty(String name, jsAst.Expression value) {
+ properties.add(new jsAst.Property(js.string(name), value));
+ }
+
+ jsAst.Expression toObjectInitializer() {
+ return new jsAst.ObjectInitializer(properties);
+ }
+
+ /// This method is temporary. Do not use it unless you're working on
+ /// transforming code to build jsAst.Nodes.
+ void writeOn_DO_NOT_USE(CodeBuffer buffer,
+ Compiler compiler,
+ String separatedBy) {
+ for (jsAst.Property property in properties) {
+ if (!buffer.isEmpty) buffer.write(separatedBy);
+ buffer.write(jsAst.prettyPrint(property, compiler));
+ }
+ }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/closure_invocation_element.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/closure_invocation_element.dart
new file mode 100644
index 0000000..bd52fe2
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/closure_invocation_element.dart
@@ -0,0 +1,25 @@
+// 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 dart2js.js_emitter;
+
+/**
+ * A function element that represents a closure call. The signature is copied
+ * from the given element.
+ */
+class ClosureInvocationElement extends FunctionElementX {
+ ClosureInvocationElement(SourceString name,
+ FunctionElement other)
+ : super.from(name, other, other.enclosingElement),
+ methodElement = other;
+
+ isInstanceMember() => true;
+
+ Element getOutermostEnclosingMemberOrTopLevel() => methodElement;
+
+ /**
+ * The [member] this invocation refers to.
+ */
+ Element methodElement;
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
similarity index 77%
rename from sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
rename to sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index a284cbe..dae8663 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -2,86 +2,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.
-part of js_backend;
-
-/// Enables debugging of fast/slow objects using V8-specific primitives.
-const DEBUG_FAST_OBJECTS = false;
-
-/**
- * A function element that represents a closure call. The signature is copied
- * from the given element.
- */
-class ClosureInvocationElement extends FunctionElementX {
- ClosureInvocationElement(SourceString name,
- FunctionElement other)
- : super.from(name, other, other.enclosingElement),
- methodElement = other;
-
- isInstanceMember() => true;
-
- Element getOutermostEnclosingMemberOrTopLevel() => methodElement;
-
- /**
- * The [member] this invocation refers to.
- */
- Element methodElement;
-}
-
-/**
- * A convenient type alias for some functions that emit keyed values.
- */
-typedef void DefineStubFunction(String invocationName, jsAst.Expression value);
-
-/**
- * [member] is a field (instance, static, or top level).
- *
- * [name] is the field name that the [Namer] has picked for this field's
- * storage, that is, the JavaScript property name.
- *
- * [accessorName] is the name of the accessor. For instance fields this is
- * mostly the same as [name] except when [member] is shadowing a field in its
- * superclass. For other fields, they are rarely the same.
- *
- * [needsGetter] and [needsSetter] represent if a getter or a setter
- * respectively is needed. There are many factors in this, for example, if the
- * accessor can be inlined.
- *
- * [needsCheckedSetter] indicates that a checked getter is needed, and in this
- * case, [needsSetter] is always false. [needsCheckedSetter] is only true when
- * type assertions are enabled (checked mode).
- */
-typedef void AcceptField(VariableElement member,
- String name,
- String accessorName,
- bool needsGetter,
- bool needsSetter,
- bool needsCheckedSetter);
-
-/**
- * A data structure for collecting fragments of a class definition.
- */
-class ClassBuilder {
- final List<jsAst.Property> properties = <jsAst.Property>[];
-
- /// Set to true by user if class is indistinguishable from its superclass.
- bool isTrivial = false;
-
- // Has the same signature as [DefineStubFunction].
- void addProperty(String name, jsAst.Expression value) {
- properties.add(new jsAst.Property(js.string(name), value));
- }
-
- jsAst.Expression toObjectInitializer() {
- return new jsAst.ObjectInitializer(properties);
- }
-}
-
-// Function signatures used in the generation of runtime type information.
-typedef void FunctionTypeSignatureEmitter(Element method,
- FunctionType methodType);
-// TODO(johnniwinther): Clean up terminology for rti in the emitter.
-typedef void FunctionTypeTestEmitter(FunctionType functionType);
-typedef void SubstitutionEmitter(Element element, {bool emitNull});
+part of dart2js.js_emitter;
/**
* Generates the code for all used classes in the program. Static fields (even
@@ -90,6 +11,7 @@
* The code for the containing (used) methods must exist in the [:universe:].
*/
class CodeEmitterTask extends CompilerTask {
+ final ContainerBuilder containerBuilder = new ContainerBuilder();
bool needsDefineClass = false;
bool needsMixinSupport = false;
bool needsLazyInitializer = false;
@@ -124,29 +46,14 @@
// TODO(ngeoffray): remove this field.
Set<ClassElement> instantiatedClasses;
- final List<jsAst.Expression> boundClosures = <jsAst.Expression>[];
-
JavaScriptBackend get backend => compiler.backend;
- String get _ => compiler.enableMinification ? "" : " ";
+ String get _ => space;
+ String get space => compiler.enableMinification ? "" : " ";
String get n => compiler.enableMinification ? "" : "\n";
String get N => compiler.enableMinification ? "\n" : ";\n";
/**
- * A cache of closures that are used to closurize instance methods.
- * A closure is dynamically bound to the instance used when
- * closurized.
- */
- final Map<int, String> boundClosureCache;
-
- /**
- * A cache of closures that are used to closurize instance methods
- * of interceptors. These closures are dynamically bound to the
- * interceptor instance, and the actual receiver of the method.
- */
- final Map<int, String> interceptorClosureCache;
-
- /**
* Raw ClassElement symbols occuring in is-checks and type assertions. If the
* program contains parameterized checks `x is Set<int>` and
* `x is Set<String>` then the ClassElement `Set` will occur once in
@@ -219,11 +126,10 @@
CodeEmitterTask(Compiler compiler, Namer namer, this.generateSourceMap)
: mainBuffer = new CodeBuffer(),
this.namer = namer,
- boundClosureCache = new Map<int, String>(),
- interceptorClosureCache = new Map<int, String>(),
constantEmitter = new ConstantEmitter(compiler, namer),
super(compiler) {
nativeEmitter = new NativeEmitter(this);
+ containerBuilder.task = this;
}
void addComment(String comment, CodeBuffer buffer) {
@@ -983,241 +889,6 @@
buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N");
}
- /**
- * Generate stubs to handle invocation of methods with optional
- * arguments.
- *
- * A method like [: foo([x]) :] may be invoked by the following
- * calls: [: foo(), foo(1), foo(x: 1) :]. See the sources of this
- * function for detailed examples.
- */
- void addParameterStub(FunctionElement member,
- Selector selector,
- DefineStubFunction defineStub,
- Set<String> alreadyGenerated) {
- FunctionSignature parameters = member.computeSignature(compiler);
- int positionalArgumentCount = selector.positionalArgumentCount;
- if (positionalArgumentCount == parameters.parameterCount) {
- assert(selector.namedArgumentCount == 0);
- return;
- }
- if (parameters.optionalParametersAreNamed
- && selector.namedArgumentCount == parameters.optionalParameterCount) {
- // If the selector has the same number of named arguments as the element,
- // we don't need to add a stub. The call site will hit the method
- // directly.
- return;
- }
- ConstantHandler handler = compiler.constantHandler;
- List<SourceString> names = selector.getOrderedNamedArguments();
-
- String invocationName = namer.invocationName(selector);
- if (alreadyGenerated.contains(invocationName)) return;
- alreadyGenerated.add(invocationName);
-
- bool isInterceptedMethod = backend.isInterceptedMethod(member);
-
- // If the method is intercepted, we need to also pass the actual receiver.
- int extraArgumentCount = isInterceptedMethod ? 1 : 0;
- // Use '$receiver' to avoid clashes with other parameter names. Using
- // '$receiver' works because [:namer.safeName:] used for getting parameter
- // names never returns a name beginning with a single '$'.
- String receiverArgumentName = r'$receiver';
-
- // The parameters that this stub takes.
- List<jsAst.Parameter> parametersBuffer =
- new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount);
- // The arguments that will be passed to the real method.
- List<jsAst.Expression> argumentsBuffer =
- new List<jsAst.Expression>(
- parameters.parameterCount + extraArgumentCount);
-
- int count = 0;
- if (isInterceptedMethod) {
- count++;
- parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName);
- argumentsBuffer[0] = js(receiverArgumentName);
- interceptorInvocationNames.add(invocationName);
- }
-
- int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
- // Includes extra receiver argument when using interceptor convention
- int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1;
-
- TreeElements elements =
- compiler.enqueuer.resolution.getCachedElements(member);
-
- parameters.orderedForEachParameter((Element element) {
- String jsName = backend.namer.safeName(element.name.slowToString());
- assert(jsName != receiverArgumentName);
- if (count < optionalParameterStart) {
- parametersBuffer[count] = new jsAst.Parameter(jsName);
- argumentsBuffer[count] = js(jsName);
- } else {
- int index = names.indexOf(element.name);
- if (index != -1) {
- indexOfLastOptionalArgumentInParameters = count;
- // The order of the named arguments is not the same as the
- // one in the real method (which is in Dart source order).
- argumentsBuffer[count] = js(jsName);
- parametersBuffer[optionalParameterStart + index] =
- new jsAst.Parameter(jsName);
- } else {
- Constant value = handler.initialVariableValues[element];
- if (value == null) {
- argumentsBuffer[count] = constantReference(new NullConstant());
- } else {
- if (!value.isNull()) {
- // If the value is the null constant, we should not pass it
- // down to the native method.
- indexOfLastOptionalArgumentInParameters = count;
- }
- argumentsBuffer[count] = constantReference(value);
- }
- }
- }
- count++;
- });
-
- List body;
- if (member.hasFixedBackendName()) {
- body = nativeEmitter.generateParameterStubStatements(
- member, isInterceptedMethod, invocationName,
- parametersBuffer, argumentsBuffer,
- indexOfLastOptionalArgumentInParameters);
- } else {
- body = [js.return_(
- js('this')[namer.getNameOfInstanceMember(member)](argumentsBuffer))];
- }
-
- jsAst.Fun function = js.fun(parametersBuffer, body);
-
- defineStub(invocationName, function);
-
- String reflectionName = getReflectionName(selector, invocationName);
- if (reflectionName != null) {
- var reflectable =
- js(backend.isAccessibleByReflection(member) ? '1' : '0');
- defineStub('+$reflectionName', reflectable);
- }
- }
-
- void addParameterStubs(FunctionElement member,
- DefineStubFunction defineStub) {
- // We fill the lists depending on the selector. For example,
- // take method foo:
- // foo(a, b, {c, d});
- //
- // We may have multiple ways of calling foo:
- // (1) foo(1, 2);
- // (2) foo(1, 2, c: 3);
- // (3) foo(1, 2, d: 4);
- // (4) foo(1, 2, c: 3, d: 4);
- // (5) foo(1, 2, d: 4, c: 3);
- //
- // What we generate at the call sites are:
- // (1) foo$2(1, 2);
- // (2) foo$3$c(1, 2, 3);
- // (3) foo$3$d(1, 2, 4);
- // (4) foo$4$c$d(1, 2, 3, 4);
- // (5) foo$4$c$d(1, 2, 3, 4);
- //
- // The stubs we generate are (expressed in Dart):
- // (1) foo$2(a, b) => foo$4$c$d(a, b, null, null)
- // (2) foo$3$c(a, b, c) => foo$4$c$d(a, b, c, null);
- // (3) foo$3$d(a, b, d) => foo$4$c$d(a, b, null, d);
- // (4) No stub generated, call is direct.
- // (5) No stub generated, call is direct.
-
- // Keep a cache of which stubs have already been generated, to
- // avoid duplicates. Note that even if selectors are
- // 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>();
- 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);
- Set<Selector> selectors = signature.optionalParametersAreNamed
- ? computeSeenNamedSelectors(member)
- : computeOptionalSelectors(signature, member);
- for (Selector selector in selectors) {
- addParameterStub(member, selector, defineStub, generatedStubNames);
- }
- if (signature.optionalParametersAreNamed && isClosureInvocation) {
- addCatchAllParameterStub(member, signature, defineStub);
- }
- } else {
- Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
- if (selectors == null) return;
- for (Selector selector in selectors) {
- if (!selector.applies(member, compiler)) continue;
- addParameterStub(member, selector, defineStub, generatedStubNames);
- }
- }
- }
-
- Set<Selector> computeSeenNamedSelectors(FunctionElement element) {
- Set<Selector> selectors = compiler.codegenWorld.invokedNames[element.name];
- 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);
- }
- return result;
- }
-
- void addCatchAllParameterStub(FunctionElement member,
- FunctionSignature signature,
- DefineStubFunction defineStub) {
- // See Primities.applyFunction in js_helper.dart for details.
- List<jsAst.Property> properties = <jsAst.Property>[];
- for (Element element in signature.orderedOptionalParameters) {
- String jsName = backend.namer.safeName(element.name.slowToString());
- Constant value = compiler.constantHandler.initialVariableValues[element];
- jsAst.Expression reference = null;
- if (value == null) {
- reference = new jsAst.LiteralNull();
- } else {
- reference = constantReference(value);
- }
- properties.add(new jsAst.Property(js.string(jsName), reference));
- }
- defineStub(
- backend.namer.callCatchAllName,
- js.fun([], js.return_(new jsAst.ObjectInitializer(properties))));
- }
-
- /**
- * Compute the set of possible selectors in the presence of optional
- * non-named parameters.
- */
- Set<Selector> computeOptionalSelectors(FunctionSignature signature,
- FunctionElement element) {
- Set<Selector> selectors = new Set<Selector>();
- // Add the selector that does not have any optional argument.
- selectors.add(new Selector(SelectorKind.CALL,
- element.name,
- element.getLibrary(),
- signature.requiredParameterCount,
- <SourceString>[]));
-
- // For each optional parameter, we increment the number of passed
- // argument.
- for (int i = 1; i <= signature.optionalParameterCount; i++) {
- selectors.add(new Selector(SelectorKind.CALL,
- element.name,
- element.getLibrary(),
- signature.requiredParameterCount + i,
- <SourceString>[]));
- }
- return selectors;
- }
-
bool fieldNeedsGetter(VariableElement field) {
assert(field.isField());
if (fieldAccessNeverThrows(field)) return false;
@@ -1240,55 +911,6 @@
return field is ClosureFieldElement;
}
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [member] must be a declaration element.
- */
- void addInstanceMember(Element member, ClassBuilder builder) {
- assert(invariant(member, member.isDeclaration));
- // TODO(floitsch): we don't need to deal with members of
- // uninstantiated classes, that have been overwritten by subclasses.
-
- if (member.isFunction()
- || member.isGenerativeConstructorBody()
- || member.isAccessor()) {
- if (member.isAbstract(compiler)) return;
- jsAst.Expression code = backend.generatedCode[member];
- if (code == null) return;
- String name = namer.getNameOfInstanceMember(member);
- if (backend.isInterceptedMethod(member)) {
- interceptorInvocationNames.add(name);
- }
- code = extendWithMetadata(member, code);
- builder.addProperty(name, code);
- String reflectionName = getReflectionName(member, name);
- if (reflectionName != null) {
- 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) {
- builder.addProperty(namer.getBailoutName(member), code);
- }
- FunctionElement function = member;
- FunctionSignature parameters = function.computeSignature(compiler);
- if (!parameters.optionalParameters.isEmpty) {
- addParameterStubs(function, builder.addProperty);
- }
- } else if (!member.isField()) {
- compiler.internalError('unexpected kind: "${member.kind}"',
- element: member);
- }
- emitExtraAccessors(member, builder);
- }
-
/// Returns the "reflection name" of an [Element] or [Selector].
/// The reflection name of a getter 'foo' is 'foo'.
/// The reflection name of a setter 'foo' is 'foo='.
@@ -1411,7 +1033,7 @@
void visitMember(ClassElement enclosing, Element member) {
assert(invariant(classElement, member.isDeclaration));
if (member.isInstanceMember()) {
- addInstanceMember(member, builder);
+ containerBuilder.addMember(member, builder);
}
}
@@ -2367,18 +1989,6 @@
}
}
- void emitStaticFunction(CodeBuffer buffer,
- String name,
- jsAst.Expression functionExpression) {
- // TODO(ahe): This method (emitStaticFunction) should return a
- // jsAst.Expression.
- if (!buffer.isEmpty) {
- buffer.write(',$n$n');
- }
- buffer.write('$name:$_');
- buffer.write(jsAst.prettyPrint(functionExpression, compiler));
- }
-
void emitStaticFunctions(CodeBuffer eagerBuffer) {
bool isStaticFunction(Element element) =>
!element.isInstanceMember() && !element.isField();
@@ -2391,27 +2001,11 @@
.toSet();
for (Element element in Elements.sortedByPosition(elements)) {
- CodeBuffer buffer = bufferForElement(element, eagerBuffer);
- jsAst.Expression code = backend.generatedCode[element];
- String name = namer.getNameOfGlobalFunction(element);
- code = extendWithMetadata(element, code);
- emitStaticFunction(buffer, name, code);
- String reflectionName = getReflectionName(element, name);
- 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) {
- pendingElementsWithBailouts.remove(element);
- emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode);
- }
+ pendingElementsWithBailouts.remove(element);
+ ClassBuilder builder = new ClassBuilder();
+ containerBuilder.addMember(element, builder);
+ builder.writeOn_DO_NOT_USE(
+ bufferForElement(element, eagerBuffer), compiler, ',$n$n');
}
if (!pendingElementsWithBailouts.isEmpty) {
@@ -2420,355 +2014,11 @@
// Is it possible the primary function was inlined but the bailout was not?
for (Element element in
Elements.sortedByPosition(pendingElementsWithBailouts)) {
- CodeBuffer buffer = bufferForElement(element, eagerBuffer);
jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
- emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode);
- }
- }
-
- final Map<Element, Element> staticGetters = new Map<Element, Element>();
-
- void emitStaticFunctionGetters(CodeBuffer eagerBuffer) {
- addComment('Static function getters', mainBuffer);
- for (FunctionElement element in
- Elements.sortedByPosition(staticGetters.keys)) {
- Element closure = staticGetters[element];
- CodeBuffer buffer = isDeferred(element) ? deferredConstants : eagerBuffer;
- String closureClass = namer.isolateAccess(closure);
- String name = namer.getStaticClosureName(element);
-
- String closureName = namer.getStaticClosureName(element);
- jsAst.Node assignment = js(
- 'init.globalFunctions["$closureName"] ='
- ' ${namer.globalObjectFor(element)}.$name ='
- ' new $closureClass(#, "$closureName")',
- namer.elementAccess(element));
- buffer.write(jsAst.prettyPrint(assignment, compiler));
- buffer.write('$N');
- }
- }
-
- void emitStaticFunctionClosures() {
- Set<FunctionElement> functionsNeedingGetter =
- compiler.codegenWorld.staticFunctionsNeedingGetter;
- for (FunctionElement element in
- Elements.sortedByPosition(functionsNeedingGetter)) {
- String superName = namer.getNameOfClass(compiler.closureClass);
- String name = 'Closure\$${element.name.slowToString()}';
- assert(instantiatedClasses.contains(compiler.closureClass));
-
- ClassElement closureClassElement = new ClosureClassElement(
- null, new SourceString(name), compiler, element,
- element.getCompilationUnit());
- // Now add the methods on the closure class. The instance method does not
- // have the correct name. Since [addParameterStubs] use the name to create
- // its stubs we simply create a fake element with the correct name.
- // Note: the callElement will not have any enclosingElement.
- FunctionElement callElement =
- new ClosureInvocationElement(namer.closureInvocationSelectorName,
- element);
-
- String invocationName = namer.instanceMethodName(callElement);
- String mangledName = namer.getNameOfClass(closureClassElement);
-
- // Define the constructor with a name so that Object.toString can
- // find the class name of the closure class.
- ClassBuilder closureBuilder = new ClassBuilder();
- // If a static function is used as a closure we need to add its name
- // in case it is used in spawnFunction.
- String methodName = namer.STATIC_CLOSURE_NAME_NAME;
- emitClosureClassHeader(
- mangledName, superName, <String>[invocationName, methodName],
- closureBuilder);
-
- addParameterStubs(callElement, closureBuilder.addProperty);
-
- // TODO(ngeoffray): Cache common base classes for closures, bound
- // closures, and static closures that have common type checks.
- boundClosures.add(
- js('$classesCollector.$mangledName = #',
- js('[${namer.globalObjectFor(closureClassElement)}, #]',
- closureBuilder.toObjectInitializer())));
-
- staticGetters[element] = closureClassElement;
-
- void emitFunctionTypeSignature(Element method, FunctionType methodType) {
- RuntimeTypes rti = backend.rti;
- // [:() => null:] is dummy encoding of [this] which is never needed for
- // the encoding of the type of the static [method].
- jsAst.Expression encoding =
- rti.getSignatureEncoding(methodType, js('null'));
- String operatorSignature = namer.operatorSignature();
- // TODO(johnniwinther): Make MiniJsParser support function expressions.
- closureBuilder.addProperty(operatorSignature, encoding);
- }
-
- void emitIsFunctionTypeTest(FunctionType functionType) {
- String operator = namer.operatorIsType(functionType);
- closureBuilder.addProperty(operator, js('true'));
- }
-
- FunctionType methodType = element.computeType(compiler);
- Map<FunctionType, bool> functionTypeChecks =
- getFunctionTypeChecksOn(methodType);
- generateFunctionTypeTests(element, methodType, functionTypeChecks,
- emitFunctionTypeSignature, emitIsFunctionTypeTest);
- }
- }
-
- void emitClosureClassHeader(String mangledName,
- String superName,
- List<String> fieldNames,
- ClassBuilder builder) {
- builder.addProperty('',
- js.string("$superName;${fieldNames.join(',')}"));
-
- List<String> fields = fieldNames;
- String constructorName = mangledName;
- precompiledFunction.add(new jsAst.FunctionDeclaration(
- new jsAst.VariableDeclaration(constructorName),
- js.fun(fields, fields.map(
- (name) => js('this.$name = $name')).toList())));
- precompiledFunction.addAll([
- js('$constructorName.builtin\$cls = "$constructorName"'),
- js('\$desc=\$collectedClasses.$constructorName'),
- js.if_('\$desc instanceof Array', js('\$desc = \$desc[1]')),
- js('$constructorName.prototype = \$desc'),
- ]);
-
- precompiledConstructorNames.add(js(constructorName));
- }
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [member] must be a declaration element.
- */
- void emitDynamicFunctionGetter(FunctionElement member,
- DefineStubFunction defineStub) {
- assert(invariant(member, member.isDeclaration));
- assert(instantiatedClasses.contains(compiler.boundClosureClass));
- // For every method that has the same name as a property-get we create a
- // getter that returns a bound closure. Say we have a class 'A' with method
- // 'foo' and somewhere in the code there is a dynamic property get of
- // 'foo'. Then we generate the following code (in pseudo Dart/JavaScript):
- //
- // class A {
- // foo(x, y, z) { ... } // Original function.
- // get foo { return new BoundClosure499(this, "foo"); }
- // }
- // class BoundClosure499 extends BoundClosure {
- // BoundClosure499(this.self, this.name);
- // $call3(x, y, z) { return self[name](x, y, z); }
- // }
-
- // TODO(floitsch): share the closure classes with other classes
- // if they share methods with the same signature. Currently we do this only
- // if there are no optional parameters. Closures with optional parameters
- // are more difficult to canonicalize because they would need to have the
- // same default values.
-
- bool hasOptionalParameters = member.optionalParameterCount(compiler) != 0;
- int parameterCount = member.parameterCount(compiler);
-
- Map<int, String> cache;
- // Intercepted methods take an extra parameter, which is the
- // receiver of the call.
- bool inInterceptor = backend.isInterceptedMethod(member);
- if (inInterceptor) {
- cache = interceptorClosureCache;
- } else {
- cache = boundClosureCache;
- }
- List<String> fieldNames = <String>[];
- compiler.boundClosureClass.forEachInstanceField((_, Element field) {
- fieldNames.add(namer.getNameOfInstanceMember(field));
- });
-
- DartType memberType = member.computeType(compiler);
- Map<FunctionType, bool> functionTypeChecks =
- getFunctionTypeChecksOn(memberType);
- bool hasFunctionTypeChecks = !functionTypeChecks.isEmpty;
-
- bool canBeShared = !hasOptionalParameters && !hasFunctionTypeChecks;
-
- ClassElement classElement = member.getEnclosingClass();
- String closureClass = canBeShared ? cache[parameterCount] : null;
- if (closureClass == null) {
- // Either the class was not cached yet, or there are optional parameters.
- // Create a new closure class.
- String name;
- if (canBeShared) {
- if (inInterceptor) {
- name = 'BoundClosure\$i${parameterCount}';
- } else {
- name = 'BoundClosure\$${parameterCount}';
- }
- } else {
- name = 'Bound_${member.name.slowToString()}'
- '_${member.enclosingElement.name.slowToString()}';
- }
-
- ClassElement closureClassElement = new ClosureClassElement(
- null, new SourceString(name), compiler, member,
- member.getCompilationUnit());
- String mangledName = namer.getNameOfClass(closureClassElement);
- String superName = namer.getNameOfClass(closureClassElement.superclass);
-
- // Define the constructor with a name so that Object.toString can
- // find the class name of the closure class.
- ClassBuilder boundClosureBuilder = new ClassBuilder();
- emitClosureClassHeader(
- mangledName, superName, fieldNames, boundClosureBuilder);
- // Now add the methods on the closure class. The instance method does not
- // have the correct name. Since [addParameterStubs] use the name to create
- // its stubs we simply create a fake element with the correct name.
- // Note: the callElement will not have any enclosingElement.
- FunctionElement callElement =
- new ClosureInvocationElement(namer.closureInvocationSelectorName,
- member);
-
- String invocationName = namer.instanceMethodName(callElement);
-
- List<String> parameters = <String>[];
- List<jsAst.Expression> arguments = <jsAst.Expression>[];
- arguments.add(js('this')[fieldNames[0]]);
- if (inInterceptor) {
- arguments.add(js('this')[fieldNames[2]]);
- }
- for (int i = 0; i < parameterCount; i++) {
- String name = 'p$i';
- parameters.add(name);
- arguments.add(js(name));
- }
-
- jsAst.Expression fun = js.fun(
- parameters,
- js.return_(
- js('this')[fieldNames[1]]['call'](arguments)));
- boundClosureBuilder.addProperty(invocationName, fun);
-
- addParameterStubs(callElement, boundClosureBuilder.addProperty);
-
- void emitFunctionTypeSignature(Element method, FunctionType methodType) {
- jsAst.Expression encoding = backend.rti.getSignatureEncoding(
- methodType, js('this')[fieldNames[0]]);
- String operatorSignature = namer.operatorSignature();
- boundClosureBuilder.addProperty(operatorSignature, encoding);
- }
-
- void emitIsFunctionTypeTest(FunctionType functionType) {
- String operator = namer.operatorIsType(functionType);
- boundClosureBuilder.addProperty(operator,
- new jsAst.LiteralBool(true));
- }
-
- generateFunctionTypeTests(member, memberType, functionTypeChecks,
- emitFunctionTypeSignature, emitIsFunctionTypeTest);
-
- boundClosures.add(
- js('$classesCollector.$mangledName = #',
- js('[${namer.globalObjectFor(closureClassElement)}, #]',
- boundClosureBuilder.toObjectInitializer())));
-
- closureClass = namer.isolateAccess(closureClassElement);
-
- // Cache it.
- if (canBeShared) {
- cache[parameterCount] = closureClass;
- }
- }
-
- // And finally the getter.
- String getterName = namer.getterName(member);
- String targetName = namer.instanceMethodName(member);
-
- List<String> parameters = <String>[];
- List<jsAst.Expression> arguments = <jsAst.Expression>[];
- arguments.add(js('this'));
- jsAst.PropertyAccess method =
- backend.namer.elementAccess(classElement)['prototype'][targetName];
-
- arguments.add(method);
- if (inInterceptor) {
- String receiverArg = fieldNames[2];
- parameters.add(receiverArg);
- arguments.add(js(receiverArg));
- } else {
- // Put null in the intercepted receiver field.
- arguments.add(new jsAst.LiteralNull());
- }
- arguments.add(js.string(targetName));
-
- jsAst.Expression getterFunction = js.fun(
- parameters, js.return_(js(closureClass).newWith(arguments)));
-
- defineStub(getterName, getterFunction);
- }
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [member] must be a declaration element.
- */
- void emitCallStubForGetter(Element member,
- Set<Selector> selectors,
- DefineStubFunction defineStub) {
- assert(invariant(member, member.isDeclaration));
- LibraryElement memberLibrary = member.getLibrary();
- // If the method is intercepted, the stub gets the
- // receiver explicitely and we need to pass it to the getter call.
- bool isInterceptedMethod = backend.isInterceptedMethod(member);
-
- const String receiverArgumentName = r'$receiver';
-
- jsAst.Expression buildGetter() {
- if (member.isGetter()) {
- String getterName = namer.getterName(member);
- return js('this')[getterName](
- isInterceptedMethod
- ? <jsAst.Expression>[js(receiverArgumentName)]
- : <jsAst.Expression>[]);
- } else {
- String fieldName = member.hasFixedBackendName()
- ? member.fixedBackendName()
- : namer.instanceFieldName(member);
- return js('this')[fieldName];
- }
- }
-
- // Two selectors may match but differ only in type. To avoid generating
- // identical stubs for each we track untyped selectors which already have
- // stubs.
- Set<Selector> generatedSelectors = new Set<Selector>();
- for (Selector selector in selectors) {
- if (selector.applies(member, compiler)) {
- selector = selector.asUntyped;
- if (generatedSelectors.contains(selector)) continue;
- generatedSelectors.add(selector);
-
- String invocationName = namer.invocationName(selector);
- Selector callSelector = new Selector.callClosureFrom(selector);
- String closureCallName = namer.invocationName(callSelector);
-
- List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
- List<jsAst.Expression> arguments = <jsAst.Expression>[];
- if (isInterceptedMethod) {
- parameters.add(new jsAst.Parameter(receiverArgumentName));
- }
-
- for (int i = 0; i < selector.argumentCount; i++) {
- String name = 'arg$i';
- parameters.add(new jsAst.Parameter(name));
- arguments.add(js(name));
- }
-
- jsAst.Fun function = js.fun(
- parameters,
- js.return_(buildGetter()[closureCallName](arguments)));
-
- defineStub(invocationName, function);
- }
+ new ClassBuilder()
+ ..addProperty(namer.getBailoutName(element), bailoutCode)
+ ..writeOn_DO_NOT_USE(
+ bufferForElement(element, eagerBuffer), compiler, ',$n$n');
}
}
@@ -2887,25 +2137,6 @@
''');
}
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [member] must be a declaration element.
- */
- void emitExtraAccessors(Element member, ClassBuilder builder) {
- assert(invariant(member, member.isDeclaration));
- if (member.isGetter() || member.isField()) {
- Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
- if (selectors != null && !selectors.isEmpty) {
- emitCallStubForGetter(member, selectors, builder.addProperty);
- }
- } else if (member.isFunction()) {
- if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) {
- emitDynamicFunctionGetter(member, builder.addProperty);
- }
- }
- }
-
// Identify the noSuchMethod handlers that are so simple that we can
// generate them programatically.
bool isTrivialNsmHandler(
@@ -2948,7 +2179,7 @@
for (Selector selector in selectors) {
TypeMask mask = selector.mask;
if (mask == null) {
- mask = new TypeMask.subclass(compiler.objectClass.rawType);
+ mask = new TypeMask.subclass(compiler.objectClass);
}
if (!mask.needsNoSuchMethodHandling(selector, compiler)) continue;
@@ -3760,33 +2991,6 @@
});
}
- jsAst.Fun extendWithMetadata(FunctionElement element, jsAst.Fun code) {
- if (!backend.retainMetadataOf(element)) return code;
- return compiler.withCurrentElement(element, () {
- List<int> metadata = <int>[];
- FunctionSignature signature = element.functionSignature;
- if (element.isConstructor()) {
- metadata.add(reifyType(element.getEnclosingClass().thisType));
- } else {
- metadata.add(reifyType(signature.returnType));
- }
- signature.forEachParameter((Element parameter) {
- metadata
- ..add(reifyName(parameter.name))
- ..add(reifyType(parameter.computeType(compiler)));
- });
- Link link = element.metadata;
- // TODO(ahe): Why is metadata sometimes null?
- if (link != null) {
- for (; !link.isEmpty; link = link.tail) {
- metadata.add(reifyMetadata(link.head));
- }
- }
- code.body.statements.add(js.string(metadata.join(',')).toStatement());
- return code;
- });
- }
-
void emitMetadata(CodeBuffer buffer) {
var literals = backend.typedefTypeLiterals.toList();
Elements.sortedByPosition(literals);
@@ -3890,11 +3094,11 @@
}
// As a side-effect, emitting classes will produce "bound closures" in
- // [boundClosures]. The bound closures are JS AST nodes that add
+ // [methodClosures]. The bound closures are JS AST nodes that add
// properties to $$ [classesCollector]. The bound closures are not
// emitted until we have emitted all other classes (native or not).
- // Might create boundClosures.
+ // Might create methodClosures.
if (!regularClasses.isEmpty) {
for (ClassElement element in regularClasses) {
generateClass(element, bufferForElement(element, mainBuffer));
@@ -3902,7 +3106,7 @@
}
// Emit native classes on [nativeBuffer].
- // Might create boundClosures.
+ // Might create methodClosures.
final CodeBuffer nativeBuffer = new CodeBuffer();
if (!nativeClasses.isEmpty) {
addComment('Native classes', nativeBuffer);
@@ -3912,23 +3116,25 @@
nativeEmitter.finishGenerateNativeClasses();
nativeEmitter.assembleCode(nativeBuffer);
- // Might create boundClosures.
+ // Might create methodClosures.
if (!deferredClasses.isEmpty) {
for (ClassElement element in deferredClasses) {
generateClass(element, bufferForElement(element, mainBuffer));
}
}
- emitStaticFunctionClosures();
+ containerBuilder.emitStaticFunctionClosures();
- addComment('Bound closures', mainBuffer);
- // Now that we have emitted all classes, we know all the bound
+ addComment('Method closures', mainBuffer);
+ // Now that we have emitted all classes, we know all the method
// closures that will be needed.
- for (jsAst.Node node in boundClosures) {
+ containerBuilder.methodClosures.forEach((String code, Element closure) {
// TODO(ahe): Some of these can be deferred.
- mainBuffer.add(jsAst.prettyPrint(node, compiler));
+ String mangledName = namer.getNameOfClass(closure);
+ mainBuffer.add('$classesCollector.$mangledName$_=$_'
+ '[${namer.globalObjectFor(closure)},$_$code]');
mainBuffer.add("$N$n");
- }
+ });
// After this assignment we will produce invalid JavaScript code if we use
// the classesCollector variable.
@@ -3995,7 +3201,7 @@
}
}
mainBuffer
- ..write(getReflectionDataParser())
+ ..write(getReflectionDataParser(classesCollector, namer))
..write('([$n');
List<Element> sortedElements =
@@ -4065,7 +3271,7 @@
classesCollector = oldClassesCollector;
}
- emitStaticFunctionGetters(mainBuffer);
+ containerBuilder.emitStaticFunctionGetters(mainBuffer);
emitRuntimeTypeSupport(mainBuffer);
emitGetInterceptorMethods(mainBuffer);
@@ -4238,7 +3444,7 @@
'$_${namer.isolateName}.prototype$N$n'
// The classesCollector object ($$).
'$classesCollector$_=$_{};$n')
- ..write(getReflectionDataParser())
+ ..write(getReflectionDataParser(classesCollector, namer))
..write('([$n')
..addBuffer(deferredLibraries)
..write('])$N');
@@ -4296,139 +3502,4 @@
bool get areAnyElementsDeferred {
return compiler.deferredLoadTask.areAnyElementsDeferred;
}
-
- // TODO(ahe): Remove this when deferred loading is fully implemented.
- void warnNotImplemented(Element element, String message) {
- compiler.reportMessage(compiler.spanFromSpannable(element),
- MessageKind.GENERIC.error({'text': message}),
- api.Diagnostic.WARNING);
- }
-
- // TODO(ahe): This code should be integrated in finishClasses.
- String getReflectionDataParser() {
- String metadataField = '"${namer.metadataField}"';
- String reflectableField = namer.reflectableField;
- String defaultValuesField = namer.defaultValuesField;
- String methodsWithOptionalArgumentsField =
- namer.methodsWithOptionalArgumentsField;
- return '''
-(function (reflectionData) {
-'''
-// [map] returns an object literal that V8 shouldn't try to optimize with a
-// hidden class. This prevents a potential performance problem where V8 tries
-// to build a hidden class for an object used as a hashMap.
-'''
- function map(x){x={x:x};delete x.x;return x}
- if (!init.libraries) init.libraries = [];
- if (!init.mangledNames) init.mangledNames = map();
- if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
- if (!init.statics) init.statics = map();
- if (!init.interfaces) init.interfaces = map();
- if (!init.globalFunctions) init.globalFunctions = map();
- var libraries = init.libraries;
- var mangledNames = init.mangledNames;
- var mangledGlobalNames = init.mangledGlobalNames;
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- var length = reflectionData.length;
- for (var i = 0; i < length; i++) {
- var data = reflectionData[i];
-'''
-// [data] contains these elements:
-// 0. The library name (not unique).
-// 1. The library URI (unique).
-// 2. A function returning the metadata associated with this library.
-// 3. The global object to use for this library.
-// 4. An object literal listing the members of the library.
-// 5. This element is optional and if present it is true and signals that this
-// library is the root library (see dart:mirrors IsolateMirror.rootLibrary).
-//
-// The entries of [data] are built in [assembleProgram] above.
-'''
- var name = data[0];
- var uri = data[1];
- var metadata = data[2];
- var globalObject = data[3];
- var descriptor = data[4];
- var isRoot = !!data[5];
- var fields = descriptor && descriptor[""];
- var classes = [];
- var functions = [];
- function processStatics(descriptor) {
- for (var property in descriptor) {
- if (!hasOwnProperty.call(descriptor, property)) continue;
- if (property === "") continue;
- var element = descriptor[property];
- var firstChar = property.substring(0, 1);
- var previousProperty;
- if (firstChar === "+") {
- mangledGlobalNames[previousProperty] = property.substring(1);
- if (descriptor[property] == 1) ''' // Break long line.
-'''descriptor[previousProperty].$reflectableField = 1;
- if (element && element.length) ''' // Break long line.
-'''init.interfaces[previousProperty] = element;
- } 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);
- init.globalFunctions[property] = element;
- } else {
- previousProperty = property;
- var newDesc = {};
- var previousProp;
- for (var prop in element) {
- if (!hasOwnProperty.call(element, prop)) continue;
- firstChar = prop.substring(0, 1);
- if (prop === "static") {
- processStatics(init.statics[property] = element[prop]);
- } else if (firstChar === "+") {
- mangledNames[previousProp] = prop.substring(1);
- if (element[prop] == 1) ''' // Break long line.
-'''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];
- }
- }
- $classesCollector[property] = [globalObject, newDesc];
- classes.push(property);
- }
- }
- }
- processStatics(descriptor);
- libraries.push([name, uri, classes, functions, metadata, fields, isRoot,
- globalObject]);
- }
-})''';
- }
}
-
-const String GENERATED_BY = """
-// Generated by dart2js, the Dart to JavaScript compiler.
-""";
-
-const String HOOKS_API_USAGE = """
-// The code supports the following hooks:
-// dartPrint(message) - if this function is defined it is called
-// instead of the Dart [print] method.
-// dartMainRunner(main) - if this function is defined, the Dart [main]
-// method will not be invoked directly.
-// Instead, a closure that will invoke [main] is
-// passed to [dartMainRunner].
-""";
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
new file mode 100644
index 0000000..15ad85a
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
@@ -0,0 +1,678 @@
+// 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 dart2js.js_emitter;
+
+/// This class should morph into something that makes it easy to build
+/// JavaScript representations of libraries, class-sides, and instance-sides.
+/// Initially, it is just a placeholder for code that is moved from
+/// [CodeEmitterTask].
+class ContainerBuilder {
+ final Map<Element, Element> staticGetters = new Map<Element, Element>();
+
+ /// A cache of synthesized closures for top-level, static or
+ /// instance methods.
+ final Map<String, Element> methodClosures = <String, Element>{};
+
+ CodeEmitterTask task;
+
+ Namer get namer => task.namer;
+
+ Compiler get compiler => task.compiler;
+
+ String get N => task.N;
+
+ JavaScriptBackend get backend => task.backend;
+
+ /**
+ * Generate stubs to handle invocation of methods with optional
+ * arguments.
+ *
+ * A method like [: foo([x]) :] may be invoked by the following
+ * calls: [: foo(), foo(1), foo(x: 1) :]. See the sources of this
+ * function for detailed examples.
+ */
+ void addParameterStub(FunctionElement member,
+ Selector selector,
+ DefineStubFunction defineStub,
+ Set<String> alreadyGenerated) {
+ FunctionSignature parameters = member.computeSignature(compiler);
+ int positionalArgumentCount = selector.positionalArgumentCount;
+ if (positionalArgumentCount == parameters.parameterCount) {
+ assert(selector.namedArgumentCount == 0);
+ return;
+ }
+ if (parameters.optionalParametersAreNamed
+ && selector.namedArgumentCount == parameters.optionalParameterCount) {
+ // If the selector has the same number of named arguments as the element,
+ // we don't need to add a stub. The call site will hit the method
+ // directly.
+ return;
+ }
+ ConstantHandler handler = compiler.constantHandler;
+ List<SourceString> names = selector.getOrderedNamedArguments();
+
+ String invocationName = namer.invocationName(selector);
+ if (alreadyGenerated.contains(invocationName)) return;
+ alreadyGenerated.add(invocationName);
+
+ bool isInterceptedMethod = backend.isInterceptedMethod(member);
+
+ // If the method is intercepted, we need to also pass the actual receiver.
+ int extraArgumentCount = isInterceptedMethod ? 1 : 0;
+ // Use '$receiver' to avoid clashes with other parameter names. Using
+ // '$receiver' works because [:namer.safeName:] used for getting parameter
+ // names never returns a name beginning with a single '$'.
+ String receiverArgumentName = r'$receiver';
+
+ // The parameters that this stub takes.
+ List<jsAst.Parameter> parametersBuffer =
+ new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount);
+ // The arguments that will be passed to the real method.
+ List<jsAst.Expression> argumentsBuffer =
+ new List<jsAst.Expression>(
+ parameters.parameterCount + extraArgumentCount);
+
+ int count = 0;
+ if (isInterceptedMethod) {
+ count++;
+ parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName);
+ argumentsBuffer[0] = js(receiverArgumentName);
+ task.interceptorInvocationNames.add(invocationName);
+ }
+
+ int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
+ // Includes extra receiver argument when using interceptor convention
+ int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1;
+
+ TreeElements elements =
+ compiler.enqueuer.resolution.getCachedElements(member);
+
+ int parameterIndex = 0;
+ parameters.orderedForEachParameter((Element element) {
+ // Use generic names for closures to facilitate code sharing.
+ String jsName = member is ClosureInvocationElement
+ ? 'p${parameterIndex++}'
+ : backend.namer.safeName(element.name.slowToString());
+ assert(jsName != receiverArgumentName);
+ if (count < optionalParameterStart) {
+ parametersBuffer[count] = new jsAst.Parameter(jsName);
+ argumentsBuffer[count] = js(jsName);
+ } else {
+ int index = names.indexOf(element.name);
+ if (index != -1) {
+ indexOfLastOptionalArgumentInParameters = count;
+ // The order of the named arguments is not the same as the
+ // one in the real method (which is in Dart source order).
+ argumentsBuffer[count] = js(jsName);
+ parametersBuffer[optionalParameterStart + index] =
+ new jsAst.Parameter(jsName);
+ } else {
+ Constant value = handler.initialVariableValues[element];
+ if (value == null) {
+ argumentsBuffer[count] = task.constantReference(new NullConstant());
+ } else {
+ if (!value.isNull()) {
+ // If the value is the null constant, we should not pass it
+ // down to the native method.
+ indexOfLastOptionalArgumentInParameters = count;
+ }
+ argumentsBuffer[count] = task.constantReference(value);
+ }
+ }
+ }
+ count++;
+ });
+
+ List body;
+ if (member.hasFixedBackendName()) {
+ body = task.nativeEmitter.generateParameterStubStatements(
+ member, isInterceptedMethod, invocationName,
+ parametersBuffer, argumentsBuffer,
+ indexOfLastOptionalArgumentInParameters);
+ } else {
+ body = [js.return_(
+ js('this')[namer.getNameOfInstanceMember(member)](argumentsBuffer))];
+ }
+
+ jsAst.Fun function = js.fun(parametersBuffer, body);
+
+ defineStub(invocationName, function);
+
+ String reflectionName = task.getReflectionName(selector, invocationName);
+ if (reflectionName != null) {
+ var reflectable =
+ js(backend.isAccessibleByReflection(member) ? '1' : '0');
+ defineStub('+$reflectionName', reflectable);
+ }
+ }
+
+ void addParameterStubs(FunctionElement member,
+ DefineStubFunction defineStub) {
+ // We fill the lists depending on the selector. For example,
+ // take method foo:
+ // foo(a, b, {c, d});
+ //
+ // We may have multiple ways of calling foo:
+ // (1) foo(1, 2);
+ // (2) foo(1, 2, c: 3);
+ // (3) foo(1, 2, d: 4);
+ // (4) foo(1, 2, c: 3, d: 4);
+ // (5) foo(1, 2, d: 4, c: 3);
+ //
+ // What we generate at the call sites are:
+ // (1) foo$2(1, 2);
+ // (2) foo$3$c(1, 2, 3);
+ // (3) foo$3$d(1, 2, 4);
+ // (4) foo$4$c$d(1, 2, 3, 4);
+ // (5) foo$4$c$d(1, 2, 3, 4);
+ //
+ // The stubs we generate are (expressed in Dart):
+ // (1) foo$2(a, b) => foo$4$c$d(a, b, null, null)
+ // (2) foo$3$c(a, b, c) => foo$4$c$d(a, b, c, null);
+ // (3) foo$3$d(a, b, d) => foo$4$c$d(a, b, null, d);
+ // (4) No stub generated, call is direct.
+ // (5) No stub generated, call is direct.
+
+ // Keep a cache of which stubs have already been generated, to
+ // avoid duplicates. Note that even if selectors are
+ // 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>();
+ 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);
+ Set<Selector> selectors = signature.optionalParametersAreNamed
+ ? computeSeenNamedSelectors(member)
+ : computeOptionalSelectors(signature, member);
+ for (Selector selector in selectors) {
+ addParameterStub(member, selector, defineStub, generatedStubNames);
+ }
+ if (signature.optionalParametersAreNamed && isClosureInvocation) {
+ addCatchAllParameterStub(member, signature, defineStub);
+ }
+ } else {
+ Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
+ if (selectors == null) return;
+ for (Selector selector in selectors) {
+ if (!selector.applies(member, compiler)) continue;
+ addParameterStub(member, selector, defineStub, generatedStubNames);
+ }
+ }
+ }
+
+ Set<Selector> computeSeenNamedSelectors(FunctionElement element) {
+ Set<Selector> selectors = compiler.codegenWorld.invokedNames[element.name];
+ 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);
+ }
+ return result;
+ }
+
+ void addCatchAllParameterStub(FunctionElement member,
+ FunctionSignature signature,
+ DefineStubFunction defineStub) {
+ // See Primities.applyFunction in js_helper.dart for details.
+ List<jsAst.Property> properties = <jsAst.Property>[];
+ for (Element element in signature.orderedOptionalParameters) {
+ String jsName = backend.namer.safeName(element.name.slowToString());
+ Constant value = compiler.constantHandler.initialVariableValues[element];
+ jsAst.Expression reference = null;
+ if (value == null) {
+ reference = new jsAst.LiteralNull();
+ } else {
+ reference = task.constantReference(value);
+ }
+ properties.add(new jsAst.Property(js.string(jsName), reference));
+ }
+ defineStub(
+ backend.namer.callCatchAllName,
+ js.fun([], js.return_(new jsAst.ObjectInitializer(properties))));
+ }
+
+ /**
+ * Compute the set of possible selectors in the presence of optional
+ * non-named parameters.
+ */
+ Set<Selector> computeOptionalSelectors(FunctionSignature signature,
+ FunctionElement element) {
+ Set<Selector> selectors = new Set<Selector>();
+ // Add the selector that does not have any optional argument.
+ selectors.add(new Selector(SelectorKind.CALL,
+ element.name,
+ element.getLibrary(),
+ signature.requiredParameterCount,
+ <SourceString>[]));
+
+ // For each optional parameter, we increment the number of passed
+ // argument.
+ for (int i = 1; i <= signature.optionalParameterCount; i++) {
+ selectors.add(new Selector(SelectorKind.CALL,
+ element.name,
+ element.getLibrary(),
+ signature.requiredParameterCount + i,
+ <SourceString>[]));
+ }
+ return selectors;
+ }
+
+ void emitStaticFunctionGetters(CodeBuffer eagerBuffer) {
+ task.addComment('Static function getters', task.mainBuffer);
+ for (FunctionElement element in
+ Elements.sortedByPosition(staticGetters.keys)) {
+ Element closure = staticGetters[element];
+ CodeBuffer buffer =
+ task.isDeferred(element) ? task.deferredConstants : eagerBuffer;
+ String closureClass = namer.isolateAccess(closure);
+ String name = namer.getStaticClosureName(element);
+
+ String closureName = namer.getStaticClosureName(element);
+ jsAst.Node assignment = js(
+ 'init.globalFunctions["$closureName"] ='
+ ' ${namer.globalObjectFor(element)}.$name ='
+ ' new $closureClass(#, "$closureName")',
+ namer.elementAccess(element));
+ buffer.write(jsAst.prettyPrint(assignment, compiler));
+ buffer.write('$N');
+ }
+ }
+
+ void emitStaticFunctionClosures() {
+ Set<FunctionElement> functionsNeedingGetter =
+ compiler.codegenWorld.staticFunctionsNeedingGetter;
+ for (FunctionElement element in
+ Elements.sortedByPosition(functionsNeedingGetter)) {
+ String superName = namer.getNameOfClass(compiler.closureClass);
+ int parameterCount = element.functionSignature.parameterCount;
+ String name = 'Closure\$$parameterCount';
+ assert(task.instantiatedClasses.contains(compiler.closureClass));
+
+ ClassElement closureClassElement = new ClosureClassElement(
+ null, new SourceString(name), compiler, element,
+ element.getCompilationUnit());
+ // Now add the methods on the closure class. The instance method does not
+ // have the correct name. Since [addParameterStubs] use the name to create
+ // its stubs we simply create a fake element with the correct name.
+ // Note: the callElement will not have any enclosingElement.
+ FunctionElement callElement =
+ new ClosureInvocationElement(namer.closureInvocationSelectorName,
+ element);
+
+ String invocationName = namer.instanceMethodName(callElement);
+ String mangledName = namer.getNameOfClass(closureClassElement);
+
+ // Define the constructor with a name so that Object.toString can
+ // find the class name of the closure class.
+ ClassBuilder closureBuilder = new ClassBuilder();
+ // If a static function is used as a closure we need to add its name
+ // in case it is used in spawnFunction.
+ String methodName = namer.STATIC_CLOSURE_NAME_NAME;
+ List<String> fieldNames = <String>[invocationName, methodName];
+ closureBuilder.addProperty('',
+ js.string("$superName;${fieldNames.join(',')}"));
+
+ addParameterStubs(callElement, closureBuilder.addProperty);
+
+ void emitFunctionTypeSignature(Element method, FunctionType methodType) {
+ RuntimeTypes rti = backend.rti;
+ // [:() => null:] is dummy encoding of [this] which is never needed for
+ // the encoding of the type of the static [method].
+ jsAst.Expression encoding =
+ rti.getSignatureEncoding(methodType, js('null'));
+ String operatorSignature = namer.operatorSignature();
+ // TODO(johnniwinther): Make MiniJsParser support function expressions.
+ closureBuilder.addProperty(operatorSignature, encoding);
+ }
+
+ void emitIsFunctionTypeTest(FunctionType functionType) {
+ String operator = namer.operatorIsType(functionType);
+ closureBuilder.addProperty(operator, js('true'));
+ }
+
+ FunctionType methodType = element.computeType(compiler);
+ Map<FunctionType, bool> functionTypeChecks =
+ task.getFunctionTypeChecksOn(methodType);
+ task.generateFunctionTypeTests(element, methodType, functionTypeChecks,
+ emitFunctionTypeSignature, emitIsFunctionTypeTest);
+
+ closureClassElement =
+ addClosureIfNew(closureBuilder, closureClassElement, fieldNames);
+ staticGetters[element] = closureClassElement;
+
+ }
+ }
+
+ ClassElement addClosureIfNew(ClassBuilder builder,
+ ClassElement closure,
+ List<String> fieldNames) {
+ String key =
+ jsAst.prettyPrint(builder.toObjectInitializer(), compiler).getText();
+ return methodClosures.putIfAbsent(key, () {
+ String mangledName = namer.getNameOfClass(closure);
+ emitClosureInPrecompiledFunction(mangledName, fieldNames);
+ return closure;
+ });
+ }
+
+ void emitClosureInPrecompiledFunction(String mangledName,
+ List<String> fieldNames) {
+ List<String> fields = fieldNames;
+ String constructorName = mangledName;
+ task.precompiledFunction.add(new jsAst.FunctionDeclaration(
+ new jsAst.VariableDeclaration(constructorName),
+ js.fun(fields, fields.map(
+ (name) => js('this.$name = $name')).toList())));
+ task.precompiledFunction.addAll([
+ js('$constructorName.builtin\$cls = "$constructorName"'),
+ js('\$desc=\$collectedClasses.$constructorName'),
+ js.if_('\$desc instanceof Array', js('\$desc = \$desc[1]')),
+ js('$constructorName.prototype = \$desc'),
+ ]);
+
+ task.precompiledConstructorNames.add(js(constructorName));
+ }
+
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [member] must be a declaration element.
+ */
+ void emitDynamicFunctionGetter(FunctionElement member,
+ DefineStubFunction defineStub) {
+ assert(invariant(member, member.isDeclaration));
+ assert(task.instantiatedClasses.contains(compiler.boundClosureClass));
+ // For every method that has the same name as a property-get we create a
+ // getter that returns a bound closure. Say we have a class 'A' with method
+ // 'foo' and somewhere in the code there is a dynamic property get of
+ // 'foo'. Then we generate the following code (in pseudo Dart/JavaScript):
+ //
+ // class A {
+ // foo(x, y, z) { ... } // Original function.
+ // get foo { return new BoundClosure499(this, "foo"); }
+ // }
+ // class BoundClosure499 extends BoundClosure {
+ // BoundClosure499(this.self, this.name);
+ // $call3(x, y, z) { return self[name](x, y, z); }
+ // }
+
+ bool hasOptionalParameters = member.optionalParameterCount(compiler) != 0;
+ int parameterCount = member.parameterCount(compiler);
+
+ // Intercepted methods take an extra parameter, which is the
+ // receiver of the call.
+ bool inInterceptor = backend.isInterceptedMethod(member);
+ List<String> fieldNames = <String>[];
+ compiler.boundClosureClass.forEachInstanceField((_, Element field) {
+ fieldNames.add(namer.getNameOfInstanceMember(field));
+ });
+
+ ClassElement classElement = member.getEnclosingClass();
+ String name = inInterceptor
+ ? 'BoundClosure\$i${parameterCount}'
+ : 'BoundClosure\$${parameterCount}';
+
+ ClassElement closureClassElement = new ClosureClassElement(
+ null, new SourceString(name), compiler, member,
+ member.getCompilationUnit());
+ String superName = namer.getNameOfClass(closureClassElement.superclass);
+
+ // Define the constructor with a name so that Object.toString can
+ // find the class name of the closure class.
+ ClassBuilder boundClosureBuilder = new ClassBuilder();
+ boundClosureBuilder.addProperty('',
+ js.string("$superName;${fieldNames.join(',')}"));
+ // Now add the methods on the closure class. The instance method does not
+ // have the correct name. Since [addParameterStubs] use the name to create
+ // its stubs we simply create a fake element with the correct name.
+ // Note: the callElement will not have any enclosingElement.
+ FunctionElement callElement = new ClosureInvocationElement(
+ namer.closureInvocationSelectorName, member);
+
+ String invocationName = namer.instanceMethodName(callElement);
+
+ List<String> parameters = <String>[];
+ List<jsAst.Expression> arguments =
+ <jsAst.Expression>[js('this')[fieldNames[0]]];
+ if (inInterceptor) {
+ arguments.add(js('this')[fieldNames[2]]);
+ }
+ for (int i = 0; i < parameterCount; i++) {
+ String name = 'p$i';
+ parameters.add(name);
+ arguments.add(js(name));
+ }
+
+ jsAst.Expression fun = js.fun(
+ parameters,
+ js.return_(
+ js('this')[fieldNames[1]]['call'](arguments)));
+ boundClosureBuilder.addProperty(invocationName, fun);
+
+ addParameterStubs(callElement, boundClosureBuilder.addProperty);
+
+ void emitFunctionTypeSignature(Element method, FunctionType methodType) {
+ jsAst.Expression encoding = backend.rti.getSignatureEncoding(
+ methodType, js('this')[fieldNames[0]]);
+ String operatorSignature = namer.operatorSignature();
+ boundClosureBuilder.addProperty(operatorSignature, encoding);
+ }
+
+ void emitIsFunctionTypeTest(FunctionType functionType) {
+ String operator = namer.operatorIsType(functionType);
+ boundClosureBuilder.addProperty(operator,
+ new jsAst.LiteralBool(true));
+ }
+
+ DartType memberType = member.computeType(compiler);
+ Map<FunctionType, bool> functionTypeChecks =
+ task.getFunctionTypeChecksOn(memberType);
+
+ task.generateFunctionTypeTests(member, memberType, functionTypeChecks,
+ emitFunctionTypeSignature, emitIsFunctionTypeTest);
+
+ closureClassElement =
+ addClosureIfNew(boundClosureBuilder, closureClassElement, fieldNames);
+
+ String closureClass = namer.isolateAccess(closureClassElement);
+
+ // And finally the getter.
+ String getterName = namer.getterName(member);
+ String targetName = namer.instanceMethodName(member);
+
+ parameters = <String>[];
+ jsAst.PropertyAccess method =
+ backend.namer.elementAccess(classElement)['prototype'][targetName];
+ arguments = <jsAst.Expression>[js('this'), method];
+
+ if (inInterceptor) {
+ String receiverArg = fieldNames[2];
+ parameters.add(receiverArg);
+ arguments.add(js(receiverArg));
+ } else {
+ // Put null in the intercepted receiver field.
+ arguments.add(new jsAst.LiteralNull());
+ }
+
+ arguments.add(js.string(targetName));
+
+ jsAst.Expression getterFunction = js.fun(
+ parameters, js.return_(js(closureClass).newWith(arguments)));
+
+ defineStub(getterName, getterFunction);
+ }
+
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [member] must be a declaration element.
+ */
+ void emitCallStubForGetter(Element member,
+ Set<Selector> selectors,
+ DefineStubFunction defineStub) {
+ assert(invariant(member, member.isDeclaration));
+ LibraryElement memberLibrary = member.getLibrary();
+ // If the method is intercepted, the stub gets the
+ // receiver explicitely and we need to pass it to the getter call.
+ bool isInterceptedMethod = backend.isInterceptedMethod(member);
+
+ const String receiverArgumentName = r'$receiver';
+
+ jsAst.Expression buildGetter() {
+ if (member.isGetter()) {
+ String getterName = namer.getterName(member);
+ return js('this')[getterName](
+ isInterceptedMethod
+ ? <jsAst.Expression>[js(receiverArgumentName)]
+ : <jsAst.Expression>[]);
+ } else {
+ String fieldName = member.hasFixedBackendName()
+ ? member.fixedBackendName()
+ : namer.instanceFieldName(member);
+ return js('this')[fieldName];
+ }
+ }
+
+ // Two selectors may match but differ only in type. To avoid generating
+ // identical stubs for each we track untyped selectors which already have
+ // stubs.
+ Set<Selector> generatedSelectors = new Set<Selector>();
+ for (Selector selector in selectors) {
+ if (selector.applies(member, compiler)) {
+ selector = selector.asUntyped;
+ if (generatedSelectors.contains(selector)) continue;
+ generatedSelectors.add(selector);
+
+ String invocationName = namer.invocationName(selector);
+ Selector callSelector = new Selector.callClosureFrom(selector);
+ String closureCallName = namer.invocationName(callSelector);
+
+ List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
+ List<jsAst.Expression> arguments = <jsAst.Expression>[];
+ if (isInterceptedMethod) {
+ parameters.add(new jsAst.Parameter(receiverArgumentName));
+ }
+
+ for (int i = 0; i < selector.argumentCount; i++) {
+ String name = 'arg$i';
+ parameters.add(new jsAst.Parameter(name));
+ arguments.add(js(name));
+ }
+
+ jsAst.Fun function = js.fun(
+ parameters,
+ js.return_(buildGetter()[closureCallName](arguments)));
+
+ defineStub(invocationName, function);
+ }
+ }
+ }
+
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [member] must be a declaration element.
+ */
+ void emitExtraAccessors(Element member, ClassBuilder builder) {
+ assert(invariant(member, member.isDeclaration));
+ if (member.isGetter() || member.isField()) {
+ Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
+ if (selectors != null && !selectors.isEmpty) {
+ emitCallStubForGetter(member, selectors, builder.addProperty);
+ }
+ } else if (member.isFunction()) {
+ if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) {
+ emitDynamicFunctionGetter(member, builder.addProperty);
+ }
+ }
+ }
+
+ void addMember(Element member, ClassBuilder builder) {
+ assert(invariant(member, member.isDeclaration));
+
+ if (member.isField()) {
+ addMemberField(member, builder);
+ } else if (member.isFunction() ||
+ member.isGenerativeConstructorBody() ||
+ member.isGenerativeConstructor() ||
+ member.isAccessor()) {
+ addMemberMethod(member, builder);
+ } else {
+ compiler.internalErrorOnElement(
+ member, 'unexpected kind: "${member.kind}"');
+ }
+ if (member.isInstanceMember()) emitExtraAccessors(member, builder);
+ }
+
+ void addMemberMethod(FunctionElement member, ClassBuilder builder) {
+ if (member.isAbstract(compiler)) return;
+ jsAst.Expression code = backend.generatedCode[member];
+ if (code == null) return;
+ String name = namer.getNameOfMember(member);
+ if (backend.isInterceptedMethod(member)) {
+ task.interceptorInvocationNames.add(name);
+ }
+ code = extendWithMetadata(member, code);
+ builder.addProperty(name, code);
+ String reflectionName = task.getReflectionName(member, name);
+ if (reflectionName != null) {
+ var reflectable =
+ js(backend.isAccessibleByReflection(member) ? '1' : '0');
+ builder.addProperty('+$reflectionName', reflectable);
+ jsAst.Node defaultValues = task.reifyDefaultArguments(member);
+ if (defaultValues != null) {
+ String unmangledName = member.name.slowToString();
+ builder.addProperty('*$unmangledName', defaultValues);
+ }
+ }
+ code = backend.generatedBailoutCode[member];
+ if (code != null) {
+ builder.addProperty(namer.getBailoutName(member), code);
+ }
+ if (member.isInstanceMember()) {
+ // TODO(ahe): Where is this done for static/top-level methods?
+ FunctionSignature parameters = member.computeSignature(compiler);
+ if (!parameters.optionalParameters.isEmpty) {
+ addParameterStubs(member, builder.addProperty);
+ }
+ }
+ }
+
+ void addMemberField(VariableElement member, ClassBuilder builder) {
+ // For now, do nothing.
+ }
+
+ jsAst.Fun extendWithMetadata(FunctionElement element, jsAst.Fun code) {
+ if (!backend.retainMetadataOf(element)) return code;
+ return compiler.withCurrentElement(element, () {
+ List<int> metadata = <int>[];
+ FunctionSignature signature = element.functionSignature;
+ if (element.isConstructor()) {
+ metadata.add(task.reifyType(element.getEnclosingClass().thisType));
+ } else {
+ metadata.add(task.reifyType(signature.returnType));
+ }
+ signature.forEachParameter((Element parameter) {
+ metadata
+ ..add(task.reifyName(parameter.name))
+ ..add(task.reifyType(parameter.computeType(compiler)));
+ });
+ Link link = element.metadata;
+ // TODO(ahe): Why is metadata sometimes null?
+ if (link != null) {
+ for (; !link.isEmpty; link = link.tail) {
+ metadata.add(task.reifyMetadata(link.head));
+ }
+ }
+ code.body.statements.add(js.string(metadata.join(',')).toStatement());
+ return code;
+ });
+ }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
new file mode 100644
index 0000000..7a3e055
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
@@ -0,0 +1,61 @@
+// 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 dart2js.js_emitter;
+
+/// Enables debugging of fast/slow objects using V8-specific primitives.
+const DEBUG_FAST_OBJECTS = false;
+
+/**
+ * A convenient type alias for some functions that emit keyed values.
+ */
+typedef void DefineStubFunction(String invocationName, jsAst.Expression value);
+
+/**
+ * [member] is a field (instance, static, or top level).
+ *
+ * [name] is the field name that the [Namer] has picked for this field's
+ * storage, that is, the JavaScript property name.
+ *
+ * [accessorName] is the name of the accessor. For instance fields this is
+ * mostly the same as [name] except when [member] is shadowing a field in its
+ * superclass. For other fields, they are rarely the same.
+ *
+ * [needsGetter] and [needsSetter] represent if a getter or a setter
+ * respectively is needed. There are many factors in this, for example, if the
+ * accessor can be inlined.
+ *
+ * [needsCheckedSetter] indicates that a checked getter is needed, and in this
+ * case, [needsSetter] is always false. [needsCheckedSetter] is only true when
+ * type assertions are enabled (checked mode).
+ */
+typedef void AcceptField(VariableElement member,
+ String name,
+ String accessorName,
+ bool needsGetter,
+ bool needsSetter,
+ bool needsCheckedSetter);
+
+// Function signatures used in the generation of runtime type information.
+typedef void FunctionTypeSignatureEmitter(Element method,
+ FunctionType methodType);
+
+// TODO(johnniwinther): Clean up terminology for rti in the emitter.
+typedef void FunctionTypeTestEmitter(FunctionType functionType);
+
+typedef void SubstitutionEmitter(Element element, {bool emitNull});
+
+const String GENERATED_BY = """
+// Generated by dart2js, the Dart to JavaScript compiler.
+""";
+
+const String HOOKS_API_USAGE = """
+// The code supports the following hooks:
+// dartPrint(message) - if this function is defined it is called
+// instead of the Dart [print] method.
+// dartMainRunner(main) - if this function is defined, the Dart [main]
+// method will not be invoked directly.
+// Instead, a closure that will invoke [main] is
+// passed to [dartMainRunner].
+""";
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
new file mode 100644
index 0000000..dfd526b
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
@@ -0,0 +1,63 @@
+// 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 dart2js.js_emitter;
+
+import 'dart:collection' show LinkedHashMap, Queue;
+
+import '../common.dart';
+
+import '../js/js.dart' as jsAst;
+
+import '../closure.dart' show
+ ClosureClassElement,
+ ClosureClassMap,
+ ClosureFieldElement;
+
+import '../dart2jslib.dart' show
+ CodeBuffer;
+
+import '../elements/modelx.dart' show
+ FunctionElementX;
+
+import '../js/js.dart' show
+ js;
+
+import '../js_backend/js_backend.dart' show
+ CheckedModeHelper,
+ CheckedModeHelper,
+ ConstantEmitter,
+ JavaScriptBackend,
+ JavaScriptBackend,
+ Namer,
+ NativeEmitter,
+ RuntimeTypes,
+ Substitution,
+ TypeCheck,
+ TypeChecks;
+
+import '../source_file.dart' show
+ SourceFile;
+
+import '../source_map_builder.dart' show
+ SourceMapBuilder;
+
+import '../util/characters.dart' show
+ $$,
+ $A,
+ $HASH,
+ $PERIOD,
+ $Z,
+ $a,
+ $z;
+
+import '../util/uri_extras.dart' show
+ relativize;
+
+part 'class_builder.dart';
+part 'closure_invocation_element.dart';
+part 'code_emitter_task.dart';
+part 'container_builder.dart';
+part 'declarations.dart';
+part 'reflection_data_parser.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
new file mode 100644
index 0000000..d90caf6
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
@@ -0,0 +1,119 @@
+// 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 dart2js.js_emitter;
+
+// TODO(ahe): This code should be integrated in CodeEmitterTask.finishClasses.
+String getReflectionDataParser(String classesCollector, Namer namer) {
+ String metadataField = '"${namer.metadataField}"';
+ String reflectableField = namer.reflectableField;
+ String defaultValuesField = namer.defaultValuesField;
+ String methodsWithOptionalArgumentsField =
+ namer.methodsWithOptionalArgumentsField;
+ return '''
+(function (reflectionData) {
+'''
+// [map] returns an object literal that V8 shouldn't try to optimize with a
+// hidden class. This prevents a potential performance problem where V8 tries
+// to build a hidden class for an object used as a hashMap.
+'''
+ function map(x){x={x:x};delete x.x;return x}
+ if (!init.libraries) init.libraries = [];
+ if (!init.mangledNames) init.mangledNames = map();
+ if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
+ if (!init.statics) init.statics = map();
+ if (!init.interfaces) init.interfaces = map();
+ if (!init.globalFunctions) init.globalFunctions = map();
+ var libraries = init.libraries;
+ var mangledNames = init.mangledNames;
+ var mangledGlobalNames = init.mangledGlobalNames;
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+ var length = reflectionData.length;
+ for (var i = 0; i < length; i++) {
+ var data = reflectionData[i];
+'''
+// [data] contains these elements:
+// 0. The library name (not unique).
+// 1. The library URI (unique).
+// 2. A function returning the metadata associated with this library.
+// 3. The global object to use for this library.
+// 4. An object literal listing the members of the library.
+// 5. This element is optional and if present it is true and signals that this
+// library is the root library (see dart:mirrors IsolateMirror.rootLibrary).
+//
+// The entries of [data] are built in [assembleProgram] above.
+'''
+ var name = data[0];
+ var uri = data[1];
+ var metadata = data[2];
+ var globalObject = data[3];
+ var descriptor = data[4];
+ var isRoot = !!data[5];
+ var fields = descriptor && descriptor[""];
+ var classes = [];
+ var functions = [];
+ function processStatics(descriptor) {
+ for (var property in descriptor) {
+ if (!hasOwnProperty.call(descriptor, property)) continue;
+ if (property === "") continue;
+ var element = descriptor[property];
+ var firstChar = property.substring(0, 1);
+ var previousProperty;
+ if (firstChar === "+") {
+ mangledGlobalNames[previousProperty] = property.substring(1);
+ if (descriptor[property] == 1) ''' // Break long line.
+'''descriptor[previousProperty].$reflectableField = 1;
+ if (element && element.length) ''' // Break long line.
+'''init.interfaces[previousProperty] = element;
+ } 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);
+ init.globalFunctions[property] = element;
+ } else {
+ previousProperty = property;
+ var newDesc = {};
+ var previousProp;
+ for (var prop in element) {
+ if (!hasOwnProperty.call(element, prop)) continue;
+ firstChar = prop.substring(0, 1);
+ if (prop === "static") {
+ processStatics(init.statics[property] = element[prop]);
+ } else if (firstChar === "+") {
+ mangledNames[previousProp] = prop.substring(1);
+ if (element[prop] == 1) ''' // Break long line.
+'''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];
+ }
+ }
+ $classesCollector[property] = [globalObject, newDesc];
+ classes.push(property);
+ }
+ }
+ }
+ processStatics(descriptor);
+ libraries.push([name, uri, classes, functions, metadata, fields, isRoot,
+ globalObject]);
+ }
+})''';
+}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 5431753..79bb281 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -14,7 +14,6 @@
import '../resolution/resolution.dart' show Scope;
import '../dart2jslib.dart';
import '../dart_types.dart';
-import '../source_file.dart';
import '../tree/tree.dart';
import '../util/util.dart' show Spannable, Link;
import '../util/characters.dart' show $CR, $LF;
@@ -634,7 +633,7 @@
Dart2JsSourceLocation(this._script, this._span);
int _computeLine() {
- var sourceFile = _script.file as SourceFile;
+ var sourceFile = _script.file;
if (sourceFile != null) {
return sourceFile.getLine(offset) + 1;
}
@@ -658,7 +657,7 @@
int _computeColumn() {
if (length == 0) return 0;
- var sourceFile = _script.file as SourceFile;
+ var sourceFile = _script.file;
if (sourceFile != null) {
return sourceFile.getColumn(sourceFile.getLine(offset), offset) + 1;
}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
index 98707c6..aad7d8b 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
@@ -134,11 +134,11 @@
for (Node argument in node.send.arguments) {
NamedArgument named = argument.asNamedArgument();
if (named == null) continue;
- Constant value = compiler.metadataHandler.compileNodeWithDefinitions(
+ Constant value = compiler.constantHandler.compileNodeWithDefinitions(
named.expression, mapping, isConst: true);
ConstantMapper mapper =
- new ConstantMapper(compiler.metadataHandler, mapping, compiler);
+ new ConstantMapper(compiler.constantHandler, mapping, compiler);
named.expression.accept(mapper);
MirrorUsageBuilder builder =
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 9643027..e475aa7 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -16,7 +16,7 @@
import 'universe/universe.dart' show SideEffects;
import 'util/util.dart';
import 'js/js.dart' as js;
-
+import 'js_emitter/js_emitter.dart' show CodeEmitterTask;
/// This class is a temporary work-around until we get a more powerful DartType.
class SpecialType {
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 2658d01..af4208d 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -25,6 +25,8 @@
Selector setIteratorSelector(ForIn node, Selector selector);
Selector setMoveNextSelector(ForIn node, Selector selector);
Selector setCurrentSelector(ForIn node, Selector selector);
+ void setConstant(Node node, Constant constant);
+ Constant getConstant(Node node);
/**
* Returns [:true:] if [node] is a type literal.
@@ -46,6 +48,7 @@
final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>();
final Set<Node> superUses = new LinkedHashSet<Node>();
final Set<Element> otherDependencies = new LinkedHashSet<Element>();
+ final Map<Node, Constant> constants = new Map<Node, Constant>();
final int hashCode = ++hashCodeCounter;
static int hashCodeCounter = 0;
@@ -140,6 +143,14 @@
return selectors[node.inToken];
}
+ void setConstant(Node node, Constant constant) {
+ constants[node] = constant;
+ }
+
+ Constant getConstant(Node node) {
+ return constants[node];
+ }
+
bool isTypeLiteral(Send node) {
return getType(node) != null;
}
@@ -348,7 +359,11 @@
TreeElements elements =
compiler.enqueuer.resolution.getCachedElements(element);
if (elements != null) {
- assert(isConstructor);
+ // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
+ // should never be non-null, not even for constructors.
+ assert(invariant(element, isConstructor,
+ message: 'Non-constructor element $element '
+ 'has already been analyzed.'));
return elements;
}
if (element.isSynthesized) {
@@ -402,7 +417,12 @@
} else if (tree.initializers != null) {
error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
}
- visitBody(visitor, tree.body);
+
+ if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) {
+ // We need to analyze the redirecting factory bodies to ensure that
+ // we can analyze compile-time constants.
+ visitor.visit(tree.body);
+ }
// Get the resolution tree and check that the resolved
// function doesn't use 'super' if it is mixed into another
@@ -448,15 +468,26 @@
ResolverVisitor visitor = visitorFor(element);
visitor.useElement(tree, element);
- // TODO(johnniwinther): Avoid analyzing initializers if
- // [Compiler.analyzeSignaturesOnly] is set.
- initializerDo(tree, visitor.visit);
+ SendSet send = tree.asSendSet();
+ if (send != null) {
+ // TODO(johnniwinther): Avoid analyzing initializers if
+ // [Compiler.analyzeSignaturesOnly] is set.
+ visitor.visit(send.arguments.head);
+ } else if (element.modifiers.isConst()) {
+ compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER);
+ }
if (Elements.isStaticOrTopLevelField(element)) {
+ visitor.addPostProcessAction(element, () {
+ compiler.constantHandler.compileVariable(
+ element, isConst: element.modifiers.isConst());
+ });
if (tree.asSendSet() != null) {
- // TODO(13429): We could do better here by using the
- // constant handler to figure out if it's a lazy field or not.
- compiler.backend.registerLazyField(visitor.mapping);
+ if (!element.modifiers.isConst()) {
+ // TODO(johnniwinther): Determine the const-ness eagerly to avoid
+ // unnecessary registrations.
+ compiler.backend.registerLazyField(visitor.mapping);
+ }
} else {
compiler.enqueuer.resolution.registerInstantiatedClass(
compiler.nullClass, visitor.mapping);
@@ -1038,8 +1069,10 @@
}
ResolverVisitor visitor = visitorFor(context);
node.accept(visitor);
- annotation.value = compiler.metadataHandler.compileNodeWithDefinitions(
+ annotation.value = compiler.constantHandler.compileNodeWithDefinitions(
node, visitor.mapping, isConst: true);
+ compiler.backend.registerMetadataConstant(annotation.value,
+ visitor.mapping);
annotation.resolutionState = STATE_DONE;
}));
@@ -1390,6 +1423,10 @@
void unimplemented(Node node, String message) {
compiler.unimplemented(message, node: node);
}
+
+ void addPostProcessAction(Element element, PostProcessAction action) {
+ compiler.enqueuer.resolution.addPostProcessAction(element, action);
+ }
}
abstract class LabelScope {
@@ -1652,7 +1689,7 @@
// Remove the guarded when this is fixed.
if (!compiler.enqueuer.resolution.queueIsClosed &&
addTypeVariableBoundsCheck) {
- compiler.enqueuer.resolution.addPostProcessAction(
+ visitor.addPostProcessAction(
visitor.enclosingElement,
() => checkTypeVariableBounds(node, type));
}
@@ -2028,6 +2065,11 @@
}
parameterNodes = parameterNodes.tail;
});
+ addPostProcessAction(enclosingElement, () {
+ functionParameters.forEachOptionalParameter((Element parameter) {
+ compiler.constantHandler.compileConstant(parameter);
+ });
+ });
if (inCheckContext) {
functionParameters.forEachParameter((Element element) {
compiler.enqueuer.resolution.registerIsCheck(
@@ -2399,6 +2441,9 @@
// type literal.
mapping.setType(node, compiler.typeClass.computeType(compiler));
world.registerTypeLiteral(target, mapping);
+
+ // Don't try to make constants of calls to type literals.
+ analyzeConstant(node, isConst: !node.isCall);
}
}
@@ -2510,7 +2555,11 @@
}
} else if (target.impliesType()) {
compiler.backend.registerThrowNoSuchMethod(mapping);
- } else if (target.modifiers.isFinal() || target.modifiers.isConst()) {
+ } else if (target.modifiers.isFinal() ||
+ target.modifiers.isConst() ||
+ (target.isFunction() &&
+ Elements.isStaticOrTopLevelFunction(target) &&
+ !target.isSetter())) {
setter = warnAndCreateErroneousElement(
node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER);
compiler.backend.registerThrowNoSuchMethod(mapping);
@@ -2615,6 +2664,7 @@
compiler.reportError(node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
{'value': node.slowNameString});
}
+ analyzeConstant(node);
}
visitStringJuxtaposition(StringJuxtaposition node) {
@@ -2700,7 +2750,7 @@
// Register a post process to check for cycles in the redirection chain and
// set the actual generative constructor at the end of the chain.
- compiler.enqueuer.resolution.addPostProcessAction(constructor, () {
+ addPostProcessAction(constructor, () {
compiler.resolver.resolveRedirectionChain(constructor, node);
});
@@ -2734,7 +2784,9 @@
Modifiers modifiers = node.modifiers;
void reportExtraModifier(String modifier) {
Node modifierNode;
- for (var nodes = modifiers.nodes; !nodes.isEmpty; nodes = nodes.tail) {
+ for (Link<Node> nodes = modifiers.nodes.nodes;
+ !nodes.isEmpty;
+ nodes = nodes.tail) {
if (modifier == nodes.head.asIdentifier().source.stringValue) {
modifierNode = nodes.head;
break;
@@ -2750,7 +2802,14 @@
if (modifiers.isVar() && (modifiers.isConst() || node.type != null)) {
reportExtraModifier('var');
}
-
+ if (enclosingElement.isFunction()) {
+ if (modifiers.isAbstract()) {
+ reportExtraModifier('abstract');
+ }
+ if (modifiers.isStatic()) {
+ reportExtraModifier('static');
+ }
+ }
visitor.visit(node.definitions);
}
@@ -2803,7 +2862,7 @@
if (isSymbolConstructor) {
if (node.isConst()) {
Node argumentNode = node.send.arguments.head;
- Constant name = compiler.metadataHandler.compileNodeWithDefinitions(
+ Constant name = compiler.constantHandler.compileNodeWithDefinitions(
argumentNode, mapping, isConst: true);
if (!name.isString()) {
DartType type = name.computeType(compiler);
@@ -2828,10 +2887,20 @@
} else if (isMirrorsUsedConstant) {
compiler.mirrorUsageAnalyzerTask.validate(node, mapping);
}
+ if (node.isConst()) {
+ analyzeConstant(node);
+ }
return null;
}
+ void analyzeConstant(Node node, {bool isConst: true}) {
+ addPostProcessAction(enclosingElement, () {
+ compiler.constantHandler.compileNodeWithDefinitions(
+ node, mapping, isConst: isConst);
+ });
+ }
+
bool validateSymbol(Node node, String name, {bool reportError: true}) {
if (name.isEmpty) return true;
if (name.startsWith('_')) {
@@ -2915,6 +2984,9 @@
world.registerInstantiatedType(listType, mapping);
compiler.backend.registerRequiredType(listType, enclosingElement);
visit(node.elements);
+ if (node.isConst()) {
+ analyzeConstant(node);
+ }
}
visitConditional(Conditional node) {
@@ -3130,6 +3202,9 @@
}
compiler.backend.registerRequiredType(mapType, enclosingElement);
node.visitChildren(this);
+ if (node.isConst()) {
+ analyzeConstant(node);
+ }
}
visitLiteralMapEntry(LiteralMapEntry node) {
@@ -3149,7 +3224,11 @@
while (!cases.isEmpty) {
SwitchCase switchCase = cases.head;
for (Node labelOrCase in switchCase.labelsAndCases) {
- if (labelOrCase is! Label) continue;
+ CaseMatch caseMatch = labelOrCase.asCaseMatch();
+ if (caseMatch != null) {
+ analyzeConstant(caseMatch.expression);
+ continue;
+ }
Label label = labelOrCase;
String labelName = label.slowToString();
@@ -3355,8 +3434,7 @@
bound = element.bound;
}
}
- compiler.enqueuer.resolution.addPostProcessAction(
- element, checkTypeVariableBound);
+ addPostProcessAction(element, checkTypeVariableBound);
} else {
variableElement.bound = compiler.objectClass.computeType(compiler);
}
@@ -3396,8 +3474,7 @@
var visitor = new TypedefCyclicVisitor(compiler, element);
type.accept(visitor, null);
}
- compiler.enqueuer.resolution.addPostProcessAction(element,
- checkCyclicReference);
+ addPostProcessAction(element, checkCyclicReference);
}
}
@@ -3529,7 +3606,8 @@
DartType supertype = resolveSupertype(element, superMixin.superclass);
Link<Node> link = superMixin.mixins.nodes;
while (!link.isEmpty) {
- supertype = applyMixin(supertype, resolveType(link.head), node);
+ supertype = applyMixin(
+ supertype, checkMixinType(link.head), link.head);
link = link.tail;
}
element.supertype = supertype;
@@ -3580,6 +3658,17 @@
return element.computeType(compiler);
}
+ /// Resolves the mixed type for [mixinNode] and checks that the the mixin type
+ /// is not black-listed. The mixin type is returned.
+ DartType checkMixinType(TypeAnnotation mixinNode) {
+ DartType mixinType = resolveType(mixinNode);
+ if (isBlackListed(mixinType)) {
+ compiler.reportError(mixinNode,
+ MessageKind.CANNOT_MIXIN, {'type': mixinType});
+ }
+ return mixinType;
+ }
+
DartType visitNamedMixinApplication(NamedMixinApplication node) {
compiler.ensure(element != null);
compiler.ensure(element.resolutionState == STATE_STARTED);
@@ -3593,10 +3682,10 @@
DartType supertype = resolveSupertype(element, node.superclass);
Link<Node> link = node.mixins.nodes;
while (!link.tail.isEmpty) {
- supertype = applyMixin(supertype, resolveType(link.head), link.head);
+ supertype = applyMixin(supertype, checkMixinType(link.head), link.head);
link = link.tail;
}
- doApplyMixinTo(element, supertype, resolveType(link.head));
+ doApplyMixinTo(element, supertype, checkMixinType(link.head));
return element.computeType(compiler);
}
@@ -3903,9 +3992,10 @@
void visitIdentifier(Identifier node) {
Element element = context.lookup(node.source);
if (element == null) {
- error(node, MessageKind.CANNOT_RESOLVE_TYPE.error, {'typeName': node});
+ compiler.reportError(
+ node, MessageKind.CANNOT_RESOLVE_TYPE.error, {'typeName': node});
} else if (!element.impliesType()) {
- error(node, MessageKind.NOT_A_TYPE.error, {'node': node});
+ compiler.reportError(node, MessageKind.NOT_A_TYPE.error, {'node': node});
} else {
if (element.isClass()) {
loadSupertype(element, node);
@@ -3981,6 +4071,11 @@
VariableElement element =
new VariableElementX(name, variables, kind, link.head);
resolver.defineElement(link.head, element);
+ if (definitions.modifiers.isConst()) {
+ compiler.enqueuer.resolution.addPostProcessAction(element, () {
+ compiler.constantHandler.compileVariable(element, isConst: true);
+ });
+ }
}
}
}
@@ -3993,6 +4088,7 @@
final bool defaultValuesAllowed;
Link<Element> optionalParameters = const Link<Element>();
int optionalParameterCount = 0;
+ bool isOptionalParameter = false;
bool optionalParametersAreNamed = false;
VariableDefinitions currentDefinitions;
@@ -4008,6 +4104,7 @@
internalError(node, "expected optional parameters");
}
optionalParametersAreNamed = (identical(value, '{'));
+ isOptionalParameter = true;
LinkBuilder<Element> elements = analyzeNodes(node.nodes);
optionalParameterCount = elements.length;
optionalParameters = elements.toLink();
@@ -4044,7 +4141,17 @@
return element;
}
+ void validateName(Identifier node) {
+ SourceString name = node.source;
+ if (isOptionalParameter &&
+ optionalParametersAreNamed &&
+ node.source.isPrivate()) {
+ compiler.reportError(node, MessageKind.PRIVATE_NAMED_PARAMETER);
+ }
+ }
+
Element visitIdentifier(Identifier node) {
+ validateName(node);
Element variables = new VariableListElementX.node(currentDefinitions,
ElementKind.VARIABLE_LIST, enclosingElement);
// Ensure a parameter is not typed 'void'.
@@ -4057,12 +4164,14 @@
var identifier = node.selector.asIdentifier();
if (identifier != null) {
// Normal parameter: [:Type name:].
+ validateName(identifier);
return identifier.source;
} else {
// Function type parameter: [:void name(DartType arg):].
var functionExpression = node.selector.asFunctionExpression();
if (functionExpression != null &&
functionExpression.name.asIdentifier() != null) {
+ validateName(functionExpression.name);
return functionExpression.name.asIdentifier().source;
} else {
cancel(node,
@@ -4106,9 +4215,11 @@
node.selector.asFunctionExpression() != null) {
Element variables = new VariableListElementX.node(currentDefinitions,
ElementKind.VARIABLE_LIST, enclosingElement);
- SourceString source = node.selector.asIdentifier() != null ?
- node.selector.asIdentifier().source :
- node.selector.asFunctionExpression().name.asIdentifier().source;
+ Identifier identifier = node.selector.asIdentifier() != null ?
+ node.selector.asIdentifier() :
+ node.selector.asFunctionExpression().name.asIdentifier();
+ validateName(identifier);
+ SourceString source = identifier.source;
element = new VariableElementX(source, variables,
ElementKind.PARAMETER, node);
}
@@ -4123,6 +4234,14 @@
}
Element visitFunctionExpression(FunctionExpression node) {
+ Modifiers modifiers = currentDefinitions.modifiers;
+ if (modifiers.isFinal()) {
+ compiler.reportError(modifiers,
+ MessageKind.FINAL_FUNCTION_TYPE_PARAMETER);
+ }
+ if (modifiers.isVar()) {
+ compiler.reportError(modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER);
+ }
// This is a function typed parameter.
// TODO(ahe): Resolve the function type.
return visit(node.name);
@@ -4238,7 +4357,7 @@
compiler.backend.registerThrowRuntimeError(resolver.mapping);
}
if (inConstContext) {
- error(diagnosticNode, kind.error, arguments);
+ compiler.reportError(diagnosticNode, kind.error, arguments);
} else {
ResolutionWarning warning =
new ResolutionWarning(
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index dc912fb..6b955ba 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -899,6 +899,7 @@
TypeAnnotation bound = popNode();
Identifier name = popNode();
pushNode(new TypeVariable(name, bound));
+ rejectBuiltInIdentifier(name);
}
void endTypeVariables(int count, Token beginToken, Token endToken) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
index 2548c6a..90f2196 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
@@ -143,7 +143,7 @@
DartType sourceType = source.computeType(compiler);
if (!sourceType.treatAsDynamic &&
sourceType.kind == TypeKind.INTERFACE) {
- TypeMask sourceMask = new TypeMask.subtype(sourceType);
+ TypeMask sourceMask = new TypeMask.subtype(sourceType.element);
TypeMask speculatedMask = speculativeType.computeMask(compiler);
if (sourceMask.intersection(speculatedMask, compiler).isEmpty) {
return false;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 6123f69..70713da 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -57,10 +57,13 @@
FunctionSignature signature = function.computeSignature(compiler);
signature.forEachOptionalParameter((Element parameter) {
// This ensures the default value will be computed.
- builder.compileVariable(parameter);
+ Constant constant =
+ compiler.constantHandler.getConstantForVariable(parameter);
+ backend.registerCompileTimeConstant(constant, work.resolutionTree);
+ compiler.constantHandler.addCompileTimeConstantForEmission(
+ constant);
});
}
-
if (compiler.tracer.enabled) {
String name;
if (element.isMember()) {
@@ -953,21 +956,21 @@
_current = c;
}
- /**
- * Compiles compile-time constants. Never returns [:null:]. If the
- * initial value is not a compile-time constants, it reports an
- * internal error.
- */
- Constant compileConstant(VariableElement element) {
- return compiler.constantHandler.compileConstant(element);
+ Constant getConstantForNode(Node node) {
+ ConstantHandler handler = compiler.constantHandler;
+ Constant constant = elements.getConstant(node);
+ assert(invariant(node, constant != null,
+ message: 'No constant computed for $node'));
+ return constant;
}
- Constant compileVariable(VariableElement element) {
- return compiler.constantHandler.compileVariable(element);
+ HInstruction addConstant(Node node) {
+ return graph.addConstant(getConstantForNode(node), compiler);
}
bool isLazilyInitialized(VariableElement element) {
- Constant initialValue = compileVariable(element);
+ Constant initialValue =
+ compiler.constantHandler.getConstantForVariable(element);
return initialValue == null;
}
@@ -978,17 +981,14 @@
if (result == null) {
Element element = localsHandler.closureData.thisElement;
ClassElement cls = element.enclosingElement.getEnclosingClass();
- // Use the raw type because we don't have the type context for the
- // type parameters.
- DartType type = cls.rawType;
if (compiler.world.isUsedAsMixin(cls)) {
// If the enclosing class is used as a mixin, [:this:] can be
// of the class that mixins the enclosing class. These two
// classes do not have a subclass relationship, so, for
// simplicity, we mark the type as an interface type.
- result = new HType.nonNullSubtype(type, compiler);
+ result = new HType.nonNullSubtype(cls, compiler);
} else {
- result = new HType.nonNullSubclass(type, compiler);
+ result = new HType.nonNullSubclass(cls, compiler);
}
cachedTypeOfThis = result;
}
@@ -1322,7 +1322,8 @@
&& !element.isGenerativeConstructorBody()
&& (selector.mask == null || selector.mask.isNullable)) {
addWithPosition(
- new HFieldGet(element, providedArguments[0]), currentNode);
+ new HFieldGet(null, providedArguments[0], isAssignable: false),
+ currentNode);
}
InliningState state = enterInlinedMethod(
function, selector, providedArguments, currentNode);
@@ -1661,7 +1662,7 @@
includeSuperAndInjectedMembers: true);
InterfaceType type = classElement.computeType(compiler);
- HType ssaType = new HType.nonNullExact(type, compiler);
+ HType ssaType = new HType.nonNullExact(classElement, compiler);
List<DartType> instantiatedTypes;
addInlinedInstantiation(type);
if (!currentInlinedInstantiations.isEmpty) {
@@ -1807,11 +1808,11 @@
int kind) {
if (type == null) return original;
type = type.unalias(compiler);
- if (type.kind == TypeKind.INTERFACE && !type.isRaw) {
- HType subtype = new HType.subtype(type, compiler);
- HInstruction representations = buildTypeArgumentRepresentations(type);
- add(representations);
- return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
+ if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) {
+ HType subtype = new HType.subtype(type.element, compiler);
+ HInstruction representations = buildTypeArgumentRepresentations(type);
+ add(representations);
+ return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
original, representations);
} else if (type.kind == TypeKind.TYPE_VARIABLE) {
HType subtype = original.instructionType;
@@ -2495,9 +2496,7 @@
}
});
- HType type = new HType.nonNullExact(
- compiler.functionClass.computeType(compiler),
- compiler);
+ HType type = new HType.nonNullExact(compiler.functionClass, compiler);
push(new HForeignNew(closureClassElement, type, capturedVariables));
Element methodElement = nestedClosureData.closureElement;
@@ -2628,7 +2627,7 @@
if (element.isField() && !element.isAssignable()) {
// A static final or const. Get its constant value and inline it if
// the value can be compiled eagerly.
- value = compileVariable(element);
+ value = compiler.constantHandler.getConstantForVariable(element);
}
if (value != null) {
HInstruction instruction = graph.addConstant(value, compiler);
@@ -2955,7 +2954,10 @@
}
HInstruction handleConstantForOptionalParameter(Element parameter) {
- Constant constant = compileConstant(parameter);
+ Constant constant =
+ compiler.constantHandler.getConstantForVariable(parameter);
+ assert(invariant(parameter, constant != null,
+ message: 'No constant computed for $parameter'));
return graph.addConstant(constant, compiler);
}
@@ -3481,7 +3483,7 @@
Node currentNode,
HInstruction newObject) {
if (!backend.classNeedsRti(type.element)) return;
- if (!type.isRaw) {
+ if (!type.treatAsRaw) {
List<HInstruction> inputs = <HInstruction>[];
type.typeArguments.forEach((DartType argument) {
inputs.add(analyzeTypeArgument(argument));
@@ -3531,7 +3533,7 @@
return inferred.isUnknown() ? backend.extendableArrayType : inferred;
} else if (element.isGenerativeConstructor()) {
ClassElement cls = element.getEnclosingClass();
- return new HType.nonNullExact(cls.thisType, compiler);
+ return new HType.nonNullExact(cls.thisType.element, compiler);
} else {
return new HType.inferredReturnTypeForElement(
originalElement, compiler);
@@ -3673,9 +3675,13 @@
Element element = elements[node];
if (element.isClass() || element.isTypedef()) {
// TODO(karlklose): add type representation
- ConstantHandler handler = compiler.constantHandler;
- Constant constant = handler.compileNodeWithDefinitions(node, elements);
- stack.add(graph.addConstant(constant, compiler));
+ if (node.isCall) {
+ // The node itself is not a constant but we register the selector (the
+ // identifier that refers to the class/typedef) as a constant.
+ stack.add(addConstant(node.selector));
+ } else {
+ stack.add(addConstant(node));
+ }
} else if (element.isTypeVariable()) {
HInstruction value =
addTypeVariableReference(element.computeType(compiler));
@@ -3806,11 +3812,9 @@
generateRuntimeError(node.send, message.toString());
}
} else if (node.isConst()) {
- ConstantHandler handler = compiler.constantHandler;
- Constant constant = handler.compileNodeWithDefinitions(node, elements);
- stack.add(graph.addConstant(constant, compiler));
+ stack.add(addConstant(node));
if (isSymbolConstructor) {
- ConstructedConstant symbol = constant;
+ ConstructedConstant symbol = elements.getConstant(node);
StringConstant stringConstant = symbol.fields.single;
String nameString = stringConstant.toDartString().slowToString();
compiler.enqueuer.codegen.registerConstSymbol(nameString, elements);
@@ -3834,12 +3838,12 @@
bool isLength = selector.isGetter()
&& selector.name == const SourceString("length");
if (isLength || selector.isIndex()) {
- DartType classType = element.getEnclosingClass().computeType(compiler);
- HType type = new HType.nonNullExact(classType, compiler);
+ HType type = new HType.nonNullExact(
+ element.getEnclosingClass(), compiler);
return type.isIndexable(compiler);
} else if (selector.isIndexSet()) {
- DartType classType = element.getEnclosingClass().computeType(compiler);
- HType type = new HType.nonNullExact(classType, compiler);
+ HType type = new HType.nonNullExact(
+ element.getEnclosingClass(), compiler);
return type.isMutableIndexable(compiler);
} else {
return false;
@@ -4126,11 +4130,9 @@
}
void visitLiteralSymbol(LiteralSymbol node) {
- ConstantHandler handler = compiler.constantHandler;
- ConstructedConstant constant =
- handler.compileNodeWithDefinitions(node, elements);
- stack.add(graph.addConstant(constant, compiler));
- compiler.enqueuer.codegen.registerConstSymbol(node.slowNameString, elements);
+ stack.add(addConstant(node));
+ compiler.enqueuer.codegen.registerConstSymbol(
+ node.slowNameString, elements);
}
void visitStringJuxtaposition(StringJuxtaposition node) {
@@ -4204,7 +4206,7 @@
}
HInstruction value;
if (node.isRedirectingFactoryBody) {
- FunctionElement element = elements[node.expression];
+ FunctionElement element = elements[node.expression].implementation;
FunctionElement function = currentElement;
List<HInstruction> inputs = <HInstruction>[];
FunctionSignature calleeSignature = element.functionSignature;
@@ -4288,9 +4290,7 @@
HInstruction instruction;
if (node.isConst()) {
- ConstantHandler handler = compiler.constantHandler;
- Constant constant = handler.compileNodeWithDefinitions(node, elements);
- instruction = graph.addConstant(constant, compiler);
+ instruction = addConstant(node);
} else {
List<HInstruction> inputs = <HInstruction>[];
for (Link<Node> link = node.elements.nodes;
@@ -4487,9 +4487,7 @@
visitLiteralMap(LiteralMap node) {
if (node.isConst()) {
- ConstantHandler handler = compiler.constantHandler;
- Constant constant = handler.compileNodeWithDefinitions(node, elements);
- stack.add(graph.addConstant(constant, compiler));
+ stack.add(addConstant(node));
return;
}
List<HInstruction> inputs = <HInstruction>[];
@@ -4502,8 +4500,7 @@
}
HLiteralList keyValuePairs = buildLiteralList(inputs);
add(keyValuePairs);
- HType mapType = new HType.nonNullSubtype(
- backend.mapLiteralClass.computeType(compiler), compiler);
+ HType mapType = new HType.nonNullSubtype(backend.mapLiteralClass, compiler);
pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType);
}
@@ -4528,9 +4525,7 @@
for (Node labelOrCase in switchCase.labelsAndCases) {
if (labelOrCase is CaseMatch) {
CaseMatch match = labelOrCase;
- Constant constant =
- compiler.constantHandler.compileNodeWithDefinitions(
- match.expression, elements, isConst: true);
+ Constant constant = getConstantForNode(match.expression);
if (firstConstantType == null) {
firstConstantType = constant.computeType(compiler);
if (nonPrimitiveTypeOverridesEquals(constant)) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 2c22260..7b0b1a1 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -1570,8 +1570,9 @@
// [node.element] will be enqueued. We're not using the receiver
// type because our optimizations might end up in a state where the
// invoke dynamic knows more than the receiver.
+ ClassElement enclosing = node.element.getEnclosingClass();
HType receiverType = new HType.fromMask(
- new TypeMask.nonNullExact(node.element.getEnclosingClass().rawType),
+ new TypeMask.nonNullExact(enclosing.declaration),
compiler);
return receiverType.refine(selector, compiler);
}
@@ -1679,7 +1680,7 @@
// If the selector we need to register a typed getter to the
// [world]. The emitter needs to know if it needs to emit a
// bound closure for a method.
- TypeMask receiverType = new TypeMask.nonNullExact(superClass.rawType);
+ TypeMask receiverType = new TypeMask.nonNullExact(superClass);
selector = new TypedSelector(receiverType, selector);
world.registerDynamicGetter(selector);
methodName = backend.namer.invocationName(selector);
@@ -1696,7 +1697,12 @@
visitFieldGet(HFieldGet node) {
use(node.receiver);
Element element = node.element;
- if (element == backend.jsIndexableLength) {
+ if (node.isNullCheck) {
+ // We access a JavaScript member we know all objects besides
+ // null and undefined have: V8 does not like accessing a member
+ // that does not exist.
+ push(new js.PropertyAccess.field(pop(), 'toString'), node);
+ } else if (element == backend.jsIndexableLength) {
// We're accessing a native JavaScript property called 'length'
// on a JS String or a JS array. Therefore, the name of that
// property should not be mangled.
@@ -1709,7 +1715,10 @@
// constant value instead.
Element element = compiler.findRequiredElement(
compiler.typedDataLibrary, const SourceString('fetchLength'));
- Constant constant = compiler.constantHandler.compileConstant(element);
+ Constant constant =
+ compiler.constantHandler.getConstantForVariable(element);
+ assert(invariant(element, constant != null,
+ message: 'No constant computed for $element'));
var jsConstant = backend.emitter.constantReference(constant);
push(new js.Call(jsConstant, [pop()]), node);
} else {
@@ -1817,15 +1826,9 @@
visitConstant(HConstant node) {
assert(isGenerateAtUseSite(node));
generateConstant(node.constant);
- DartType type = node.constant.computeType(compiler);
- if (node.constant is ConstructedConstant ||
- node.constant is InterceptorConstant) {
- ConstantHandler handler = compiler.constantHandler;
- handler.registerCompileTimeConstant(node.constant, work.resolutionTree);
- }
- if (node.constant is! InterceptorConstant) {
- world.registerInstantiatedClass(type.element, work.resolutionTree);
- }
+
+ backend.registerCompileTimeConstant(node.constant, work.resolutionTree);
+ compiler.constantHandler.addCompileTimeConstantForEmission(node.constant);
}
visitNot(HNot node) {
@@ -2462,20 +2465,22 @@
TypeMask receiver = input.instructionType.computeMask(compiler);
TypeMask mask = node.instructionType.computeMask(compiler);
// Figure out if it is beneficial to turn this into a null check.
- // V8 generally prefers 'typeof' checks, but for integers and
+ // 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)
+ bool turnIntoNumCheck = input.isIntegerOrNull() && node.isInteger();
+ bool turnIntoNullCheck = !turnIntoNumCheck
+ && (mask.nullable() == receiver)
&& (node.isInteger() || node.isIndexablePrimitive(compiler));
js.Expression test;
if (turnIntoNullCheck) {
use(input);
test = new js.Binary("==", pop(), new js.LiteralNull());
- } else if (node.isInteger()) {
+ } else if (node.isInteger() && !turnIntoNumCheck) {
// input is !int
checkInt(input, '!==');
test = pop();
- } else if (node.isNumber()) {
+ } else if (node.isNumber() || turnIntoNumCheck) {
// input is !num
checkNum(input, '!==');
test = pop();
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index 98e5a73..d80e5a8 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -85,8 +85,8 @@
return interceptedClasses
.where((cls) => cls != compiler.objectClass)
.map((cls) => backend.classesMixedIntoNativeClasses.contains(cls)
- ? new TypeMask.subtype(cls.rawType)
- : new TypeMask.subclass(cls.rawType))
+ ? new TypeMask.subtype(cls)
+ : new TypeMask.subclass(cls))
.every((mask) => receiverMask.intersection(mask, compiler).isEmpty);
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 8c723df..c3dc5a6 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -175,7 +175,8 @@
// TODO(sra): What is the type of the prototype of an interceptor?
if (constant.isInterceptor()) return HType.UNKNOWN;
ObjectConstant objectConstant = constant;
- return new HBoundedType(new TypeMask.nonNullExact(objectConstant.type));
+ TypeMask mask = new TypeMask.nonNullExact(objectConstant.type.element);
+ return new HBoundedType(mask);
}
HConstant addConstant(Constant constant, Compiler compiler) {
@@ -1124,18 +1125,20 @@
// instructions with generics. It has the generic type context
// available.
assert(type.kind != TypeKind.TYPE_VARIABLE);
- assert(type.isRaw || type.kind == TypeKind.FUNCTION);
+ assert(type.treatAsRaw || type.kind == TypeKind.FUNCTION);
if (type.treatAsDynamic) return this;
- if (identical(type.element, compiler.objectClass)) return this;
+ // The type element is either a class or the void element.
+ Element element = type.element;
+ if (identical(element, compiler.objectClass)) return this;
if (type.kind != TypeKind.INTERFACE) {
return new HTypeConversion(type, kind, HType.UNKNOWN, this);
} else if (kind == HTypeConversion.BOOLEAN_CONVERSION_CHECK) {
// Boolean conversion checks work on non-nullable booleans.
return new HTypeConversion(type, kind, HType.BOOLEAN, this);
- } else if (kind == HTypeConversion.CHECKED_MODE_CHECK && !type.isRaw) {
- throw 'creating compound check to $type (this = ${this})';
+ } else if (kind == HTypeConversion.CHECKED_MODE_CHECK && !type.treatAsRaw) {
+ throw 'creating compound check to $type (this = ${this})';
} else {
- HType subtype = new HType.subtype(type, compiler);
+ HType subtype = new HType.subtype(element, compiler);
return new HTypeConversion(type, kind, subtype, this);
}
}
@@ -1497,6 +1500,7 @@
HInstruction getDartReceiver(Compiler compiler) => receiver;
bool onlyThrowsNSM() => true;
+ bool get isNullCheck => element == null;
accept(HVisitor visitor) => visitor.visitFieldGet(this);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 333bd7e..1cd4b7d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -201,11 +201,10 @@
HType type = input.instructionType;
if (type.isBoolean()) return input;
// All values that cannot be 'true' are boolified to false.
- DartType booleanType = backend.jsBoolClass.computeType(compiler);
TypeMask mask = type.computeMask(compiler);
// TODO(kasperl): Get rid of the null check here once all HTypes
// have a proper mask.
- if (mask != null && !mask.contains(booleanType, compiler)) {
+ if (mask != null && !mask.contains(backend.jsBoolClass, compiler)) {
return graph.addConstantBool(false, compiler);
}
return node;
@@ -637,7 +636,8 @@
} else if (!RuntimeTypes.hasTypeArguments(type)) {
TypeMask expressionMask = expressionType.computeMask(compiler);
TypeMask typeMask = (element == compiler.nullClass)
- ? new TypeMask.subtype(type) : new TypeMask.nonNullSubtype(type);
+ ? new TypeMask.subtype(element)
+ : new TypeMask.nonNullSubtype(element);
if (expressionMask.union(typeMask, compiler) == typeMask) {
return graph.addConstantBool(true, compiler);
} else if (expressionMask.intersection(typeMask, compiler).isEmpty) {
@@ -651,7 +651,7 @@
HInstruction value = node.inputs[0];
DartType type = node.typeExpression;
if (type != null) {
- if (!type.isRaw || type.kind == TypeKind.TYPE_VARIABLE) {
+ if (!type.treatAsRaw || type.kind == TypeKind.TYPE_VARIABLE) {
return node;
}
if (type.kind == TypeKind.FUNCTION) {
@@ -694,7 +694,17 @@
} else {
var type = receiver.instructionType.computeMask(compiler);
if (type.isContainer && type.length != null) {
- return graph.addConstantInt(type.length, compiler);
+ HInstruction constant = graph.addConstantInt(type.length, compiler);
+ if (type.isNullable) {
+ // If the container can be null, we update all uses of the
+ // length access to use the constant instead, but keep the
+ // length access in the graph, to ensure we still have a
+ // null check.
+ node.block.rewrite(node, constant);
+ return node;
+ } else {
+ return constant;
+ }
}
}
}
@@ -769,7 +779,7 @@
HInstruction value = node.inputs.last;
if (compiler.enableTypeAssertions) {
DartType type = field.computeType(compiler);
- if (!type.isRaw || type.kind == TypeKind.TYPE_VARIABLE) {
+ if (!type.treatAsRaw || type.kind == TypeKind.TYPE_VARIABLE) {
// We cannot generate the correct type representation here, so don't
// inline this access.
return node;
@@ -948,7 +958,14 @@
if (current.canThrow() || current.sideEffects.hasSideEffects()) {
return false;
}
- current = current.next;
+ if (current.next == null && current is HGoto) {
+ // We do not merge blocks in our SSA graph, so if this block
+ // just jumps to a single predecessor, visit this predecessor.
+ assert(current.block.successors.length == 1);
+ current = current.block.successors[0].first;
+ } else {
+ current = current.next;
+ }
} while (current != null);
return false;
}
@@ -1503,7 +1520,6 @@
visitDominatorTree(graph);
}
-
// Update users of [input] that are dominated by [:dominator.first:]
// to use [newInput] instead.
void changeUsesDominatedBy(HBasicBlock dominator,
@@ -1543,7 +1559,7 @@
if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
- HType convertedType = new HType.nonNullSubtype(type, compiler);
+ HType convertedType = new HType.nonNullSubtype(element, compiler);
HInstruction input = instruction.expression;
for (HIf ifUser in ifUsers) {
changeUsesDominatedBy(ifUser.thenBlock, input, convertedType);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
index 60014f2..95b020f 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
@@ -27,6 +27,8 @@
show ElementX,
ConstructorBodyElementX;
+import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
+
part 'bailout.dart';
part 'builder.dart';
part 'codegen.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index 659737c..bfdb564 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -30,8 +30,7 @@
// TODO(ngeoffray): Avoid creating [TypeMask]s with the string
// class as base.
return isNullable
- ? new HBoundedType(
- new TypeMask.exact(backend.jsStringClass.rawType))
+ ? new HBoundedType(new TypeMask.exact(backend.jsStringClass))
: backend.stringType;
} else if (mask.containsOnlyBool(compiler)) {
return isNullable ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN;
@@ -48,33 +47,33 @@
return new HBoundedType(mask);
}
- factory HType.exact(DartType type, Compiler compiler) {
- TypeMask mask = new TypeMask.exact(type);
+ factory HType.exact(ClassElement type, Compiler compiler) {
+ TypeMask mask = new TypeMask.exact(type.declaration);
return new HType.fromMask(mask, compiler);
}
- factory HType.subclass(DartType type, Compiler compiler) {
- TypeMask mask = new TypeMask.subclass(type);
+ factory HType.subclass(ClassElement type, Compiler compiler) {
+ TypeMask mask = new TypeMask.subclass(type.declaration);
return new HType.fromMask(mask, compiler);
}
- factory HType.subtype(DartType type, Compiler compiler) {
- TypeMask mask = new TypeMask.subtype(type);
+ factory HType.subtype(ClassElement type, Compiler compiler) {
+ TypeMask mask = new TypeMask.subtype(type.declaration);
return new HType.fromMask(mask, compiler);
}
- factory HType.nonNullExact(DartType type, Compiler compiler) {
- TypeMask mask = new TypeMask.nonNullExact(type);
+ factory HType.nonNullExact(ClassElement type, Compiler compiler) {
+ TypeMask mask = new TypeMask.nonNullExact(type.declaration);
return new HType.fromMask(mask, compiler);
}
- factory HType.nonNullSubclass(DartType type, Compiler compiler) {
- TypeMask mask = new TypeMask.nonNullSubclass(type);
+ factory HType.nonNullSubclass(ClassElement type, Compiler compiler) {
+ TypeMask mask = new TypeMask.nonNullSubclass(type.declaration);
return new HType.fromMask(mask, compiler);
}
- factory HType.nonNullSubtype(DartType type, Compiler compiler) {
- TypeMask mask = new TypeMask.nonNullSubtype(type);
+ factory HType.nonNullSubtype(ClassElement type, Compiler compiler) {
+ TypeMask mask = new TypeMask.nonNullSubtype(type.declaration);
return new HType.fromMask(mask, compiler);
}
@@ -123,8 +122,7 @@
// like [native.SpecialType.JsObject].
static HType fromNativeType(type, Compiler compiler) {
if (type == native.SpecialType.JsObject) {
- return new HType.nonNullExact(
- compiler.objectClass.computeType(compiler), compiler);
+ return new HType.nonNullExact(compiler.objectClass, compiler);
} else if (type.isVoid) {
return HType.NULL;
} else if (type.element == compiler.nullClass) {
@@ -132,11 +130,11 @@
} else if (type.treatAsDynamic) {
return HType.UNKNOWN;
} else if (compiler.world.hasAnySubtype(type.element)) {
- return new HType.nonNullSubtype(type, compiler);
+ return new HType.nonNullSubtype(type.element, compiler);
} else if (compiler.world.hasAnySubclass(type.element)) {
- return new HType.nonNullSubclass(type, compiler);
+ return new HType.nonNullSubclass(type.element, compiler);
} else {
- return new HType.nonNullExact(type, compiler);
+ return new HType.nonNullExact(type.element, compiler);
}
}
@@ -190,8 +188,7 @@
}
bool implementsInterface(ClassElement interfaceElement, Compiler compiler) {
- DartType interfaceType = interfaceElement.computeType(compiler);
- TypeMask mask = new TypeMask.subtype(interfaceType);
+ TypeMask mask = new TypeMask.subtype(interfaceElement);
return mask == mask.union(computeMask(compiler), compiler);
}
@@ -280,8 +277,7 @@
bool canBePrimitiveBoolean(Compiler compiler) => true;
TypeMask computeMask(Compiler compiler) {
- DartType base = compiler.objectClass.computeType(compiler);
- return new TypeMask.subclass(base);
+ return new TypeMask.subclass(compiler.objectClass);
}
}
@@ -295,8 +291,7 @@
bool canBePrimitiveBoolean(Compiler compiler) => true;
TypeMask computeMask(Compiler compiler) {
- DartType base = compiler.objectClass.computeType(compiler);
- return new TypeMask.nonNullSubclass(base);
+ return new TypeMask.nonNullSubclass(compiler.objectClass);
}
}
@@ -344,8 +339,7 @@
TypeMask computeMask(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType base = backend.jsBoolClass.computeType(compiler);
- return new TypeMask.exact(base);
+ return new TypeMask.exact(backend.jsBoolClass);
}
}
@@ -359,8 +353,7 @@
TypeMask computeMask(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType base = backend.jsBoolClass.computeType(compiler);
- return new TypeMask.nonNullExact(base);
+ return new TypeMask.nonNullExact(backend.jsBoolClass);
}
}
@@ -372,8 +365,7 @@
TypeMask computeMask(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType base = backend.jsNumberClass.computeType(compiler);
- return new TypeMask.subclass(base);
+ return new TypeMask.subclass(backend.jsNumberClass);
}
}
@@ -386,8 +378,7 @@
TypeMask computeMask(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType base = backend.jsNumberClass.computeType(compiler);
- return new TypeMask.nonNullSubclass(base);
+ return new TypeMask.nonNullSubclass(backend.jsNumberClass);
}
}
@@ -398,8 +389,7 @@
TypeMask computeMask(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType base = backend.jsIntClass.computeType(compiler);
- return new TypeMask.exact(base);
+ return new TypeMask.exact(backend.jsIntClass);
}
}
@@ -412,8 +402,7 @@
TypeMask computeMask(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType base = backend.jsIntClass.computeType(compiler);
- return new TypeMask.nonNullExact(base);
+ return new TypeMask.nonNullExact(backend.jsIntClass);
}
}
@@ -424,8 +413,7 @@
TypeMask computeMask(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType base = backend.jsDoubleClass.computeType(compiler);
- return new TypeMask.exact(base);
+ return new TypeMask.exact(backend.jsDoubleClass);
}
}
@@ -438,8 +426,7 @@
TypeMask computeMask(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType base = backend.jsDoubleClass.computeType(compiler);
- return new TypeMask.nonNullExact(base);
+ return new TypeMask.nonNullExact(backend.jsDoubleClass);
}
}
@@ -460,28 +447,21 @@
bool canBePrimitiveNumber(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType jsNumberType = backend.jsNumberClass.computeType(compiler);
- DartType jsIntType = backend.jsIntClass.computeType(compiler);
- DartType jsDoubleType = backend.jsDoubleClass.computeType(compiler);
- return mask.contains(jsNumberType, compiler)
- || mask.contains(jsIntType, compiler)
- || mask.contains(jsDoubleType, compiler);
+ return mask.contains(backend.jsNumberClass, compiler)
+ || mask.contains(backend.jsIntClass, compiler)
+ || mask.contains(backend.jsDoubleClass, compiler);
}
bool canBePrimitiveBoolean(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType jsBoolType = backend.jsBoolClass.computeType(compiler);
- return mask.contains(jsBoolType, compiler);
+ return mask.contains(backend.jsBoolClass, compiler);
}
bool canBePrimitiveArray(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType jsArrayType = backend.jsArrayClass.rawType;
- DartType jsFixedArrayType = backend.jsFixedArrayClass.rawType;
- DartType jsExtendableArrayType = backend.jsExtendableArrayClass.rawType;
- return mask.contains(jsArrayType, compiler)
- || mask.contains(jsFixedArrayType, compiler)
- || mask.contains(jsExtendableArrayType, compiler);
+ return mask.contains(backend.jsArrayClass, compiler)
+ || mask.contains(backend.jsFixedArrayClass, compiler)
+ || mask.contains(backend.jsExtendableArrayClass, compiler);
}
bool isIndexablePrimitive(Compiler compiler) {
@@ -511,8 +491,7 @@
bool canBePrimitiveString(Compiler compiler) {
JavaScriptBackend backend = compiler.backend;
- DartType jsStringType = backend.jsStringClass.computeType(compiler);
- return mask.contains(jsStringType, compiler);
+ return mask.contains(backend.jsStringClass, compiler);
}
TypeMask computeMask(Compiler compiler) => mask;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 8271832..a1cf853 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -10,7 +10,7 @@
final Map<int, HInstruction> workmap = new Map<int, HInstruction>();
final List<int> worklist = new List<int>();
final Map<HInstruction, Function> pendingOptimizations =
- new Map<HInstruction, Function>();
+ new Map<HInstruction, Function>();
final Compiler compiler;
String get name => 'type propagator';
@@ -176,7 +176,7 @@
HTypeConversion converted = new HTypeConversion(
null, kind, type, input, selector);
instruction.block.addBefore(instruction, converted);
- input.replaceAllUsersDominatedBy(instruction, converted);
+ input.replaceAllUsersDominatedBy(instruction, converted);
}
bool isCheckEnoughForNsmOrAe(HInstruction instruction,
@@ -211,7 +211,7 @@
if (targets.length == 1) {
Element target = targets.first;
ClassElement cls = target.getEnclosingClass();
- HType type = new HType.nonNullSubclass(cls.rawType, compiler);
+ HType type = new HType.nonNullSubclass(cls, compiler);
// TODO(ngeoffray): We currently only optimize on primitive
// types.
if (!type.isPrimitive(compiler)) return false;
@@ -439,7 +439,7 @@
}
return desiredType;
}
-
+
bool hasBeenSpeculativelyOptimized(HInstruction instruction) {
return savedTypes.containsKey(instruction);
}
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 1af2669..2b2a399 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -155,9 +155,7 @@
final ClassElement currentClass;
- /// The type of [:this:]. Can only be accessed if [currentClass] is not null.
InterfaceType thisType;
- /// The type of [:super:]. Can only be accessed if [currentClass] is not null.
InterfaceType superType;
Link<DartType> cascadeTypes = const Link<DartType>();
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 622e1a2..fb77255 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -414,7 +414,7 @@
Types types = inferrer.compiler.types;
bool paramMatches(ConcreteType concrete, VariableElement parameter) {
DartType parameterType = parameter.variables.type;
- if (parameterType.treatAsDynamic || parameterType.isRaw) {
+ if (parameterType.treatAsDynamic || parameterType.treatAsRaw) {
return true;
}
for (BaseType baseType in concrete.baseTypes) {
@@ -533,7 +533,7 @@
throw new UnsupportedError("");
}
- bool contains(DartType type, Compiler compiler) {
+ bool contains(ClassElement type, Compiler compiler) {
throw new UnsupportedError("");
}
@@ -816,7 +816,7 @@
Element enclosing = field.enclosingElement;
if (enclosing.isClass()) {
ClassElement cls = enclosing;
- TypeMask receiverMask = new TypeMask.exact(cls.rawType);
+ TypeMask receiverMask = new TypeMask.exact(cls);
TypeMask resultMask = concreteTypeToTypeMask(result);
augmentInferredSelectorType(selector, receiverMask, resultMask);
}
@@ -974,11 +974,11 @@
assert(element != null);
if (element == compiler.backend.numImplementation) {
return new TypeMask.nonNullSubclass(
- compiler.backend.numImplementation.rawType);
+ compiler.backend.numImplementation);
} else if (element == compiler.dynamicClass) {
- return new TypeMask.nonNullSubclass(compiler.objectClass.rawType);
+ return new TypeMask.nonNullSubclass(compiler.objectClass);
} else {
- return new TypeMask.nonNullExact(element.rawType);
+ return new TypeMask.nonNullExact(element);
}
}
}
@@ -1104,8 +1104,8 @@
// abstract classes than num.
TypeMask receiverMask =
(receiverType == compiler.backend.numImplementation)
- ? new TypeMask.nonNullSubclass(receiverType.rawType)
- : new TypeMask.nonNullExact(receiverType.rawType);
+ ? new TypeMask.nonNullSubclass(receiverType)
+ : new TypeMask.nonNullExact(receiverType);
TypeMask resultMask = concreteTypeToTypeMask(result);
augmentInferredSelectorType(selector, receiverMask, resultMask);
}
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 03cd53a..cc17100 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -15,46 +15,31 @@
static const int SUBCLASS = 2;
static const int SUBTYPE = 3;
- final DartType base;
+ final ClassElement base;
final int flags;
- FlatTypeMask(DartType base, int kind, bool isNullable)
+ FlatTypeMask(ClassElement base, int kind, bool isNullable)
: this.internal(base, (kind << 1) | (isNullable ? 1 : 0));
- FlatTypeMask.exact(DartType base)
+ FlatTypeMask.exact(ClassElement base)
: this.internal(base, (EXACT << 1) | 1);
- FlatTypeMask.subclass(DartType base)
+ FlatTypeMask.subclass(ClassElement base)
: this.internal(base, (SUBCLASS << 1) | 1);
- FlatTypeMask.subtype(DartType base)
+ FlatTypeMask.subtype(ClassElement base)
: this.internal(base, (SUBTYPE << 1) | 1);
const FlatTypeMask.nonNullEmpty(): base = null, flags = 0;
const FlatTypeMask.empty() : base = null, flags = 1;
- FlatTypeMask.nonNullExact(DartType base)
+ FlatTypeMask.nonNullExact(ClassElement base)
: this.internal(base, EXACT << 1);
- FlatTypeMask.nonNullSubclass(DartType base)
+ FlatTypeMask.nonNullSubclass(ClassElement base)
: this.internal(base, SUBCLASS << 1);
- FlatTypeMask.nonNullSubtype(DartType base)
+ FlatTypeMask.nonNullSubtype(ClassElement base)
: this.internal(base, SUBTYPE << 1);
- FlatTypeMask.internal(DartType base, this.flags)
- : this.base = transformBase(base) {
- assert(base == null || !(isExact && base.treatAsDynamic));
- }
-
- // TODO(kasperl): We temporarily transform the base to be the raw
- // variant of the type. Long term, we're going to keep the class
- // element corresponding to the type in the mask instead.
- static DartType transformBase(DartType base) {
- if (base == null) {
- return null;
- } else if (base.kind != TypeKind.INTERFACE) {
- assert(base.kind == TypeKind.INTERFACE);
- return null;
- } else {
- return base.asRaw();
- }
+ FlatTypeMask.internal(this.base, this.flags) {
+ assert(base == null || base.isDeclaration);
}
bool get isEmpty => (flags >> 1) == EMPTY;
@@ -81,10 +66,11 @@
TypeMask simplify(Compiler compiler) => this;
- bool contains(DartType type, Compiler compiler) {
+ bool contains(ClassElement type, Compiler compiler) {
+ assert(type.isDeclaration);
if (isEmpty) {
return false;
- } else if (identical(base.element, type.element)) {
+ } else if (identical(base, type)) {
return true;
} else if (isExact) {
return false;
@@ -97,43 +83,44 @@
}
bool containsOnlyInt(Compiler compiler) {
- return base.element == compiler.intClass
- || base.element == compiler.backend.intImplementation;
+ return base == compiler.intClass
+ || base == compiler.backend.intImplementation;
}
bool containsOnlyDouble(Compiler compiler) {
- return base.element == compiler.doubleClass
- || base.element == compiler.backend.doubleImplementation;
+ return base == compiler.doubleClass
+ || base == compiler.backend.doubleImplementation;
}
bool containsOnlyNum(Compiler compiler) {
- return base.element == compiler.numClass
- || base.element == compiler.backend.numImplementation;
+ return base == compiler.numClass
+ || base == compiler.backend.numImplementation;
}
bool containsOnlyNull(Compiler compiler) {
- return base.element == compiler.nullClass
- || base.element == compiler.backend.nullImplementation;
+ return base == compiler.nullClass
+ || base == compiler.backend.nullImplementation;
}
bool containsOnlyBool(Compiler compiler) {
- return base.element == compiler.boolClass
- || base.element == compiler.backend.boolImplementation;
+ return base == compiler.boolClass
+ || base == compiler.backend.boolImplementation;
}
bool containsOnlyString(Compiler compiler) {
- return base.element == compiler.stringClass
- || base.element == compiler.backend.stringImplementation;
+ return base == compiler.stringClass
+ || base == compiler.backend.stringImplementation;
}
bool containsOnly(ClassElement cls) {
- return base.element == cls;
+ assert(cls.isDeclaration);
+ return base == cls;
}
bool satisfies(ClassElement cls, Compiler compiler) {
+ assert(cls.isDeclaration);
if (isEmpty) return false;
- return base.element == cls
- || isSubtypeOf(base, cls.computeType(compiler).asRaw(), compiler);
+ return base == cls || isSubtypeOf(base, cls, compiler);
}
/**
@@ -143,11 +130,10 @@
ClassElement singleClass(Compiler compiler) {
if (isEmpty) return null;
if (isNullable) return null; // It is Null and some other class.
- ClassElement element = base.element;
if (isExact) {
- return element;
+ return base;
} else if (isSubclass) {
- return compiler.world.hasAnySubclass(element) ? null : element;
+ return compiler.world.hasAnySubclass(base) ? null : base;
} else {
assert(isSubtype);
return null;
@@ -159,8 +145,8 @@
*/
bool containsAll(Compiler compiler) {
if (isEmpty || isExact) return false;
- return identical(base.element, compiler.objectClass)
- || identical(base.element, compiler.dynamicClass);
+ return identical(base, compiler.objectClass)
+ || identical(base, compiler.dynamicClass);
}
TypeMask union(TypeMask other, Compiler compiler) {
@@ -348,7 +334,7 @@
int combined = (kind << 1) | (flags & other.flags & 1);
TypeMask result;
for (ClassElement each in candidates) {
- TypeMask mask = new FlatTypeMask.internal(each.rawType, combined);
+ TypeMask mask = new FlatTypeMask.internal(each, combined);
result = (result == null) ? mask : result.union(mask, compiler);
}
return result;
@@ -359,7 +345,7 @@
}
Iterable<ClassElement> containedClasses(Compiler compiler) {
- Iterable<ClassElement> self = [ base.element ];
+ Iterable<ClassElement> self = [ base ];
if (isExact) {
return self;
} else {
@@ -408,7 +394,7 @@
// TODO(kasperl): Can't we just avoid creating typed selectors
// based of function types?
- Element self = base.element;
+ Element self = base;
if (self.isTypedef()) {
// A typedef is a function type that doesn't have any
// user-defined members.
@@ -468,7 +454,7 @@
if (!isNullable) return false;
cls = compiler.backend.nullImplementation;
} else {
- cls = base.element;
+ cls = base;
}
// Use [lookupMember] because finding abstract members is okay.
@@ -481,7 +467,7 @@
// `null`.
if (isEmpty) return false;
// A call on an exact mask for an abstract class is dead code.
- if (isExact && base.element.isAbstract(compiler)) return false;
+ if (isExact && base.isAbstract(compiler)) return false;
// If the receiver is guaranteed to have a member that
// matches what we're looking for, there's no need to
// introduce a noSuchMethod handler. It will never be called.
@@ -524,17 +510,16 @@
// handler because we may have to call B.noSuchMethod since B
// does not implement bar.
- Element cls = base.element;
- bool hasMatch = hasConcreteMatch(cls, selector, compiler);
+ bool hasMatch = hasConcreteMatch(base, selector, compiler);
if (isExact) return !hasMatch;
- if (!cls.isAbstract(compiler) && !hasMatch) return true;
+ if (!base.isAbstract(compiler) && !hasMatch) return true;
Set<ClassElement> subtypesToCheck;
if (isSubtype) {
- subtypesToCheck = compiler.world.subtypesOf(cls);
+ subtypesToCheck = compiler.world.subtypesOf(base);
} else {
assert(isSubclass);
- subtypesToCheck = compiler.world.subclassesOf(cls);
+ subtypesToCheck = compiler.world.subclassesOf(base);
}
return subtypesToCheck != null
@@ -558,8 +543,7 @@
// implemented on the exact receiver type. It could be found in a
// subclass or in an inheritance-wise unrelated class in case of
// subtype selectors.
- ClassElement cls = base.element;
- return (cls.isSubclassOf(enclosing)) ? result : null;
+ return (base.isSubclassOf(enclosing)) ? result : null;
}
bool operator ==(var other) {
@@ -579,22 +563,20 @@
if (isExact) buffer.write('exact=');
if (isSubclass) buffer.write('subclass=');
if (isSubtype) buffer.write('subtype=');
- buffer.write(base.element.name.slowToString());
+ buffer.write(base.name.slowToString());
return "[$buffer]";
}
- static bool isSubclassOf(DartType x, DartType y, Compiler compiler) {
- ClassElement xElement = x.element;
- ClassElement yElement = y.element;
- Set<ClassElement> subclasses = compiler.world.subclassesOf(yElement);
- return (subclasses != null) ? subclasses.contains(xElement) : false;
+ static bool isSubclassOf(ClassElement x, ClassElement y, Compiler compiler) {
+ assert(x.isDeclaration && y.isDeclaration);
+ Set<ClassElement> subclasses = compiler.world.subclassesOf(y);
+ return (subclasses != null) ? subclasses.contains(x) : false;
}
- static bool isSubtypeOf(DartType x, DartType y, Compiler compiler) {
- ClassElement xElement = x.element;
- ClassElement yElement = y.element;
- Set<ClassElement> subtypes = compiler.world.subtypesOf(yElement);
- return (subtypes != null) ? subtypes.contains(xElement) : false;
+ static bool isSubtypeOf(ClassElement x, ClassElement y, Compiler compiler) {
+ assert(x.isDeclaration && y.isDeclaration);
+ Set<ClassElement> subtypes = compiler.world.subtypesOf(y);
+ return (subtypes != null) ? subtypes.contains(x) : false;
}
static Set<ClassElement> commonContainedClasses(FlatTypeMask x,
@@ -617,7 +599,7 @@
}
static Set<ClassElement> containedSubset(FlatTypeMask x, Compiler compiler) {
- ClassElement element = x.base.element;
+ ClassElement element = x.base;
if (x.isExact) {
return null;
} else if (x.isSubclass) {
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 c077d5f..8f4c05f 100644
--- a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
@@ -54,7 +54,7 @@
return forwardTo.satisfies(cls, compiler);
}
- bool contains(DartType type, Compiler compiler) {
+ bool contains(ClassElement type, Compiler compiler) {
return forwardTo.contains(type, compiler);
}
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index a809af3..27e2df5 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -10,21 +10,24 @@
* yield conservative answers that contain too many classes.
*/
abstract class TypeMask {
- factory TypeMask(DartType base, int kind, bool isNullable)
+ factory TypeMask(ClassElement base, int kind, bool isNullable)
=> new FlatTypeMask(base, kind, isNullable);
const factory TypeMask.empty() = FlatTypeMask.empty;
- factory TypeMask.exact(DartType base) => new FlatTypeMask.exact(base);
- factory TypeMask.subclass(DartType base) => new FlatTypeMask.subclass(base);
- factory TypeMask.subtype(DartType base) => new FlatTypeMask.subtype(base);
+ factory TypeMask.exact(ClassElement base)
+ => new FlatTypeMask.exact(base);
+ factory TypeMask.subclass(ClassElement base)
+ => new FlatTypeMask.subclass(base);
+ factory TypeMask.subtype(ClassElement base)
+ => new FlatTypeMask.subtype(base);
const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
- factory TypeMask.nonNullExact(DartType base)
+ factory TypeMask.nonNullExact(ClassElement base)
=> new FlatTypeMask.nonNullExact(base);
- factory TypeMask.nonNullSubclass(DartType base)
+ factory TypeMask.nonNullSubclass(ClassElement base)
=> new FlatTypeMask.nonNullSubclass(base);
- factory TypeMask.nonNullSubtype(DartType base)
+ factory TypeMask.nonNullSubtype(ClassElement base)
=> new FlatTypeMask.nonNullSubtype(base);
factory TypeMask.unionOf(Iterable<TypeMask> masks, Compiler compiler) {
@@ -58,7 +61,7 @@
bool containsOnlyBool(Compiler compiler);
bool containsOnlyString(Compiler compiler);
bool containsOnly(ClassElement element);
-
+
/**
* Returns whether this type mask is an instance of [cls].
*/
@@ -67,7 +70,7 @@
/**
* Returns whether or not this type mask contains the given type.
*/
- bool contains(DartType type, Compiler compiler);
+ bool contains(ClassElement type, Compiler compiler);
/**
* Returns whether or not this type mask contains all types.
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index d4a83b98..1a47e3b 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -68,7 +68,7 @@
TypeMask get dynamicType {
if (dynamicTypeCache == null) {
- dynamicTypeCache = new TypeMask.subclass(compiler.objectClass.rawType);
+ dynamicTypeCache = new TypeMask.subclass(compiler.objectClass);
}
return dynamicTypeCache;
}
@@ -76,7 +76,7 @@
TypeMask get intType {
if (intTypeCache == null) {
intTypeCache = new TypeMask.nonNullExact(
- compiler.backend.intImplementation.rawType);
+ compiler.backend.intImplementation);
}
return intTypeCache;
}
@@ -84,7 +84,7 @@
TypeMask get doubleType {
if (doubleTypeCache == null) {
doubleTypeCache = new TypeMask.nonNullExact(
- compiler.backend.doubleImplementation.rawType);
+ compiler.backend.doubleImplementation);
}
return doubleTypeCache;
}
@@ -92,7 +92,7 @@
TypeMask get numType {
if (numTypeCache == null) {
numTypeCache = new TypeMask.nonNullSubclass(
- compiler.backend.numImplementation.rawType);
+ compiler.backend.numImplementation);
}
return numTypeCache;
}
@@ -100,7 +100,7 @@
TypeMask get boolType {
if (boolTypeCache == null) {
boolTypeCache = new TypeMask.nonNullExact(
- compiler.backend.boolImplementation.rawType);
+ compiler.backend.boolImplementation);
}
return boolTypeCache;
}
@@ -108,7 +108,7 @@
TypeMask get functionType {
if (functionTypeCache == null) {
functionTypeCache = new TypeMask.nonNullSubtype(
- compiler.backend.functionImplementation.rawType);
+ compiler.backend.functionImplementation);
}
return functionTypeCache;
}
@@ -116,7 +116,7 @@
TypeMask get listType {
if (listTypeCache == null) {
listTypeCache = new TypeMask.nonNullExact(
- compiler.backend.listImplementation.rawType);
+ compiler.backend.listImplementation);
}
return listTypeCache;
}
@@ -124,7 +124,7 @@
TypeMask get constListType {
if (constListTypeCache == null) {
constListTypeCache = new TypeMask.nonNullExact(
- compiler.backend.constListImplementation.rawType);
+ compiler.backend.constListImplementation);
}
return constListTypeCache;
}
@@ -132,7 +132,7 @@
TypeMask get fixedListType {
if (fixedListTypeCache == null) {
fixedListTypeCache = new TypeMask.nonNullExact(
- compiler.backend.fixedListImplementation.rawType);
+ compiler.backend.fixedListImplementation);
}
return fixedListTypeCache;
}
@@ -140,7 +140,7 @@
TypeMask get growableListType {
if (growableListTypeCache == null) {
growableListTypeCache = new TypeMask.nonNullExact(
- compiler.backend.growableListImplementation.rawType);
+ compiler.backend.growableListImplementation);
}
return growableListTypeCache;
}
@@ -148,7 +148,7 @@
TypeMask get mapType {
if (mapTypeCache == null) {
mapTypeCache = new TypeMask.nonNullSubtype(
- compiler.backend.mapImplementation.rawType);
+ compiler.backend.mapImplementation);
}
return mapTypeCache;
}
@@ -156,7 +156,7 @@
TypeMask get constMapType {
if (constMapTypeCache == null) {
constMapTypeCache = new TypeMask.nonNullSubtype(
- compiler.backend.constMapImplementation.rawType);
+ compiler.backend.constMapImplementation);
}
return constMapTypeCache;
}
@@ -164,7 +164,7 @@
TypeMask get stringType {
if (stringTypeCache == null) {
stringTypeCache = new TypeMask.nonNullExact(
- compiler.backend.stringImplementation.rawType);
+ compiler.backend.stringImplementation);
}
return stringTypeCache;
}
@@ -172,7 +172,7 @@
TypeMask get typeType {
if (typeTypeCache == null) {
typeTypeCache = new TypeMask.nonNullExact(
- compiler.backend.typeImplementation.rawType);
+ compiler.backend.typeImplementation);
}
return typeTypeCache;
}
@@ -209,18 +209,17 @@
return cls;
}
- /// Checks that two [DartType]s are the same modulo normalization.
- bool same(DartType type1, DartType type2) {
- return (type1 == type2)
- || normalize(type1.element) == normalize(type2.element);
+ /// Checks that two types are the same modulo normalization.
+ bool same(ClassElement type1, ClassElement type2) {
+ return (type1 == type2) || normalize(type1) == normalize(type2);
}
/**
* Checks that one of [type1] and [type2] is a subtype of the other.
*/
- bool related(DartType type1, DartType type2) {
- return compiler.types.isSubtype(type1, type2)
- || compiler.types.isSubtype(type2, type1);
+ bool related(ClassElement type1, ClassElement type2) {
+ return compiler.types.isSubtype(type1.rawType, type2.rawType)
+ || compiler.types.isSubtype(type2.rawType, type1.rawType);
}
/**
@@ -228,18 +227,20 @@
* exactness, subclassing, subtyping and nullability. The [element] parameter
* is for debugging purposes only and can be omitted.
*/
- TypeMask best(var type1, var type2, [element]) {
+ FlatTypeMask best(TypeMask type1, TypeMask type2, [element]) {
// TODO(polux): Handle [UnionTypeMask].
if (type1 != null) type1 = type1.simplify(compiler);
if (type2 != null) type2 = type2.simplify(compiler);
- final result = _best(type1, type2);
+ FlatTypeMask result = _best(type1, type2);
// Tests type1 and type2 for equality modulo normalization of native types.
// Only called when DUMP_SURPRISING_RESULTS is true.
bool similar() {
if (type1 == null || type2 == null || type1.isEmpty || type2.isEmpty) {
return type1 == type2;
}
- return same(type1.base, type2.base);
+ FlatTypeMask flat1 = type1;
+ FlatTypeMask flat2 = type2;
+ return same(flat1.base, flat2.base);
}
if (DUMP_SURPRISING_RESULTS && result == type1 && !similar()) {
print("$type1 better than $type2 for $element");
@@ -248,54 +249,56 @@
}
/// Helper method for [best].
- TypeMask _best(var type1, var type2) {
+ FlatTypeMask _best(var type1, var type2) {
if (type1 == null) return type2;
if (type2 == null) return type1;
- if (type1.isContainer) type1 = type1.asFlat;
- if (type2.isContainer) type2 = type2.asFlat;
- if (type1.isExact) {
- if (type2.isExact) {
+ FlatTypeMask flat1 = type1.isContainer ? type1.asFlat : type1;
+ FlatTypeMask flat2 = type2.isContainer ? type2.asFlat : type2;
+ if (flat1.isExact) {
+ if (flat2.isExact) {
// TODO(polux): Update the code to not have this situation.
- if (type1.base != type2.base) return type1;
- assert(same(type1.base, type2.base));
- return type1.isNullable ? type2 : type1;
+ if (flat1.base != flat2.base) return flat1;
+ assert(same(flat1.base, flat2.base));
+ return flat1.isNullable ? flat2 : flat1;
} else {
- return type1;
+ return flat1;
}
- } else if (type2.isExact) {
- return type2;
- } else if (type1.isSubclass) {
- if (type2.isSubclass) {
- assert(related(type1.base, type2.base));
- if (same(type1.base, type2.base)) {
- return type1.isNullable ? type2 : type1;
- } else if (compiler.types.isSubtype(type1.base, type2.base)) {
- return type1;
+ } else if (flat2.isExact) {
+ return flat2;
+ } else if (flat1.isSubclass) {
+ if (flat2.isSubclass) {
+ assert(related(flat1.base, flat2.base));
+ if (same(flat1.base, flat2.base)) {
+ return flat1.isNullable ? flat2 : flat1;
+ } else if (compiler.types.isSubtype(flat1.base.rawType,
+ flat2.base.rawType)) {
+ return flat1;
} else {
- return type2;
+ return flat2;
}
} else {
- return type1;
+ return flat1;
}
- } else if (type2.isSubclass) {
- return type2;
- } else if (type1.isSubtype) {
- if (type2.isSubtype) {
- assert(related(type1.base, type2.base));
- if (same(type1.base, type2.base)) {
- return type1.isNullable ? type2 : type1;
- } else if (compiler.types.isSubtype(type1.base, type2.base)) {
- return type1;
+ } else if (flat2.isSubclass) {
+ return flat2;
+ } else if (flat1.isSubtype) {
+ if (flat2.isSubtype) {
+ assert(related(flat1.base, flat2.base));
+ if (same(flat1.base, flat2.base)) {
+ return flat1.isNullable ? flat2 : flat1;
+ } else if (compiler.types.isSubtype(flat1.base.rawType,
+ flat2.base.rawType)) {
+ return flat1;
} else {
- return type2;
+ return flat2;
}
} else {
- return type1;
+ return flat1;
}
- } else if (type2.isSubtype) {
- return type2;
+ } else if (flat2.isSubtype) {
+ return flat2;
} else {
- return type1.isNullable ? type2 : type1;
+ return flat1.isNullable ? flat2 : flat1;
}
}
@@ -315,7 +318,6 @@
}
}
});
- compiler.containerTracer.analyze();
typesInferrer.clear();
}
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 6c40e56..269b1b5 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -37,8 +37,7 @@
continue;
} else {
FlatTypeMask flatMask = mask;
- assert(flatMask.base == null
- || flatMask.base.element != compiler.dynamicClass);
+ assert(flatMask.base == null || flatMask.base != compiler.dynamicClass);
int inListIndex = -1;
bool covered = false;
@@ -87,13 +86,13 @@
bool isNullable = masks.any((e) => e.isNullable);
// Compute the common supertypes of the two types.
- ClassElement firstElement = masks[0].base.element;
- ClassElement secondElement = masks[1].base.element;
+ ClassElement firstElement = masks[0].base;
+ ClassElement secondElement = masks[1].base;
Iterable<ClassElement> candidates =
compiler.world.commonSupertypesOf(firstElement, secondElement);
bool unseenType = false;
for (int i = 2; i < masks.length; i++) {
- ClassElement element = masks[i].base.element;
+ ClassElement element = masks[i].base;
Set<ClassElement> supertypes = compiler.world.supertypesOf(element);
if (supertypes == null) {
unseenType = true;
@@ -105,7 +104,7 @@
if (candidates.isEmpty || unseenType) {
// TODO(kasperl): Get rid of this check. It can only happen when
// at least one of the two base types is 'unseen'.
- return new TypeMask(compiler.objectClass.rawType,
+ return new TypeMask(compiler.objectClass,
FlatTypeMask.SUBCLASS,
isNullable);
}
@@ -120,7 +119,7 @@
int size;
int kind;
if (subclasses != null
- && masks.every((t) => subclasses.contains(t.base.element))) {
+ && masks.every((t) => subclasses.contains(t.base))) {
// If both [this] and [other] are subclasses of the supertype,
// then we prefer to construct a subclass type mask because it
// will always be at least as small as the corresponding
@@ -140,9 +139,7 @@
}
}
if (bestElement == compiler.objectClass) bestKind = FlatTypeMask.SUBCLASS;
- return new TypeMask(bestElement.computeType(compiler),
- bestKind,
- isNullable);
+ return new TypeMask(bestElement, bestKind, isNullable);
}
TypeMask union(var other, Compiler compiler) {
@@ -217,7 +214,7 @@
return disjointMasks.every((mask) => mask.satisfies(cls, compiler));
}
- bool contains(DartType type, Compiler compiler) {
+ bool contains(ClassElement type, Compiler compiler) {
return disjointMasks.any((e) => e.contains(type, compiler));
}
diff --git a/sdk/lib/_internal/compiler/implementation/universe/function_set.dart b/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
index bae06cb..d5f8784 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
@@ -146,7 +146,7 @@
// to always be a subclass of Object.
return selector.mask != null
? selector.mask
- : new TypeMask.subclass(compiler.objectClass.rawType);
+ : new TypeMask.subclass(compiler.objectClass);
}
FunctionSetQuery query(Selector selector,
@@ -225,8 +225,8 @@
return const TypeMask.empty();
}
return compiler.world.hasSubclasses(cls)
- ? new TypeMask.nonNullSubclass(cls.rawType)
- : new TypeMask.nonNullExact(cls.rawType);
+ ? new TypeMask.nonNullSubclass(cls)
+ : new TypeMask.nonNullExact(cls);
}),
compiler);
}
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 1bcf514..e0b1548 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -638,13 +638,13 @@
return result;
}
- factory TypedSelector.exact(DartType base, Selector selector)
+ factory TypedSelector.exact(ClassElement base, Selector selector)
=> new TypedSelector(new TypeMask.exact(base), selector);
- factory TypedSelector.subclass(DartType base, Selector selector)
+ factory TypedSelector.subclass(ClassElement base, Selector selector)
=> new TypedSelector(new TypeMask.subclass(base), selector);
- factory TypedSelector.subtype(DartType base, Selector selector)
+ factory TypedSelector.subtype(ClassElement base, Selector selector)
=> new TypedSelector(new TypeMask.subtype(base), selector);
bool appliesUnnamed(Element element, Compiler compiler) {
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index 2638fd8..c904cc1 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -77,6 +77,11 @@
_StackTraceLine(this.index, this.file, this.lineNo,
this.columnNo, this.method);
+
+ String toString() {
+ return 'index=$index, file=$file, '
+ 'lineNo=$lineNo, columnNo=$columnNo, method=$method';
+ }
}
// TODO(johnniwinther): Use this format for --throw-on-error.
@@ -123,14 +128,31 @@
int lastColon = line.lastIndexOf(':', rightParenPos);
int nextToLastColon = line.lastIndexOf(':', lastColon-1);
- String lineNo = line.substring(nextToLastColon+1, lastColon);
+ String lineNo;
+ String columnNo;
+ if (nextToLastColon != -1) {
+ lineNo = line.substring(nextToLastColon+1, lastColon);
+ columnNo = line.substring(lastColon+1, rightParenPos);
+ try {
+ int.parse(lineNo);
+ } on FormatException catch (e) {
+ lineNo = columnNo;
+ columnNo = '';
+ nextToLastColon = lastColon;
+ }
+ } else {
+ lineNo = line.substring(lastColon+1, rightParenPos);
+ columnNo = '';
+ nextToLastColon = lastColon;
+ }
+
if (lineNo.length > maxLineNoLength) {
maxLineNoLength = lineNo.length;
}
- String columnNo = line.substring(lastColon+1, rightParenPos);
if (columnNo.length > maxColumnNoLength) {
maxColumnNoLength = columnNo.length;
}
+
String file = line.substring(leftParenPos+1, nextToLastColon);
if (filePrefix != null && file.startsWith(filePrefix)) {
file = file.substring(filePrefix.length);
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index b44e3ec..3c3729e 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -599,6 +599,34 @@
main() => foo(42);
"""]);
+ static const MessageKind FINAL_FUNCTION_TYPE_PARAMETER = const MessageKind(
+ "Error: A function type parameter can't be declared final.",
+ howToFix: "Try removing 'final'.",
+ examples: const ["""
+foo(final int x(int a)) {}
+main() => foo((y) => 42);
+""", """
+foo({final int x(int a)}) {}
+main() => foo((y) => 42);
+""", """
+foo([final int x(int a)]) {}
+main() => foo((y) => 42);
+"""]);
+
+ static const MessageKind VAR_FUNCTION_TYPE_PARAMETER = const MessageKind(
+ "Error: A function type parameter can't be declared with 'var'.",
+ howToFix: "Try removing 'var'.",
+ examples: const ["""
+foo(var int x(int a)) {}
+main() => foo((y) => 42);
+""", """
+foo({var int x(int a)}) {}
+main() => foo((y) => 42);
+""", """
+foo([var int x(int a)]) {}
+main() => foo((y) => 42);
+"""]);
+
static const MessageKind CANNOT_INSTANTIATE_TYPE_VARIABLE = const MessageKind(
"Error: Cannot instantiate type variable '#{typeVariableName}'.");
@@ -640,6 +668,19 @@
static const MessageKind CANNOT_IMPLEMENT = const MessageKind(
"Error: '#{type}' cannot be implemented.");
+ static const MessageKind CANNOT_MIXIN = const MessageKind(
+ "Error: The type '#{type}' can't be mixed in.",
+ howToFix: "Try removing '#{type}' from the 'with' clause.",
+ examples: const ["""
+class C extends Object with String {}
+
+main() => new C();
+""", """
+typedef C = Object with String;
+
+main() => new C();
+"""]);
+
static const MessageKind DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
"Error: '#{type}' can not be both extended and implemented.");
@@ -905,6 +946,13 @@
"Error: '#{value}' is not a valid Symbol name because it starts with "
"'_'.");
+ static const MessageKind PRIVATE_NAMED_PARAMETER = const MessageKind(
+ "Error: Named optional parameter can't have a library private name.",
+ howToFix: "Try removing the '_' or making the parameter positional or "
+ "required.",
+ examples: const ["""foo({int _p}) {} main() => foo();"""]
+ );
+
static const MessageKind UNSUPPORTED_LITERAL_SYMBOL = const MessageKind(
"Internal Error: Symbol literal '##{value}' is currently unsupported.");
diff --git a/sdk/lib/_internal/compiler/implementation/world.dart b/sdk/lib/_internal/compiler/implementation/world.dart
index 4d25945..17f3b7f 100644
--- a/sdk/lib/_internal/compiler/implementation/world.dart
+++ b/sdk/lib/_internal/compiler/implementation/world.dart
@@ -152,15 +152,17 @@
}
// Returns whether a subclass of [superclass] implements [type].
- bool hasAnySubclassThatImplements(ClassElement superclass, DartType type) {
+ bool hasAnySubclassThatImplements(ClassElement superclass,
+ ClassElement type) {
Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass);
if (subclasses == null) return false;
- return subclasses.contains(type.element);
+ return subclasses.contains(type);
}
// Returns whether a subclass of any mixin application of [cls] implements
// [type].
- bool hasAnySubclassOfMixinUseThatImplements(ClassElement cls, DartType type) {
+ bool hasAnySubclassOfMixinUseThatImplements(ClassElement cls,
+ ClassElement type) {
Set<MixinApplicationElement> uses = mixinUses[cls];
if (uses == null || uses.isEmpty) return false;
return uses.any((use) => hasAnySubclassThatImplements(use, type));
@@ -192,7 +194,7 @@
Element locateSingleElement(Selector selector) {
ti.TypeMask mask = selector.mask == null
- ? new ti.TypeMask.subclass(compiler.objectClass.rawType)
+ ? new ti.TypeMask.subclass(compiler.objectClass)
: selector.mask;
return mask.locateSingleElement(selector, compiler);
}
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index 095c424..dd4444a 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -9,7 +9,7 @@
patch static _setCurrent(path) {
throw new UnsupportedError("Directory_SetCurrent");
}
- patch static _createTemp(String template) {
+ patch static _createTemp(String template, bool system) {
throw new UnsupportedError("Directory._createTemp");
}
patch static int _exists(String path) {
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index ac4cc0f..8b0ad62 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -411,7 +411,7 @@
const String _SPAWNED_SIGNAL = "spawned";
-var globalThis = IsolateNatives.computeGlobalThis();
+var globalThis = Primitives.computeGlobalThis();
var globalWindow = JS('', "#.window", globalThis);
var globalWorker = JS('', "#.Worker", globalThis);
bool globalPostMessageDefined =
@@ -480,8 +480,6 @@
throw new UnsupportedError('Cannot extract URI from "$stack"');
}
- static computeGlobalThis() => JS('', 'function() { return this; }()');
-
/**
* Assume that [e] is a browser message event and extract its message data.
* We don't import the dom explicitly so, when workers are disabled, this
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index ddeb666..0219440 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -279,6 +279,8 @@
return JS('int', '#', hash);
}
+ static computeGlobalThis() => JS('', 'function() { return this; }()');
+
/**
* This is the low-level method that is used to implement
* [print]. It is possible to override this function from JavaScript
@@ -1498,13 +1500,19 @@
var isolate,
int numberOfArguments,
var arg1,
- var arg2) {
+ var arg2,
+ var arg3,
+ var arg4) {
if (numberOfArguments == 0) {
return JS_CALL_IN_ISOLATE(isolate, () => closure());
} else if (numberOfArguments == 1) {
return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1));
} else if (numberOfArguments == 2) {
return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2));
+ } else if (numberOfArguments == 3) {
+ return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2, arg3));
+ } else if (numberOfArguments == 4) {
+ return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2, arg3, arg4));
} else {
throw new Exception(
'Unsupported number of arguments for wrapped closure');
@@ -1523,9 +1531,11 @@
// We use $0 and $1 to not clash with variable names used by the
// compiler and/or minifier.
function = JS('var',
- r'(function ($2, $3) {'
- r' return function($0, $1) { '
- r'return $3(#, $2, #, $0, $1) }})(#, #)',
+ '(function(closure, arity, context, invoke) {'
+ ' return function(a1, a2, a3, a4) {'
+ ' return invoke(closure, context, arity, a1, a2, a3, a4);'
+ ' };'
+ '})(#,#,#,#)',
closure,
arity,
// Capture the current isolate now. Remember that "#"
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 557dbba..be6ef7c 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
@@ -46,11 +46,7 @@
/// them (with [configuration] if it's non-null), and return them.
Iterable<Transformer> initialize(Uri uri, Map configuration) {
var mirrors = currentMirrorSystem();
- // TODO(nweiz): look this up by name once issue 5897 is fixed.
- var transformerUri = Uri.parse(
- 'http://<<HOST_AND_PORT>>/packages/barback/src/transformer.dart');
- var transformerClass = mirrors.libraries[transformerUri]
- .classes[const Symbol('Transformer')];
+ var transformerClass = reflectClass(Transformer);
// TODO(nweiz): if no valid transformers are found, throw an error message
// describing candidates and why they were rejected.
@@ -289,7 +285,7 @@
TransformerId id) {
var path = id.asset.path.replaceFirst('lib/', '');
// TODO(nweiz): load from a "package:" URI when issue 12474 is fixed.
- var hostAndPort = '${server.host}:${server.port}';
+ var hostAndPort = '${server.address.address}:${server.port}';
var uri = 'http://$hostAndPort/packages/${id.asset.package}/$path';
var code = 'import "$uri";' +
_TRANSFORMER_ISOLATE.replaceAll('<<HOST_AND_PORT>>', hostAndPort);
diff --git a/sdk/lib/_internal/pub/lib/src/barback/server.dart b/sdk/lib/_internal/pub/lib/src/barback/server.dart
index a2ce379..3b8c154 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/server.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/server.dart
@@ -29,10 +29,8 @@
/// 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 server's address.
+ final InternetAddress address;
/// The results of requests handled by the server.
///
@@ -50,12 +48,13 @@
static Future<BarbackServer> bind(String host, int port, Barback barback,
String rootPackage) {
return HttpServer.bind(host, port)
- .then((server) => new BarbackServer._(server, barback, rootPackage, host));
+ .then((server) => new BarbackServer._(server, barback, rootPackage));
}
- BarbackServer._(HttpServer server, this.barback, this._rootPackage, this.host)
+ BarbackServer._(HttpServer server, this.barback, this._rootPackage)
: _server = server,
- port = server.port {
+ port = server.port,
+ address = server.address {
_server.listen(_handleRequest, onError: (error) {
_resultsController.addError(error);
close();
diff --git a/sdk/lib/_internal/pub/lib/src/exit_codes.dart b/sdk/lib/_internal/pub/lib/src/exit_codes.dart
index 028fd1c..156e49e 100644
--- a/sdk/lib/_internal/pub/lib/src/exit_codes.dart
+++ b/sdk/lib/_internal/pub/lib/src/exit_codes.dart
@@ -10,46 +10,46 @@
library pub.exit_codes;
/// The command was used incorrectly.
-final USAGE = 64;
+const USAGE = 64;
/// The input data was incorrect.
-final DATA = 65;
+const DATA = 65;
/// An input file did not exist or was unreadable.
-final NO_INPUT = 66;
+const NO_INPUT = 66;
/// The user specified did not exist.
-final NO_USER = 67;
+const NO_USER = 67;
/// The host specified did not exist.
-final NO_HOST = 68;
+const NO_HOST = 68;
/// A service is unavailable.
-final UNAVAILABLE = 69;
+const UNAVAILABLE = 69;
/// An internal software error has been detected.
-final SOFTWARE = 70;
+const SOFTWARE = 70;
/// An operating system error has been detected.
-final OS = 71;
+const OS = 71;
/// Some system file did not exist or was unreadable.
-final OS_FILE = 72;
+const OS_FILE = 72;
/// A user-specified output file cannot be created.
-final CANT_CREATE = 73;
+const CANT_CREATE = 73;
/// An error occurred while doing I/O on some file.
-final IO = 74;
+const IO = 74;
/// Temporary failure, indicating something that is not really an error.
-final TEMP_FAIL = 75;
+const TEMP_FAIL = 75;
/// The remote system returned something invalid during a protocol exchange.
-final PROTOCOL = 76;
+const PROTOCOL = 76;
/// The user did not have sufficient permissions.
-final NO_PERM = 77;
+const NO_PERM = 77;
/// Something was unconfigured or mis-configured.
-final CONFIG = 78;
+const CONFIG = 78;
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 41a2543..af8168e 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -232,12 +232,19 @@
/// suffix appended to it. If [dir] is not provided, a temp directory will be
/// created in a platform-dependent temporary location. Returns the path of the
/// created directory.
-String createTempDir([dir = '']) {
- var tempDir = new Directory(dir).createTempSync();
+String createTempDir(String base, String prefix) {
+ var tempDir = new Directory(base).createTempSync(prefix);
log.io("Created temp directory ${tempDir.path}");
return tempDir.path;
}
+String createSystemTempDir() {
+ var tempDir = Directory.createSystemTempSync('pub_');
+ log.io("Created temp directory ${tempDir.path}");
+ return tempDir.path;
+}
+
+
/// Lists the contents of [dir]. If [recursive] is `true`, lists subdirectory
/// contents (defaults to `false`). If [includeHidden] is `true`, includes files
/// and directories beginning with `.` (defaults to `false`).
@@ -648,7 +655,7 @@
/// [fn] completes to.
Future withTempDir(Future fn(String path)) {
return new Future.sync(() {
- var tempDir = createTempDir();
+ var tempDir = createSystemTempDir();
return new Future.sync(() => fn(tempDir))
.whenComplete(() => deleteEntry(tempDir));
});
diff --git a/sdk/lib/_internal/pub/lib/src/system_cache.dart b/sdk/lib/_internal/pub/lib/src/system_cache.dart
index 7dafb8c..63b9817 100644
--- a/sdk/lib/_internal/pub/lib/src/system_cache.dart
+++ b/sdk/lib/_internal/pub/lib/src/system_cache.dart
@@ -96,7 +96,7 @@
/// cache so that it can move the directory from it.
String createTempDir() {
var temp = ensureDir(tempDir);
- return io.createTempDir(path.join(temp, 'dir'));
+ return io.createTempDir(temp, 'dir');
}
/// Deletes the system cache's internal temp directory.
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index 1f79116..fc449c2 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -337,7 +337,7 @@
d.file('version', '0.1.2.3')
]).create();
- _sandboxDir = createTempDir();
+ _sandboxDir = createSystemTempDir();
d.defaultRoot = sandboxDir;
currentSchedule.onComplete.schedule(() => deleteEntry(_sandboxDir),
'deleting the sandbox directory');
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index ac6bacd..4f067dd 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -251,23 +251,44 @@
*/
dynamic runUnaryGuarded(f(arg), var arg);
- ZoneCallback registerCallback(f());
- ZoneUnaryCallback registerUnaryCallback(f(arg));
+ /**
+ * Registers the given callback in this zone.
+ *
+ * It is good practice to register asynchronous or delayed callbacks before
+ * invoking [run]. This gives the zone a chance to wrap the callback and
+ * to store information with the callback. For example, a zone may decide
+ * to store the stack trace (at the time of the registration) with the
+ * callback.
+ *
+ * Returns a potentially new callback that should be used in place of the
+ * given [callback].
+ */
+ ZoneCallback registerCallback(callback());
+
+ /**
+ * Registers the given callback in this zone.
+ *
+ * Similar to [registerCallback] but with a unary callback.
+ */
+ ZoneUnaryCallback registerUnaryCallback(callback(arg));
/**
* Equivalent to:
*
* ZoneCallback registered = registerCallback(f);
+ * if (runGuarded) return () => this.runGuarded(registered);
* return () => this.run(registered);
+ *
*/
- ZoneCallback bindCallback(f(), { bool runGuarded });
+ ZoneCallback bindCallback(f(), { bool runGuarded: true });
/**
* Equivalent to:
*
* ZoneCallback registered = registerCallback1(f);
- * return (arg) => this.run1(registered, arg);
+ * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg);
+ * return (arg) => thin.runUnary(registered, arg);
*/
- ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded });
+ ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded: true });
/**
* Runs [f] asynchronously.
@@ -427,7 +448,7 @@
}
}
- ZoneCallback bindCallback(f(), { bool runGuarded }) {
+ ZoneCallback bindCallback(f(), { bool runGuarded: true }) {
ZoneCallback registered = registerCallback(f);
if (runGuarded) {
return () => this.runGuarded(registered);
@@ -436,7 +457,7 @@
}
}
- ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded }) {
+ ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded: true }) {
ZoneUnaryCallback registered = registerUnaryCallback(f);
if (runGuarded) {
return (arg) => this.runUnaryGuarded(registered, arg);
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 6abaa05..3562085 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -7,6 +7,9 @@
/** The Unicode Replacement character `U+FFFD` (�). */
const UNICODE_REPLACEMENT_CHARACTER_RUNE = 0xFFFD;
+/** The Unicode Byte Order Marker (BOM) character `U+FEFF`. */
+const UNICODE_BOM_CHARACTER_RUNE = 0xFEFF;
+
/**
* An instance of the default implementation of the [Utf8Codec].
*
@@ -48,6 +51,9 @@
* Decodes the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
* corresponding string.
*
+ * If the [codeUnits] start with a leading [UNICODE_BOM_CHARACTER_RUNE] this
+ * character is discarded.
+ *
* If [allowMalformed] is `true` the decoder replaces invalid (or
* unterminated) character sequences with the Unicode Replacement character
* `U+FFFD` (�). Otherwise it throws a [FormatException].
@@ -303,6 +309,9 @@
/**
* Converts the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
* corresponding string.
+ *
+ * If the [codeUnits] start with a leading [UNICODE_BOM_CHARACTER_RUNE] this
+ * character is discarded.
*/
String convert(List<int> codeUnits) {
StringBuffer buffer = new StringBuffer();
@@ -346,9 +355,6 @@
const int _LEAD_SURROGATE_MIN = 0xD800;
const int _TAIL_SURROGATE_MIN = 0xDC00;
-const int _REPLACEMENT_CHARACTER = 0xFFFD;
-const int _BOM_CHARACTER = 0xFEFF;
-
bool _isSurrogate(int codeUnit) =>
(codeUnit & _SURROGATE_MASK) == _LEAD_SURROGATE_MIN;
bool _isLeadSurrogate(int codeUnit) =>
@@ -356,7 +362,7 @@
bool _isTailSurrogate(int codeUnit) =>
(codeUnit & _SURROGATE_TAG_MASK) == _TAIL_SURROGATE_MIN;
int _combineSurrogatePair(int lead, int tail) =>
- 0x10000 | ((lead & _SURROGATE_VALUE_MASK) << 10)
+ 0x10000 + ((lead & _SURROGATE_VALUE_MASK) << 10)
| (tail & _SURROGATE_VALUE_MASK);
@@ -400,7 +406,7 @@
if (!_allowMalformed) {
throw new FormatException("Unfinished UTF-8 octet sequence");
}
- _stringSink.writeCharCode(_REPLACEMENT_CHARACTER);
+ _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE);
_value = 0;
_expectedUnits = 0;
_extraUnits = 0;
@@ -430,7 +436,7 @@
"Bad UTF-8 encoding 0x${unit.toRadixString(16)}");
}
_isFirstCharacter = false;
- _stringSink.writeCharCode(_REPLACEMENT_CHARACTER);
+ _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE);
break multibyte;
} else {
value = (value << 6) | (unit & 0x3f);
@@ -446,16 +452,16 @@
"Overlong encoding of 0x${value.toRadixString(16)}");
}
expectedUnits = extraUnits = 0;
- value = _REPLACEMENT_CHARACTER;
+ value = UNICODE_REPLACEMENT_CHARACTER_RUNE;
}
if (value > _FOUR_BYTE_LIMIT) {
if (!_allowMalformed) {
throw new FormatException("Character outside valid Unicode range: "
"0x${value.toRadixString(16)}");
}
- value = _REPLACEMENT_CHARACTER;
+ value = UNICODE_REPLACEMENT_CHARACTER_RUNE;
}
- if (!_isFirstCharacter || value != _BOM_CHARACTER) {
+ if (!_isFirstCharacter || value != UNICODE_BOM_CHARACTER_RUNE) {
_stringSink.writeCharCode(value);
}
_isFirstCharacter = false;
@@ -474,7 +480,7 @@
throw new FormatException(
"Negative UTF-8 code unit: -0x${(-unit).toRadixString(16)}");
}
- _stringSink.writeCharCode(_REPLACEMENT_CHARACTER);
+ _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE);
} else if (unit <= _ONE_BYTE_LIMIT) {
_isFirstCharacter = false;
_stringSink.writeCharCode(unit);
@@ -499,7 +505,7 @@
throw new FormatException(
"Bad UTF-8 encoding 0x${unit.toRadixString(16)}");
}
- value = _REPLACEMENT_CHARACTER;
+ value = UNICODE_REPLACEMENT_CHARACTER_RUNE;
expectedUnits = extraUnits = 0;
_isFirstCharacter = false;
_stringSink.writeCharCode(value);
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index d311785..a0473cb 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -19,42 +19,49 @@
* The following code illustrates that some List implementations support
* only a subset of the API.
*
- * var fixedLengthList = new List(5);
- * fixedLengthList.length = 0; // Error.
- * fixedLengthList.add(499); // Error.
+ * List<int> fixedLengthList = new List(5);
+ * fixedLengthList.length = 0; // Error
+ * fixedLengthList.add(499); // Error
* fixedLengthList[0] = 87;
- *
- * var growableList = [1, 2];
+ * List<int> growableList = [1, 2];
* growableList.length = 0;
* growableList.add(499);
* growableList[0] = 87;
*
- * Lists are [Iterable].
- * Iteration occurs over values in index order.
- * Changing the values does not affect iteration,
- * but changing the valid indices—that is,
- * changing the list's length—between
- * iteration steps
- * causes a [ConcurrentModificationError].
- * This means that only growable lists can throw ConcurrentModificationError.
- * If the length changes temporarily
- * and is restored before continuing the iteration,
- * the iterator does not detect it.
+ * Lists are [Iterable]. Iteration occurs over values in index order. Changing
+ * the values does not affect iteration, but changing the valid
+ * indices—that is, changing the list's length—between iteration
+ * steps causes a [ConcurrentModificationError]. This means that only growable
+ * lists can throw ConcurrentModificationError. If the length changes
+ * temporarily and is restored before continuing the iteration, the iterator
+ * does not detect it.
*/
abstract class List<E> implements Iterable<E> {
/**
- * Creates a list of the given _length_.
+ * Creates a list of the given length.
*
- * The created list is fixed-length if _length_ is provided.
- * The list has length 0 and is growable if _length_ is omitted.
+ * The created list is fixed-length if [length] is provided.
*
- * An error occurs if _length_ is negative.
+ * List fixedLengthList = new List(3);
+ * fixedLengthList.length; // 3
+ fixedLengthList.length = 1; // Error
+ *
+ *
+ * The list has length 0 and is growable if [length] is omitted.
+ *
+ * List growableList = new List();
+ * growableList.length; // 0;
+ * growableList.length = 3;
+ *
+ * An error occurs if [length] is negative.
*/
external factory List([int length]);
/**
- * Creates a fixed-length list of the given _length_
- * and initializes the value at each position with [fill].
+ * Creates a fixed-length list of the given length, and initializes the
+ * value at each position with [fill]:
+ *
+ * new List<int>.filled(3, 0); // [0, 0, 0]
*/
external factory List.filled(int length, E fill);
@@ -83,11 +90,12 @@
/**
* Generates a list of values.
*
- * Creates a list with _length_ positions
- * and fills it with values created by calling [generator]
- * for each index in the range `0` .. `length - 1`
+ * Creates a list with [length] positions and fills it with values created by
+ * calling [generator] for each index in the range `0` .. `length - 1`
* in increasing order.
*
+ * new List<int>.generate(3, (int index) => index * index); // [0, 1, 4]
+ *
* The created list is fixed-length unless [growable] is true.
*/
factory List.generate(int length, E generator(int index),
@@ -127,7 +135,7 @@
* Changes the length of this list.
*
* If [newLength] is greater than
- * the current [length], entries are initialized to [:null:].
+ * the current length, entries are initialized to [:null:].
*
* Throws an [UnsupportedError] if the list is fixed-length.
*/
@@ -158,19 +166,35 @@
* Sorts this list according to the order specified by the [compare] function.
*
* The [compare] function must act as a [Comparator].
+
+ * List<String> numbers = ['one', 'two', 'three', 'four'];
+ * // Sort from shortest to longest.
+ * numbers.sort((x, y) => x.length.compareTo(y.length));
+ * numbers.join(', '); // 'one, two, four, three'
*
* The default List implementations use [Comparable.compare] if
* [compare] is omitted.
+ *
+ * List<int> nums = [13, 2, -11];
+ * nums.sort();
+ nums.join(', '); // '-11, 2, 13'
*/
void sort([int compare(E a, E b)]);
/**
* Returns the first index of [element] in this list.
*
- * Searches the list from index [start] to the length of the list.
+ * Searches the list from index [start] to the end of the list.
* The first time an object [:o:] is encountered so that [:o == element:],
* the index of [:o:] is returned.
+ *
+ * List<String> notes = ['do', 're', 'mi', 're'];
+ * notes.indexOf('re'); // 1
+ * notes.indexOf('re', 2); // 3
+ *
* Returns -1 if [element] is not found.
+ *
+ * notes.indexOf('fa'); // -1
*/
int indexOf(E element, [int start = 0]);
@@ -182,9 +206,17 @@
* The first time an object [:o:] is encountered so that [:o == element:],
* the index of [:o:] is returned.
*
- * If [start] is not provided, it defaults to [:this.length - 1:].
+ * List<String> notes = ['do', 're', 'mi', 're'];
+ * notes.lastIndexOf('re', 2); // 1
+ *
+ * If [start] is not provided, this method searches from the end of the
+ * list./Returns
+ *
+ * notes.lastIndexOf('re'); // 3
*
* Returns -1 if [element] is not found.
+ *
+ * notes.lastIndexOf('fa'); // -1
*/
int lastIndexOf(E element, [int start]);
@@ -223,6 +255,10 @@
* Overwrites objects of `this` with the objects of [iterable], starting
* at position [index] in this list.
*
+ * List<String> list = ['a', 'b', 'c'];
+ * list.setAll(1, ['bee', 'sea']);
+ * list.join(', '); // 'a, bee, sea'
+ *
* This operation does not increase the length of `this`.
*
* An error occurs if the [index] is less than 0 or greater than length.
@@ -233,11 +269,18 @@
/**
* Removes the first occurence of [value] from this list.
*
- * Returns true if [value] was in the list.
- * Returns false otherwise.
+ * Returns true if [value] was in the list, false otherwise.
+ *
+ * List<String> parts = ['head', 'shoulders', 'knees', 'toes'];
+ * parts.remove('head'); // true
+ * parts.join(', '); // 'shoulders, knees, toes'
*
* The method has no effect if [value] was not in the list.
*
+ * // Note: 'head' has already been removed.
+ * parts.remove('head'); // false
+ * parts.join(', '); // 'shoulders, knees, toes'
+ *
* An [UnsupportedError] occurs if the list is fixed-length.
*/
bool remove(Object value);
@@ -269,6 +312,10 @@
*
* An object [:o:] satisfies [test] if [:test(o):] is true.
*
+ * List<String> numbers = ['one', 'two', 'three', 'four'];
+ * numbers.removeWhere((item) => item.length == 3);
+ * numbers.join(', '); // 'three, four'
+ *
* Throws an [UnsupportedError] if this is a fixed-length list.
*/
void removeWhere(bool test(E element));
@@ -278,16 +325,25 @@
*
* An object [:o:] satisfies [test] if [:test(o):] is true.
*
+ * List<String> numbers = ['one', 'two', 'three', 'four'];
+ * numbers.retainWhere((item) => item.length == 3);
+ * numbers.join(', '); // 'one, two'
+ *
* Throws an [UnsupportedError] if this is a fixed-length list.
*/
void retainWhere(bool test(E element));
/**
- * Returns a new list containing the objects
- * from [start] inclusive to [end] exclusive.
+ * Returns a new list containing the objects from [start] inclusive to [end]
+ * exclusive.
+ *
+ * List<String> colors = ['red', 'green', 'blue', 'orange', 'pink'];
+ * colors.sublist(1, 3); // ['green', 'blue']
*
* If [end] is omitted, the [length] of `this` is used.
*
+ * colors.sublist(1); // ['green', 'blue', 'orange', 'pink']
+ *
* An error occurs if [start] is outside the range `0` .. `length` or if
* [end] is outside the range `start` .. `length`.
*/
@@ -304,13 +360,11 @@
* `skip(start).take(end - start)`. That is, it does not throw exceptions
* if `this` changes size.
*
- * Example:
- *
- * var list = [1, 2, 3, 4, 5];
- * var range = list.getRange(1, 4);
- * print(range.join(', ')); // => 2, 3, 4
- * list.length = 3;
- * print(range.join(', ')); // => 2, 3
+ * List<String> colors = ['red', 'green', 'blue', 'orange', 'pink'];
+ * Iterable<String> range = colors.getRange(1, 4);
+ * range.join(', '); // 'green, blue, orange'
+ * colors.length = 3;
+ * range.join(', '); // 'green, blue'
*/
Iterable<E> getRange(int start, int end);
@@ -318,6 +372,13 @@
* Copies the objects of [iterable], skipping [skipCount] objects first,
* into the range [start] inclusive to [end] exclusive of `this`.
*
+ * List<int> list1 = [1, 2, 3, 4];
+ * List<int> list2 = [5, 6, 7, 8, 9];
+ * // Copies the 4th and 5th items in list2 as the 2nd and 3rd items
+ * // of list1.
+ * list1.setRange(1, 3, list2, 3);
+ * list1.join(', '); // '1, 8, 9, 4'
+ *
* If [start] equals [end] and [start]..[end] represents a legal range, this
* method has no effect.
*
@@ -325,12 +386,6 @@
* An error occurs if the [iterable] does not have enough objects after
* skipping [skipCount] objects.
*
- * Example:
- *
- * var list = [1, 2, 3, 4];
- * var list2 = [5, 6, 7, 8, 9];
- * list.setRange(1, 3, list2, 3);
- * print(list); // => [1, 8, 9, 4]
*/
void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]);
@@ -354,13 +409,11 @@
* Removes the objects in the range [start] inclusive to [end] exclusive
* and replaces them with the contents of the [iterable].
*
+ * List<int> list = [1, 2, 3, 4];
+ * list.replaceRange(1, 3, [6, 7]);
+ * list.join(', '); // '1, 6, 7, 4'
+ *
* An error occurs if [start]..[end] is not a valid range for `this`.
- *
- * Example:
- *
- * var list = [1, 2, 3, 4, 5];
- * list.replaceRange(1, 3, [6, 7, 8, 9]);
- * print(list); // [1, 6, 7, 8, 9, 4, 5]
*/
void replaceRange(int start, int end, Iterable<E> iterable);
@@ -370,6 +423,11 @@
* The map uses the indices of this list as keys and the corresponding objects
* as values. The `Map.keys` [Iterable] iterates the indices of this list
* in numerical order.
+ *
+ * List<String> words = ['fee', 'fi', 'fo', 'fum'];
+ * Map<int, String> map = words.asMap();
+ * map[0] + map[1]; // 'feefi';
+ * map.keys.toList(); // [0, 1, 2, 3]
*/
Map<int, E> asMap();
}
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index db187f5..38cb7cf 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -5,8 +5,8 @@
part of dart.core;
/**
- * An unordered collection of key-value pairs,
- * from which you retrieve a value by using its associated key.
+ * An unordered collection of key-value pairs, from which you retrieve a value
+ * by using its associated key.
*
* Each key can occur at most once in a map.
*/
@@ -27,18 +27,36 @@
factory Map.identity() = LinkedHashMap<K, V>.identity;
/**
- * Creates a Map instance
- * where the keys and values are computed from the [iterable].
+ * Creates a Map instance in which the keys and values are computed from the
+ * [iterable].
*
* For each element of the [iterable] this constructor computes a key-value
* pair, by applying [key] and [value] respectively.
*
- * The keys computed by the source [iterable]
- * do not need to be unique. The last
- * occurrence of a key will simply overwrite any previous value.
+ * The example below creates a new Map from a List. The keys of `map` are
+ * `list` values converted to strings, and the values of the `map` are the
+ * squares of the `list` values:
+ *
+ * List<int> list = [1, 2, 3];
+ * Map<String, int> map = new Map.fromIterable(list,
+ * key: (item) => item.toString(),
+ * value: (item) => item * item));
+ *
+ * map['1'] + map['2']; // 1 + 4
+ * map['3'] - map['2']; // 9 - 4
*
* If no values are specified for [key] and [value] the default is the
* identity function.
+ *
+ * In the following example, the keys and corresponding values of `map`
+ * are `list` values:
+ *
+ * map = new Map.fromIterable(list);
+ * map[1] + map[2]; // 1 + 2
+ * map[3] - map[2]; // 3 - 2
+ *
+ * The keys computed by the source [iterable] do not need to be unique. The
+ * last occurrence of a key will simply overwrite any previous value.
*/
factory Map.fromIterable(Iterable iterable,
{K key(element), V value(element)}) = LinkedHashMap<K, V>.fromIterable;
@@ -49,6 +67,11 @@
* This constructor iterates over [keys] and [values] and maps each element of
* [keys] to the corresponding element of [values].
*
+ * List<String> letters = ['b', 'c'];
+ * List<String> words = ['bad', 'cat'];
+ * Map<String, String> map = new Map.fromIterables(letters, words);
+ * map['b'] + map['c']; // badcat
+ *
* If [keys] contains the same object multiple times, the last occurrence
* overwrites the previous value.
*
@@ -85,8 +108,15 @@
* updates the map by mapping [key] to the value returned by
* [ifAbsent]. Returns the value in the map.
*
- * It is an error to add or remove keys from the map during the call to
- * [ifAbsent].
+ * Map<String, int> scores = {'Bob': 36};
+ * for (var key in ['Bob', 'Rohan', 'Sophena']) {
+ * scores.putIfAbsent(key, () => key.length);
+ * }
+ * scores['Bob']; // 36
+ * scores['Rohan']; // 5
+ * scores['Sophena']; // 7
+ *
+ * The code that [ifAbsent] executes must not add or remove keys.
*/
V putIfAbsent(K key, V ifAbsent());
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index f1199d0..6c9cfd9 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -88,8 +88,20 @@
// Dart issue 1990.
class HtmlElement extends Element native "HTMLElement" {
factory HtmlElement() { throw new UnsupportedError("Not supported"); }
+
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HtmlElement.created() : super.created();
}
+// EntryArray type was removed, so explicitly adding it to allow support for
+// older Chrome versions.
+// Issue #12573.
+abstract class _EntryArray implements List<Entry> native "EntryArray" {}
+
// Support for Send/ReceivePortSync.
int _getNewIsolateId() {
if (JS('bool', r'!window.$dart$isolate$counter')) {
@@ -186,6 +198,12 @@
if (href != null) e.href = href;
return e;
}
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnchorElement.created() : super.created();
@DomName('HTMLAnchorElement.download')
@DocsEditable()
@@ -431,6 +449,12 @@
@DomName('HTMLAreaElement.HTMLAreaElement')
@DocsEditable()
factory AreaElement() => document.createElement("area");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AreaElement.created() : super.created();
@DomName('HTMLAreaElement.alt')
@DocsEditable()
@@ -507,6 +531,12 @@
}
static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AudioElement.created() : super.created();
}
// 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
@@ -539,6 +569,12 @@
@DomName('HTMLBRElement.HTMLBRElement')
@DocsEditable()
factory BRElement() => document.createElement("br");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ BRElement.created() : super.created();
}
// 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
@@ -569,6 +605,12 @@
@DomName('HTMLBaseElement.HTMLBaseElement')
@DocsEditable()
factory BaseElement() => document.createElement("base");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ BaseElement.created() : super.created();
@DomName('HTMLBaseElement.href')
@DocsEditable()
@@ -696,6 +738,12 @@
@DomName('HTMLBodyElement.HTMLBodyElement')
@DocsEditable()
factory BodyElement() => document.createElement("body");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ BodyElement.created() : super.created();
@DomName('HTMLBodyElement.onblur')
@DocsEditable()
@@ -759,6 +807,12 @@
@DomName('HTMLButtonElement.HTMLButtonElement')
@DocsEditable()
factory ButtonElement() => document.createElement("button");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ButtonElement.created() : super.created();
@DomName('HTMLButtonElement.autofocus')
@DocsEditable()
@@ -885,6 +939,12 @@
if (height != null) e.height = height;
return e;
}
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ CanvasElement.created() : super.created();
/// The height of this canvas element in CSS pixels.
@DomName('HTMLCanvasElement.height')
@@ -1974,6 +2034,12 @@
@DomName('HTMLContentElement.HTMLContentElement')
@DocsEditable()
factory ContentElement() => document.createElement("content");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ContentElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('content');
@@ -6316,6 +6382,12 @@
@DomName('HTMLDListElement.HTMLDListElement')
@DocsEditable()
factory DListElement() => document.createElement("dl");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DListElement.created() : super.created();
}
// 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
@@ -6335,6 +6407,12 @@
@DomName('HTMLDataListElement.HTMLDataListElement')
@DocsEditable()
factory DataListElement() => document.createElement("datalist");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DataListElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('datalist');
@@ -6550,6 +6628,12 @@
@DomName('HTMLDetailsElement.HTMLDetailsElement')
@DocsEditable()
factory DetailsElement() => document.createElement("details");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DetailsElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('details');
@@ -6687,6 +6771,12 @@
class DialogElement extends HtmlElement native "HTMLDialogElement" {
// To suppress missing implicit constructor warnings.
factory DialogElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DialogElement.created() : super.created();
@DomName('HTMLDialogElement.open')
@DocsEditable()
@@ -6941,6 +7031,12 @@
@DomName('HTMLDivElement.HTMLDivElement')
@DocsEditable()
factory DivElement() => document.createElement("div");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DivElement.created() : super.created();
}
// 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
@@ -7603,7 +7699,6 @@
@Experimental()
Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);
-
/**
* Finds all descendant elements of this document that match the specified
* group of selectors.
@@ -8805,6 +8900,30 @@
}
/**
+ * Custom element creation constructor.
+ *
+ * This constructor is used by the DOM when a custom element has been
+ * created. It can only be invoked by subclasses of Element from
+ * that classes created constructor.
+ *
+ * class CustomElement extends Element {
+ * factory CustomElement() => new Element.tag('x-custom');
+ *
+ * CustomElement.created() : super.created() {
+ * // Perform any element initialization.
+ * }
+ * }
+ * document.register('x-custom', CustomElement);
+ */
+ Element.created() : super._created() {
+ // Validate that this is a custom element & perform any additional
+ // initialization.
+ _initializeCustomElement(this);
+
+ createdCallback();
+ }
+
+ /**
* Creates the HTML element specified by the tag name.
*
* This is similar to [Document.createElement].
@@ -9147,9 +9266,12 @@
/**
* Called by the DOM when this element has been instantiated.
+ *
+ * Will be replaced by created constructor.
*/
@Experimental()
- void created() {}
+ @deprecated
+ void createdCallback() {}
/**
* Called by the DOM when this element has been inserted into the live
@@ -9165,6 +9287,11 @@
@Experimental()
void leftView() {}
+ /**
+ * Called by the DOM whenever an attribute on this has been changed.
+ */
+ void attributeChanged(String name, String oldValue, String newValue) {}
+
// Hooks to support custom WebComponents.
@Creates('Null') // Set from Dart code; does not instantiate a native type.
@@ -10658,6 +10785,12 @@
@DomName('HTMLEmbedElement.HTMLEmbedElement')
@DocsEditable()
factory EmbedElement() => document.createElement("embed");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ EmbedElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('embed');
@@ -11259,6 +11392,9 @@
@DomName('EventTarget')
class EventTarget extends Interceptor native "EventTarget" {
+ // Custom element created callback.
+ EventTarget._created();
+
/**
* This is an ease-of-use accessor for event streams which should only be
* used when an explicit accessor is not available.
@@ -11297,6 +11433,12 @@
@DomName('HTMLFieldSetElement.HTMLFieldSetElement')
@DocsEditable()
factory FieldSetElement() => document.createElement("fieldset");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FieldSetElement.created() : super.created();
@DomName('HTMLFieldSetElement.disabled')
@DocsEditable()
@@ -11991,6 +12133,12 @@
@DomName('HTMLFormElement.HTMLFormElement')
@DocsEditable()
factory FormElement() => document.createElement("form");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FormElement.created() : super.created();
@DomName('HTMLFormElement.acceptCharset')
@DocsEditable()
@@ -12251,6 +12399,12 @@
@DomName('HTMLHRElement.HTMLHRElement')
@DocsEditable()
factory HRElement() => document.createElement("hr");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HRElement.created() : super.created();
}
// 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
@@ -12307,6 +12461,12 @@
@DomName('HTMLHeadElement.HTMLHeadElement')
@DocsEditable()
factory HeadElement() => document.createElement("head");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HeadElement.created() : super.created();
}
// 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
@@ -12342,6 +12502,12 @@
@DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable()
factory HeadingElement.h6() => document.createElement("h6");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HeadingElement.created() : super.created();
}
// 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
@@ -12900,6 +13066,12 @@
@DomName('HTMLHtmlElement.HTMLHtmlElement')
@DocsEditable()
factory HtmlHtmlElement() => document.createElement("html");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HtmlHtmlElement.created() : super.created();
}
// 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
@@ -13001,7 +13173,7 @@
}
/**
- * Creates a URL request for the specified [url].
+ * Creates and sends a URL request for the specified [url].
*
* By default `request` will perform an HTTP GET request, but a different
* method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
@@ -13485,6 +13657,12 @@
@DomName('HTMLIFrameElement.HTMLIFrameElement')
@DocsEditable()
factory IFrameElement() => document.createElement("iframe");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ IFrameElement.created() : super.created();
@DomName('HTMLIFrameElement.contentWindow')
@DocsEditable()
@@ -13584,6 +13762,12 @@
if (height != null) e.height = height;
return e;
}
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ImageElement.created() : super.created();
@DomName('HTMLImageElement.alt')
@DocsEditable()
@@ -13697,6 +13881,12 @@
@Experimental()
// http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#extending_html_elements
static const EventStreamProvider<Event> speechChangeEvent = const EventStreamProvider<Event>('webkitSpeechChange');
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ InputElement.created() : super.created();
@DomName('HTMLInputElement.accept')
@DocsEditable()
@@ -14718,6 +14908,12 @@
@DomName('HTMLKeygenElement.HTMLKeygenElement')
@DocsEditable()
factory KeygenElement() => document.createElement("keygen");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ KeygenElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('keygen') && (new Element.tag('keygen') is KeygenElement);
@@ -14791,6 +14987,12 @@
@DomName('HTMLLIElement.HTMLLIElement')
@DocsEditable()
factory LIElement() => document.createElement("li");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LIElement.created() : super.created();
@DomName('HTMLLIElement.type')
@DocsEditable()
@@ -14816,6 +15018,12 @@
@DomName('HTMLLabelElement.HTMLLabelElement')
@DocsEditable()
factory LabelElement() => document.createElement("label");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LabelElement.created() : super.created();
@DomName('HTMLLabelElement.control')
@DocsEditable()
@@ -14843,6 +15051,12 @@
@DomName('HTMLLegendElement.HTMLLegendElement')
@DocsEditable()
factory LegendElement() => document.createElement("legend");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LegendElement.created() : super.created();
@DomName('HTMLLegendElement.form')
@DocsEditable()
@@ -14862,6 +15076,12 @@
@DomName('HTMLLinkElement.HTMLLinkElement')
@DocsEditable()
factory LinkElement() => document.createElement("link");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LinkElement.created() : super.created();
@DomName('HTMLLinkElement.disabled')
@DocsEditable()
@@ -15009,6 +15229,12 @@
@DomName('HTMLMapElement.HTMLMapElement')
@DocsEditable()
factory MapElement() => document.createElement("map");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MapElement.created() : super.created();
@DomName('HTMLMapElement.areas')
@DocsEditable()
@@ -15223,6 +15449,12 @@
@Experimental()
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MediaElement.created() : super.created();
@DomName('HTMLMediaElement.HAVE_CURRENT_DATA')
@DocsEditable()
@@ -16226,6 +16458,12 @@
@DomName('HTMLMenuElement.HTMLMenuElement')
@DocsEditable()
factory MenuElement() => document.createElement("menu");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MenuElement.created() : super.created();
}
// 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
@@ -16373,6 +16611,12 @@
@DomName('HTMLMetaElement.HTMLMetaElement')
@DocsEditable()
factory MetaElement() => document.createElement("meta");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MetaElement.created() : super.created();
@DomName('HTMLMetaElement.content')
@DocsEditable()
@@ -16439,6 +16683,12 @@
@DomName('HTMLMeterElement.HTMLMeterElement')
@DocsEditable()
factory MeterElement() => document.createElement("meter");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MeterElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('meter');
@@ -16750,6 +17000,12 @@
class ModElement extends HtmlElement native "HTMLModElement" {
// To suppress missing implicit constructor warnings.
factory ModElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ModElement.created() : super.created();
@DomName('HTMLModElement.cite')
@DocsEditable()
@@ -17708,6 +17964,10 @@
@DomName('Node')
class Node extends EventTarget native "Node" {
+
+ // Custom element created callback.
+ Node._created() : super._created();
+
List<Node> get nodes {
return new _ChildNodeListLazy(this);
}
@@ -18387,6 +18647,12 @@
@DomName('HTMLOListElement.HTMLOListElement')
@DocsEditable()
factory OListElement() => document.createElement("ol");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ OListElement.created() : super.created();
@DomName('HTMLOListElement.reversed')
@DocsEditable()
@@ -18418,6 +18684,12 @@
@DomName('HTMLObjectElement.HTMLObjectElement')
@DocsEditable()
factory ObjectElement() => document.createElement("object");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ObjectElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('object');
@@ -18498,6 +18770,12 @@
@DomName('HTMLOptGroupElement.HTMLOptGroupElement')
@DocsEditable()
factory OptGroupElement() => document.createElement("optgroup");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ OptGroupElement.created() : super.created();
@DomName('HTMLOptGroupElement.disabled')
@DocsEditable()
@@ -18507,20 +18785,21 @@
@DocsEditable()
String label;
}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// 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.
-@DocsEditable()
@DomName('HTMLOptionElement')
class OptionElement extends HtmlElement native "HTMLOptionElement" {
- // To suppress missing implicit constructor warnings.
- factory OptionElement._() { throw new UnsupportedError("Not supported"); }
+ factory OptionElement({String data, String value, bool defaultSelected,
+ bool selected}) {
+ return new OptionElement._(data, value, defaultSelected, selected);
+ }
@DomName('HTMLOptionElement.HTMLOptionElement')
@DocsEditable()
- factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
+ factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
if (selected != null) {
return OptionElement._create_1(data, value, defaultSelected, selected);
}
@@ -18540,6 +18819,12 @@
static OptionElement _create_3(data, value) => JS('OptionElement', 'new Option(#,#)', data, value);
static OptionElement _create_4(data) => JS('OptionElement', 'new Option(#)', data);
static OptionElement _create_5() => JS('OptionElement', 'new Option()');
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ OptionElement.created() : super.created();
@DomName('HTMLOptionElement.defaultSelected')
@DocsEditable()
@@ -18568,6 +18853,7 @@
@DomName('HTMLOptionElement.value')
@DocsEditable()
String value;
+
}
// 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
@@ -18586,6 +18872,12 @@
@DomName('HTMLOutputElement.HTMLOutputElement')
@DocsEditable()
factory OutputElement() => document.createElement("output");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ OutputElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('output');
@@ -18708,6 +19000,12 @@
@DomName('HTMLParagraphElement.HTMLParagraphElement')
@DocsEditable()
factory ParagraphElement() => document.createElement("p");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ParagraphElement.created() : super.created();
}
// 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
@@ -18724,6 +19022,12 @@
@DomName('HTMLParamElement.HTMLParamElement')
@DocsEditable()
factory ParamElement() => document.createElement("param");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ParamElement.created() : super.created();
@DomName('HTMLParamElement.name')
@DocsEditable()
@@ -19366,6 +19670,12 @@
@DomName('HTMLPreElement.HTMLPreElement')
@DocsEditable()
factory PreElement() => document.createElement("pre");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PreElement.created() : super.created();
@DomName('HTMLPreElement.wrap')
@DocsEditable()
@@ -19411,6 +19721,12 @@
@DomName('HTMLProgressElement.HTMLProgressElement')
@DocsEditable()
factory ProgressElement() => document.createElement("progress");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ProgressElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('progress');
@@ -19536,6 +19852,12 @@
@DomName('HTMLQuoteElement.HTMLQuoteElement')
@DocsEditable()
factory QuoteElement() => document.createElement("q");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ QuoteElement.created() : super.created();
@DomName('HTMLQuoteElement.cite')
@DocsEditable()
@@ -20558,6 +20880,12 @@
@DomName('HTMLScriptElement.HTMLScriptElement')
@DocsEditable()
factory ScriptElement() => document.createElement("script");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ScriptElement.created() : super.created();
@DomName('HTMLScriptElement.async')
@DocsEditable()
@@ -20745,6 +21073,12 @@
@DomName('HTMLSelectElement.HTMLSelectElement')
@DocsEditable()
factory SelectElement() => document.createElement("select");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SelectElement.created() : super.created();
@DomName('HTMLSelectElement.autofocus')
@DocsEditable()
@@ -20988,6 +21322,12 @@
@DomName('HTMLShadowElement.HTMLShadowElement')
@DocsEditable()
factory ShadowElement() => document.createElement("shadow");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ShadowElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('shadow');
@@ -21231,6 +21571,12 @@
@DomName('HTMLSourceElement.HTMLSourceElement')
@DocsEditable()
factory SourceElement() => document.createElement("source");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SourceElement.created() : super.created();
@DomName('HTMLSourceElement.media')
@DocsEditable()
@@ -21288,6 +21634,12 @@
@DomName('HTMLSpanElement.HTMLSpanElement')
@DocsEditable()
factory SpanElement() => document.createElement("span");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SpanElement.created() : super.created();
}
// 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
@@ -22187,6 +22539,12 @@
@DomName('HTMLStyleElement.HTMLStyleElement')
@DocsEditable()
factory StyleElement() => document.createElement("style");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ StyleElement.created() : super.created();
@DomName('HTMLStyleElement.disabled')
@DocsEditable()
@@ -22278,6 +22636,12 @@
@DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
@DocsEditable()
factory TableCaptionElement() => document.createElement("caption");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableCaptionElement.created() : super.created();
}
// 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
@@ -22293,6 +22657,12 @@
@DomName('HTMLTableCellElement.HTMLTableCellElement')
@DocsEditable()
factory TableCellElement() => document.createElement("td");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableCellElement.created() : super.created();
@DomName('HTMLTableCellElement.cellIndex')
@DocsEditable()
@@ -22324,6 +22694,12 @@
@DomName('HTMLTableColElement.HTMLTableColElement')
@DocsEditable()
factory TableColElement() => document.createElement("col");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableColElement.created() : super.created();
@DomName('HTMLTableColElement.span')
@DocsEditable()
@@ -22390,6 +22766,12 @@
@DomName('HTMLTableElement.HTMLTableElement')
@DocsEditable()
factory TableElement() => document.createElement("table");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableElement.created() : super.created();
@DomName('HTMLTableElement.border')
@DocsEditable()
@@ -22495,6 +22877,12 @@
@DomName('HTMLTableRowElement.HTMLTableRowElement')
@DocsEditable()
factory TableRowElement() => document.createElement("tr");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableRowElement.created() : super.created();
@JSName('cells')
@DomName('HTMLTableRowElement.cells')
@@ -22553,6 +22941,12 @@
// To suppress missing implicit constructor warnings.
factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableSectionElement.created() : super.created();
@JSName('rows')
@DomName('HTMLTableSectionElement.rows')
@@ -22669,6 +23063,12 @@
@DomName('HTMLTemplateElement.HTMLTemplateElement')
@DocsEditable()
factory TemplateElement() => document.createElement("template");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TemplateElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('template');
@@ -22942,6 +23342,12 @@
@DomName('HTMLTextAreaElement.HTMLTextAreaElement')
@DocsEditable()
factory TextAreaElement() => document.createElement("textarea");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextAreaElement.created() : super.created();
@DomName('HTMLTextAreaElement.autofocus')
@DocsEditable()
@@ -23447,6 +23853,12 @@
@DomName('HTMLTitleElement.HTMLTitleElement')
@DocsEditable()
factory TitleElement() => document.createElement("title");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TitleElement.created() : super.created();
}
// 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
@@ -23713,6 +24125,12 @@
@DomName('HTMLTrackElement.HTMLTrackElement')
@DocsEditable()
factory TrackElement() => document.createElement("track");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TrackElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => Element.isTagSupported('track');
@@ -23990,6 +24408,12 @@
@DomName('HTMLUListElement.HTMLUListElement')
@DocsEditable()
factory UListElement() => document.createElement("ul");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ UListElement.created() : super.created();
}
// 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
@@ -24001,6 +24425,12 @@
class UnknownElement extends HtmlElement native "HTMLUnknownElement" {
// To suppress missing implicit constructor warnings.
factory UnknownElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ UnknownElement.created() : super.created();
}
// 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
@@ -24096,6 +24526,12 @@
@DomName('HTMLVideoElement.HTMLVideoElement')
@DocsEditable()
factory VideoElement() => document.createElement("video");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ VideoElement.created() : super.created();
@DomName('HTMLVideoElement.height')
@DocsEditable()
@@ -27068,6 +27504,12 @@
abstract class _HTMLAppletElement extends HtmlElement native "HTMLAppletElement" {
// To suppress missing implicit constructor warnings.
factory _HTMLAppletElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLAppletElement.created() : super.created();
}
// 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
@@ -27081,6 +27523,12 @@
abstract class _HTMLBaseFontElement extends HtmlElement native "HTMLBaseFontElement" {
// To suppress missing implicit constructor warnings.
factory _HTMLBaseFontElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLBaseFontElement.created() : super.created();
}
// 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
@@ -27094,6 +27542,12 @@
abstract class _HTMLDirectoryElement extends HtmlElement native "HTMLDirectoryElement" {
// To suppress missing implicit constructor warnings.
factory _HTMLDirectoryElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLDirectoryElement.created() : super.created();
}
// 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
@@ -27107,6 +27561,12 @@
abstract class _HTMLFontElement extends HtmlElement native "HTMLFontElement" {
// To suppress missing implicit constructor warnings.
factory _HTMLFontElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLFontElement.created() : super.created();
}
// 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
@@ -27120,6 +27580,12 @@
abstract class _HTMLFrameElement extends HtmlElement native "HTMLFrameElement" {
// To suppress missing implicit constructor warnings.
factory _HTMLFrameElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLFrameElement.created() : super.created();
}
// 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
@@ -27133,6 +27599,12 @@
abstract class _HTMLFrameSetElement extends HtmlElement native "HTMLFrameSetElement" {
// To suppress missing implicit constructor warnings.
factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLFrameSetElement.created() : super.created();
}
// 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
@@ -27146,6 +27618,12 @@
abstract class _HTMLMarqueeElement extends HtmlElement native "HTMLMarqueeElement" {
// To suppress missing implicit constructor warnings.
factory _HTMLMarqueeElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLMarqueeElement.created() : super.created();
}
// 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
@@ -32060,7 +32538,7 @@
_callCreated(receiver) {
- return receiver.created();
+ return receiver.createdCallback();
}
_callEnteredView(receiver) {
@@ -32070,6 +32548,9 @@
_callLeftView(receiver) {
return receiver.leftView();
}
+ _callAttributeChanged(receiver, name, oldValue, newValue) {
+ return receiver.attributeChanged(name, oldValue, newValue);
+}
_makeCallbackMethod(callback) {
return JS('',
@@ -32081,6 +32562,16 @@
convertDartClosureToJS(callback, 1));
}
+_makeCallbackMethod3(callback) {
+ return JS('',
+ '''((function(invokeCallback) {
+ return function(arg1, arg2, arg3) {
+ return invokeCallback(this, arg1, arg2, arg3);
+ };
+ })(#))''',
+ convertDartClosureToJS(callback, 4));
+}
+
const _typeNameToTag = const {
'HTMLAnchorElement': 'a',
'HTMLAudioElement': 'audio',
@@ -32146,6 +32637,8 @@
JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
JS('void', '#.leftViewCallback = #', properties,
JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
+ JS('void', '#.attributeChangedCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));
// TODO(blois): Bug 13220- remove once transition is complete
JS('void', '#.enteredDocumentCallback = #', properties,
@@ -32172,6 +32665,11 @@
JS('void', '#.register(#, #)', document, tag, options);
}
+
+//// Called by Element.created to do validation & initialization.
+void _initializeCustomElement(Element e) {
+ // TODO(blois): Add validation that this is only in response to an upgrade.
+}
// 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.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 106ac6c..c9879ea 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -208,6 +208,12 @@
if (href != null) e.href = href;
return e;
}
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnchorElement.created() : super.created();
@DomName('HTMLAnchorElement.download')
@DocsEditable()
@@ -538,6 +544,12 @@
@DomName('HTMLAreaElement.HTMLAreaElement')
@DocsEditable()
factory AreaElement() => document.createElement("area");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AreaElement.created() : super.created();
@DomName('HTMLAreaElement.alt')
@DocsEditable()
@@ -641,6 +653,12 @@
@DocsEditable()
static AudioElement _create_1(src) native "HTMLAudioElement__create_1constructorCallback";
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AudioElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -679,6 +697,12 @@
@DomName('HTMLBRElement.HTMLBRElement')
@DocsEditable()
factory BRElement() => document.createElement("br");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ BRElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -715,6 +739,12 @@
@DomName('HTMLBaseElement.HTMLBaseElement')
@DocsEditable()
factory BaseElement() => document.createElement("base");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ BaseElement.created() : super.created();
@DomName('HTMLBaseElement.href')
@DocsEditable()
@@ -862,6 +892,12 @@
@DomName('HTMLBodyElement.HTMLBodyElement')
@DocsEditable()
factory BodyElement() => document.createElement("body");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ BodyElement.created() : super.created();
@DomName('HTMLBodyElement.onblur')
@DocsEditable()
@@ -928,6 +964,12 @@
@DomName('HTMLButtonElement.HTMLButtonElement')
@DocsEditable()
factory ButtonElement() => document.createElement("button");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ButtonElement.created() : super.created();
@DomName('HTMLButtonElement.autofocus')
@DocsEditable()
@@ -1103,6 +1145,12 @@
if (height != null) e.height = height;
return e;
}
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ CanvasElement.created() : super.created();
/// The height of this canvas element in CSS pixels.
@DomName('HTMLCanvasElement.height')
@@ -2370,6 +2418,12 @@
@DomName('HTMLContentElement.HTMLContentElement')
@DocsEditable()
factory ContentElement() => document.createElement("content");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ContentElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -6885,6 +6939,12 @@
@DomName('HTMLDListElement.HTMLDListElement')
@DocsEditable()
factory DListElement() => document.createElement("dl");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6907,6 +6967,12 @@
@DomName('HTMLDataListElement.HTMLDataListElement')
@DocsEditable()
factory DataListElement() => document.createElement("datalist");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DataListElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -7146,6 +7212,12 @@
@DomName('HTMLDetailsElement.HTMLDetailsElement')
@DocsEditable()
factory DetailsElement() => document.createElement("details");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DetailsElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -7298,6 +7370,12 @@
class DialogElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory DialogElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DialogElement.created() : super.created();
@DomName('HTMLDialogElement.open')
@DocsEditable()
@@ -7485,6 +7563,12 @@
@DomName('HTMLDivElement.HTMLDivElement')
@DocsEditable()
factory DivElement() => document.createElement("div");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DivElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -8144,7 +8228,6 @@
@Experimental()
Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);
-
/**
* Finds all descendant elements of this document that match the specified
* group of selectors.
@@ -9373,6 +9456,30 @@
}
/**
+ * Custom element creation constructor.
+ *
+ * This constructor is used by the DOM when a custom element has been
+ * created. It can only be invoked by subclasses of Element from
+ * that classes created constructor.
+ *
+ * class CustomElement extends Element {
+ * factory CustomElement() => new Element.tag('x-custom');
+ *
+ * CustomElement.created() : super.created() {
+ * // Perform any element initialization.
+ * }
+ * }
+ * document.register('x-custom', CustomElement);
+ */
+ Element.created() : super._created() {
+ // Validate that this is a custom element & perform any additional
+ // initialization.
+ _initializeCustomElement(this);
+
+ createdCallback();
+ }
+
+ /**
* Creates the HTML element specified by the tag name.
*
* This is similar to [Document.createElement].
@@ -9715,9 +9822,12 @@
/**
* Called by the DOM when this element has been instantiated.
+ *
+ * Will be replaced by created constructor.
*/
@Experimental()
- void created() {}
+ @deprecated
+ void createdCallback() {}
/**
* Called by the DOM when this element has been inserted into the live
@@ -9733,6 +9843,11 @@
@Experimental()
void leftView() {}
+ /**
+ * Called by the DOM whenever an attribute on this has been changed.
+ */
+ void attributeChanged(String name, String oldValue, String newValue) {}
+
// Hooks to support custom WebComponents.
Element _xtag;
@@ -11056,6 +11171,12 @@
@DomName('HTMLEmbedElement.HTMLEmbedElement')
@DocsEditable()
factory EmbedElement() => document.createElement("embed");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ EmbedElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -11687,6 +11808,9 @@
@DomName('EventTarget')
class EventTarget extends NativeFieldWrapperClass1 {
+ // Custom element created callback.
+ EventTarget._created();
+
/**
* This is an ease-of-use accessor for event streams which should only be
* used when an explicit accessor is not available.
@@ -11725,6 +11849,12 @@
@DomName('HTMLFieldSetElement.HTMLFieldSetElement')
@DocsEditable()
factory FieldSetElement() => document.createElement("fieldset");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FieldSetElement.created() : super.created();
@DomName('HTMLFieldSetElement.disabled')
@DocsEditable()
@@ -12477,6 +12607,12 @@
@DomName('HTMLFormElement.HTMLFormElement')
@DocsEditable()
factory FormElement() => document.createElement("form");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FormElement.created() : super.created();
@DomName('HTMLFormElement.acceptCharset')
@DocsEditable()
@@ -12763,6 +12899,12 @@
@DomName('HTMLHRElement.HTMLHRElement')
@DocsEditable()
factory HRElement() => document.createElement("hr");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HRElement.created() : super.created();
}
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
@@ -12819,6 +12961,12 @@
@DomName('HTMLHeadElement.HTMLHeadElement')
@DocsEditable()
factory HeadElement() => document.createElement("head");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HeadElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -12857,6 +13005,12 @@
@DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable()
factory HeadingElement.h6() => document.createElement("h6");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HeadingElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -13395,6 +13549,12 @@
class HtmlElement extends Element {
// To suppress missing implicit constructor warnings.
factory HtmlElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HtmlElement.created() : super.created();
@DomName('HTMLElement.contentEditable')
@DocsEditable()
@@ -13566,6 +13726,12 @@
@DomName('HTMLHtmlElement.HTMLHtmlElement')
@DocsEditable()
factory HtmlHtmlElement() => document.createElement("html");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HtmlHtmlElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -13671,7 +13837,7 @@
}
/**
- * Creates a URL request for the specified [url].
+ * Creates and sends a URL request for the specified [url].
*
* By default `request` will perform an HTTP GET request, but a different
* method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
@@ -14140,6 +14306,12 @@
@DomName('HTMLIFrameElement.HTMLIFrameElement')
@DocsEditable()
factory IFrameElement() => document.createElement("iframe");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ IFrameElement.created() : super.created();
@DomName('HTMLIFrameElement.contentWindow')
@DocsEditable()
@@ -14273,6 +14445,12 @@
if (height != null) e.height = height;
return e;
}
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ImageElement.created() : super.created();
@DomName('HTMLImageElement.alt')
@DocsEditable()
@@ -14424,6 +14602,12 @@
@Experimental()
// http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#extending_html_elements
static const EventStreamProvider<Event> speechChangeEvent = const EventStreamProvider<Event>('webkitSpeechChange');
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ InputElement.created() : super.created();
@DomName('HTMLInputElement.accept')
@DocsEditable()
@@ -15620,6 +15804,12 @@
@DomName('HTMLKeygenElement.HTMLKeygenElement')
@DocsEditable()
factory KeygenElement() => document.createElement("keygen");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ KeygenElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -15714,6 +15904,12 @@
@DomName('HTMLLIElement.HTMLLIElement')
@DocsEditable()
factory LIElement() => document.createElement("li");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LIElement.created() : super.created();
@DomName('HTMLLIElement.type')
@DocsEditable()
@@ -15752,6 +15948,12 @@
@DomName('HTMLLabelElement.HTMLLabelElement')
@DocsEditable()
factory LabelElement() => document.createElement("label");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LabelElement.created() : super.created();
@DomName('HTMLLabelElement.control')
@DocsEditable()
@@ -15786,6 +15988,12 @@
@DomName('HTMLLegendElement.HTMLLegendElement')
@DocsEditable()
factory LegendElement() => document.createElement("legend");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LegendElement.created() : super.created();
@DomName('HTMLLegendElement.form')
@DocsEditable()
@@ -15808,6 +16016,12 @@
@DomName('HTMLLinkElement.HTMLLinkElement')
@DocsEditable()
factory LinkElement() => document.createElement("link");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LinkElement.created() : super.created();
@DomName('HTMLLinkElement.disabled')
@DocsEditable()
@@ -16015,6 +16229,12 @@
@DomName('HTMLMapElement.HTMLMapElement')
@DocsEditable()
factory MapElement() => document.createElement("map");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MapElement.created() : super.created();
@DomName('HTMLMapElement.areas')
@DocsEditable()
@@ -16273,6 +16493,12 @@
@Experimental()
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MediaElement.created() : super.created();
@DomName('HTMLMediaElement.HAVE_CURRENT_DATA')
@DocsEditable()
@@ -17474,6 +17700,12 @@
@DomName('HTMLMenuElement.HTMLMenuElement')
@DocsEditable()
factory MenuElement() => document.createElement("menu");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MenuElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -17611,6 +17843,12 @@
@DomName('HTMLMetaElement.HTMLMetaElement')
@DocsEditable()
factory MetaElement() => document.createElement("meta");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MetaElement.created() : super.created();
@DomName('HTMLMetaElement.content')
@DocsEditable()
@@ -17690,6 +17928,12 @@
@DomName('HTMLMeterElement.HTMLMeterElement')
@DocsEditable()
factory MeterElement() => document.createElement("meter");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MeterElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -18087,6 +18331,12 @@
class ModElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory ModElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ModElement.created() : super.created();
@DomName('HTMLModElement.cite')
@DocsEditable()
@@ -19024,6 +19274,10 @@
@DomName('Node')
class Node extends EventTarget {
+
+ // Custom element created callback.
+ Node._created() : super._created();
+
List<Node> get nodes {
return new _ChildNodeListLazy(this);
}
@@ -19736,6 +19990,12 @@
@DomName('HTMLOListElement.HTMLOListElement')
@DocsEditable()
factory OListElement() => document.createElement("ol");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ OListElement.created() : super.created();
@DomName('HTMLOListElement.reversed')
@DocsEditable()
@@ -19782,6 +20042,12 @@
@DomName('HTMLObjectElement.HTMLObjectElement')
@DocsEditable()
factory ObjectElement() => document.createElement("object");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ObjectElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -19895,6 +20161,12 @@
@DomName('HTMLOptGroupElement.HTMLOptGroupElement')
@DocsEditable()
factory OptGroupElement() => document.createElement("optgroup");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ OptGroupElement.created() : super.created();
@DomName('HTMLOptGroupElement.disabled')
@DocsEditable()
@@ -19913,27 +20185,32 @@
void set label(String value) native "HTMLOptGroupElement_label_Setter";
}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// 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.
-// WARNING: Do not edit - generated code.
-
-@DocsEditable()
@DomName('HTMLOptionElement')
class OptionElement extends HtmlElement {
- // To suppress missing implicit constructor warnings.
- factory OptionElement._() { throw new UnsupportedError("Not supported"); }
+ factory OptionElement({String data, String value, bool defaultSelected,
+ bool selected}) {
+ return new OptionElement._(data, value, defaultSelected, selected);
+ }
@DomName('HTMLOptionElement.HTMLOptionElement')
@DocsEditable()
- factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
+ factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
return OptionElement._create_1(data, value, defaultSelected, selected);
}
@DocsEditable()
static OptionElement _create_1(data, value, defaultSelected, selected) native "HTMLOptionElement__create_1constructorCallback";
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ OptionElement.created() : super.created();
@DomName('HTMLOptionElement.defaultSelected')
@DocsEditable()
@@ -20003,6 +20280,12 @@
@DomName('HTMLOutputElement.HTMLOutputElement')
@DocsEditable()
factory OutputElement() => document.createElement("output");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ OutputElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -20144,6 +20427,12 @@
@DomName('HTMLParagraphElement.HTMLParagraphElement')
@DocsEditable()
factory ParagraphElement() => document.createElement("p");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ParagraphElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -20163,6 +20452,12 @@
@DomName('HTMLParamElement.HTMLParamElement')
@DocsEditable()
factory ParamElement() => document.createElement("param");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ParamElement.created() : super.created();
@DomName('HTMLParamElement.name')
@DocsEditable()
@@ -20881,6 +21176,12 @@
@DomName('HTMLPreElement.HTMLPreElement')
@DocsEditable()
factory PreElement() => document.createElement("pre");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PreElement.created() : super.created();
@DomName('HTMLPreElement.wrap')
@DocsEditable()
@@ -20937,6 +21238,12 @@
@DomName('HTMLProgressElement.HTMLProgressElement')
@DocsEditable()
factory ProgressElement() => document.createElement("progress");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ProgressElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -21080,6 +21387,12 @@
@DomName('HTMLQuoteElement.HTMLQuoteElement')
@DocsEditable()
factory QuoteElement() => document.createElement("q");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ QuoteElement.created() : super.created();
@DomName('HTMLQuoteElement.cite')
@DocsEditable()
@@ -22100,6 +22413,12 @@
@DomName('HTMLScriptElement.HTMLScriptElement')
@DocsEditable()
factory ScriptElement() => document.createElement("script");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ScriptElement.created() : super.created();
@DomName('HTMLScriptElement.async')
@DocsEditable()
@@ -22334,6 +22653,12 @@
@DomName('HTMLSelectElement.HTMLSelectElement')
@DocsEditable()
factory SelectElement() => document.createElement("select");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SelectElement.created() : super.created();
@DomName('HTMLSelectElement.autofocus')
@DocsEditable()
@@ -22616,6 +22941,12 @@
@DomName('HTMLShadowElement.HTMLShadowElement')
@DocsEditable()
factory ShadowElement() => document.createElement("shadow");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ShadowElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -22921,6 +23252,12 @@
@DomName('HTMLSourceElement.HTMLSourceElement')
@DocsEditable()
factory SourceElement() => document.createElement("source");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SourceElement.created() : super.created();
@DomName('HTMLSourceElement.media')
@DocsEditable()
@@ -22996,6 +23333,12 @@
@DomName('HTMLSpanElement.HTMLSpanElement')
@DocsEditable()
factory SpanElement() => document.createElement("span");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SpanElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -24059,6 +24402,12 @@
@DomName('HTMLStyleElement.HTMLStyleElement')
@DocsEditable()
factory StyleElement() => document.createElement("style");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ StyleElement.created() : super.created();
@DomName('HTMLStyleElement.disabled')
@DocsEditable()
@@ -24179,6 +24528,12 @@
@DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
@DocsEditable()
factory TableCaptionElement() => document.createElement("caption");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableCaptionElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -24197,6 +24552,12 @@
@DomName('HTMLTableCellElement.HTMLTableCellElement')
@DocsEditable()
factory TableCellElement() => document.createElement("td");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableCellElement.created() : super.created();
@DomName('HTMLTableCellElement.cellIndex')
@DocsEditable()
@@ -24243,6 +24604,12 @@
@DomName('HTMLTableColElement.HTMLTableColElement')
@DocsEditable()
factory TableColElement() => document.createElement("col");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableColElement.created() : super.created();
@DomName('HTMLTableColElement.span')
@DocsEditable()
@@ -24287,6 +24654,12 @@
@DomName('HTMLTableElement.HTMLTableElement')
@DocsEditable()
factory TableElement() => document.createElement("table");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableElement.created() : super.created();
@DomName('HTMLTableElement.border')
@DocsEditable()
@@ -24394,6 +24767,12 @@
@DomName('HTMLTableRowElement.HTMLTableRowElement')
@DocsEditable()
factory TableRowElement() => document.createElement("tr");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableRowElement.created() : super.created();
@DomName('HTMLTableRowElement.cells')
@DocsEditable()
@@ -24437,6 +24816,12 @@
// To suppress missing implicit constructor warnings.
factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TableSectionElement.created() : super.created();
@DomName('HTMLTableSectionElement.rows')
@DocsEditable()
@@ -24551,6 +24936,12 @@
@DomName('HTMLTemplateElement.HTMLTemplateElement')
@DocsEditable()
factory TemplateElement() => document.createElement("template");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TemplateElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -24823,6 +25214,12 @@
@DomName('HTMLTextAreaElement.HTMLTextAreaElement')
@DocsEditable()
factory TextAreaElement() => document.createElement("textarea");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextAreaElement.created() : super.created();
@DomName('HTMLTextAreaElement.autofocus')
@DocsEditable()
@@ -25530,6 +25927,12 @@
@DomName('HTMLTitleElement.HTMLTitleElement')
@DocsEditable()
factory TitleElement() => document.createElement("title");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TitleElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -25783,6 +26186,12 @@
@DomName('HTMLTrackElement.HTMLTrackElement')
@DocsEditable()
factory TrackElement() => document.createElement("track");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TrackElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -26078,6 +26487,12 @@
@DomName('HTMLUListElement.HTMLUListElement')
@DocsEditable()
factory UListElement() => document.createElement("ul");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ UListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -26092,6 +26507,12 @@
class UnknownElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory UnknownElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ UnknownElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -26114,13 +26535,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 MediaSource || blob_OR_source_OR_stream == null)) {
+ if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
return _createObjectURL_2(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 MediaSource || blob_OR_source_OR_stream == null)) {
return _createObjectURL_3(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 _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
return _createObjectURL_4(blob_OR_source_OR_stream);
}
throw new ArgumentError("Incorrect number or type of arguments");
@@ -26216,6 +26637,12 @@
@DomName('HTMLVideoElement.HTMLVideoElement')
@DocsEditable()
factory VideoElement() => document.createElement("video");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ VideoElement.created() : super.created();
@DomName('HTMLVideoElement.height')
@DocsEditable()
@@ -29094,6 +29521,12 @@
abstract class _HTMLAppletElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory _HTMLAppletElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLAppletElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -29110,6 +29543,12 @@
abstract class _HTMLBaseFontElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory _HTMLBaseFontElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLBaseFontElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -29126,6 +29565,12 @@
abstract class _HTMLDirectoryElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory _HTMLDirectoryElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLDirectoryElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -29142,6 +29587,12 @@
abstract class _HTMLFontElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory _HTMLFontElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLFontElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -29158,6 +29609,12 @@
abstract class _HTMLFrameElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory _HTMLFrameElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLFrameElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -29174,6 +29631,12 @@
abstract class _HTMLFrameSetElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLFrameSetElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -29190,6 +29653,12 @@
abstract class _HTMLMarqueeElement extends HtmlElement {
// To suppress missing implicit constructor warnings.
factory _HTMLMarqueeElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _HTMLMarqueeElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -34446,33 +34915,6 @@
}
}
}
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-// testRunner implementation.
-// FIXME: provide a separate lib for testRunner.
-
-var _testRunner;
-
-TestRunner get testRunner {
- if (_testRunner == null)
- _testRunner = new TestRunner._(_NPObject.retrieve("testRunner"));
- return _testRunner;
-}
-
-class TestRunner {
- final _NPObject _npObject;
-
- TestRunner._(this._npObject);
-
- display() => _npObject.invoke('display');
- dumpAsText() => _npObject.invoke('dumpAsText');
- notifyDone() => _npObject.invoke('notifyDone');
- setCanOpenWindows() => _npObject.invoke('setCanOpenWindows');
- waitUntilDone() => _npObject.invoke('waitUntilDone');
-}
// 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.
@@ -34763,6 +35205,10 @@
if (_isBuiltinType(cls)) {
throw new UnsupportedError("Invalid custom element from $libName.");
}
+ var className = MirrorSystem.getName(cls.simpleName);
+ if (!cls.constructors.containsKey(new Symbol('$className.created'))) {
+ throw new UnsupportedError('Class is missing constructor $className.created');
+ }
_register(document, tag, type, extendsTagName);
}
@@ -34770,13 +35216,8 @@
String extendsTagName) native "Utils_register";
static Element createElement(Document document, String tagName) native "Utils_createElement";
-}
-class _NPObject extends NativeFieldWrapperClass1 {
- _NPObject.internal();
- static _NPObject retrieve(String key) native "NPObject_retrieve";
- property(String propertyName) native "NPObject_property";
- invoke(String methodName, [List args = null]) native "NPObject_invoke";
+ static void initializeCustomElement(HtmlElement element) native "Utils_initializeCustomElement";
}
class _DOMWindowCrossFrame extends NativeFieldWrapperClass1 implements
@@ -34991,3 +35432,7 @@
get _pureIsolateTimerFactoryClosure =>
((int milliSeconds, void callback(Timer time), bool repeating) =>
new _PureIsolateTimer(milliSeconds, callback, repeating));
+
+void _initializeCustomElement(Element e) {
+ _Utils.initializeCustomElement(e);
+}
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 671064c..6aa18f8 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -68,25 +68,59 @@
void createSync({bool recursive: false});
/**
- * Creates a temporary directory with a name based on the current
- * path. The path is used as a template, and additional
- * characters are appended to it to make a unique temporary
- * directory name. If the path is the empty string, a default
- * system temp directory and name are used for the template.
+ * Creates a temporary directory in this directory. Additional random
+ * characters are appended to [template] to produce a unique directory
+ * name.
+ *
+ * Returns a [:Future<Directory>:] that completes with the newly
+ * created temporary directory.
+ *
+ * Deprecated behavior, to be removed Oct 18, 2013: If the path is the
+ * empty string, the directory is created in the default system temp
+ * directory. This capability has been moved to the static function
+ * [createSystemTemp].
+ */
+ Future<Directory> createTemp([String template]);
+
+ /**
+ * Synchronously creates a temporary directory in this directory.
+ * Additional random characters are appended to [template] to produce
+ * a unique directory name.
+ *
+ * Returns the newly created temporary directory.
+ *
+ * Deprecated behavior, to be removed Oct 18, 2013: If the path is the
+ * empty string, the directory is created in the default system temp
+ * directory. This capability has been moved to the static function
+ * [createSystemTemp].
+ */
+ Directory createTempSync([String template]);
+
+ /**
+ * Creates a temporary directory in the system temp directory.
+ * The location of the system temp directory is platform-dependent,
+ * and may be set by an environment variable.
+ * Additional random characters are appended to [template] to produce
+ * a unique directory name.
*
* Returns a [:Future<Directory>:] that completes with the newly
* created temporary directory.
*/
- Future<Directory> createTemp();
+ static Future<Directory> createSystemTemp([String template]) =>
+ _Directory.createSystemTemp(template);
/**
- * Synchronously creates a temporary directory with a name based on the
- * current path. The path is used as a template, and additional
- * characters are appended to it to make a unique temporary directory name.
- * If the path is the empty string, a default system temp directory and name
- * are used for the template. Returns the newly created temporary directory.
+ * Synchronously creates a temporary directory in the system temp directory.
+ * The location of the system temp directory is platform-dependent,
+ * and may be set by an environment variable.
+ * Additional random characters are appended to [template] to produce
+ * a unique directory name.
+ *
+ * Returns a [:Future<Directory>:] that completes with the newly
+ * created temporary directory.
*/
- Directory createTempSync();
+ static Directory createSystemTempSync([String template]) =>
+ _Directory.createSystemTempSync(template);
Future<String> resolveSymbolicLinks();
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index d1258fb..ac048de 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -5,15 +5,6 @@
part of dart.io;
class _Directory extends FileSystemEntity implements Directory {
- static const CREATE_REQUEST = 0;
- static const DELETE_REQUEST = 1;
- static const EXISTS_REQUEST = 2;
- static const CREATE_TEMP_REQUEST = 3;
- static const LIST_START_REQUEST = 4;
- static const LIST_NEXT_REQUEST = 5;
- static const LIST_STOP_REQUEST = 6;
- static const RENAME_REQUEST = 7;
-
final String path;
_Directory(String this.path) {
@@ -25,7 +16,7 @@
external static _current();
external static _setCurrent(path);
- external static _createTemp(String template);
+ external static _createTemp(String template, bool system);
external static int _exists(String path);
external static _create(String path);
external static _deleteNative(String path, bool recursive);
@@ -158,8 +149,18 @@
}
}
- Future<Directory> createTemp() {
- return _IOService.dispatch(_DIRECTORY_CREATE_TEMP, [path]).then((response) {
+ // TODO(13720): Make template argument mandatory on Oct 18, 2013.
+ Future<Directory> createTemp([String template]) {
+ if (path == '') {
+ if (template == null) template = '';
+ return createSystemTemp(template);
+ // TODO(13720): On Oct 18, 2013, replace this with
+ // an error. createTemp cannot be called on a Directory with empty path.
+ }
+ String fullTemplate = "$path${Platform.pathSeparator}";
+ if (template != null) fullTemplate = "$fullTemplate$template";
+ return _IOService.dispatch(_DIRECTORY_CREATE_TEMP, [fullTemplate])
+ .then((response) {
if (_isErrorResponse(response)) {
throw _exceptionOrErrorFromResponse(
response, "Creation of temporary directory failed");
@@ -168,11 +169,41 @@
});
}
- Directory createTempSync() {
- var result = _createTemp(path);
+ // TODO(13720): Make template argument mandatory on Oct 18, 2013.
+ Directory createTempSync([String template]) {
+ if (path == '') {
+ if (template == null) template = '';
+ return createSystemTempSync(template);
+ // TODO(13720): On Oct 18, 2013, replace this with
+ // an error. createTemp cannot be called on a Directory with empty path.
+ }
+ String fullTemplate = "$path${Platform.pathSeparator}";
+ if (template != null) fullTemplate = "$fullTemplate$template";
+ var result = _createTemp(fullTemplate, false);
if (result is OSError) {
throw new DirectoryException("Creation of temporary directory failed",
- path,
+ fullTemplate,
+ result);
+ }
+ return new Directory(result);
+ }
+
+ static Future<Directory> createSystemTemp(String template) {
+ return _IOService.dispatch(_DIRECTORY_CREATE_SYSTEM_TEMP,
+ [template]).then((response) {
+ if (response is List && response[0] != _SUCCESS_RESPONSE) {
+ throw new _Directory(template)._exceptionOrErrorFromResponse(
+ response, "Creation of temporary directory failed");
+ }
+ return new Directory(response);
+ });
+ }
+
+ static Directory createSystemTempSync(String template) {
+ var result = _createTemp(template, true);
+ if (result is OSError) {
+ throw new DirectoryException("Creation of temporary directory failed",
+ template,
result);
}
return new Directory(result);
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 1dce796..4df878a 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -531,17 +531,13 @@
class _RandomAccessFile implements RandomAccessFile {
final String path;
int _id;
+ bool _asyncDispatched = false;
SendPort _fileService;
_RandomAccessFile(int this._id, String this.path);
Future<RandomAccessFile> close() {
- if (closed) return _closedException();
- // 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 _IOService.dispatch(_FILE_CLOSE, [id]).then((result) {
+ return _dispatch(_FILE_CLOSE, [_id], markClosed: true).then((result) {
if (result != -1) {
_id = result;
return this;
@@ -554,7 +550,7 @@
external static int _close(int id);
void closeSync() {
- _checkNotClosed();
+ _checkAvailable();
var id = _close(_id);
if (id == -1) {
throw new FileException("Cannot close file", path);
@@ -563,8 +559,7 @@
}
Future<int> readByte() {
- if (closed) return _closedException();
- return _IOService.dispatch(_FILE_READ_BYTE, [_id]).then((response) {
+ return _dispatch(_FILE_READ_BYTE, [_id]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "readByte failed", path);
}
@@ -575,7 +570,7 @@
external static _readByte(int id);
int readByteSync() {
- _checkNotClosed();
+ _checkAvailable();
var result = _readByte(_id);
if (result is OSError) {
throw new FileException("readByte failed", path, result);
@@ -587,8 +582,7 @@
if (bytes is !int) {
throw new ArgumentError(bytes);
}
- if (closed) return _closedException();
- return _IOService.dispatch(_FILE_READ, [_id, bytes]).then((response) {
+ return _dispatch(_FILE_READ, [_id, bytes]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "read failed", path);
}
@@ -599,7 +593,7 @@
external static _read(int id, int bytes);
List<int> readSync(int bytes) {
- _checkNotClosed();
+ _checkAvailable();
if (bytes is !int) {
throw new ArgumentError(bytes);
}
@@ -616,11 +610,10 @@
(end != null && end is !int)) {
throw new ArgumentError();
}
- if (closed) return _closedException();
if (start == null) start = 0;
if (end == null) end = buffer.length;
int length = end - start;
- return _IOService.dispatch(_FILE_READ_INTO, [_id, length]).then((response) {
+ return _dispatch(_FILE_READ_INTO, [_id, length]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "readInto failed", path);
}
@@ -642,7 +635,7 @@
external static _readInto(int id, List<int> buffer, int start, int end);
int readIntoSync(List<int> buffer, [int start, int end]) {
- _checkNotClosed();
+ _checkAvailable();
if (buffer is !List ||
(start != null && start is !int) ||
(end != null && end is !int)) {
@@ -663,8 +656,7 @@
if (value is !int) {
throw new ArgumentError(value);
}
- if (closed) return _closedException();
- return _IOService.dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) {
+ return _dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "writeByte failed", path);
}
@@ -675,7 +667,7 @@
external static _writeByte(int id, int value);
int writeByteSync(int value) {
- _checkNotClosed();
+ _checkAvailable();
if (value is !int) {
throw new ArgumentError(value);
}
@@ -693,8 +685,6 @@
throw new ArgumentError("Invalid arguments to writeFrom");
}
- if (closed) return _closedException();
-
_BufferAndStart result;
try {
result = _ensureFastAndSerializableByteData(buffer, start, end);
@@ -707,7 +697,7 @@
request[1] = result.buffer;
request[2] = result.start;
request[3] = end - (start - result.start);
- return _IOService.dispatch(_FILE_WRITE_FROM, request).then((response) {
+ return _dispatch(_FILE_WRITE_FROM, request).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "writeFrom failed", path);
}
@@ -718,7 +708,7 @@
external static _writeFrom(int id, List<int> buffer, int start, int end);
void writeFromSync(List<int> buffer, [int start, int end]) {
- _checkNotClosed();
+ _checkAvailable();
if (buffer is !List ||
(start != null && start is !int) ||
(end != null && end is !int)) {
@@ -757,8 +747,7 @@
}
Future<int> position() {
- if (closed) return _closedException();
- return _IOService.dispatch(_FILE_POSITION, [_id]).then((response) {
+ return _dispatch(_FILE_POSITION, [_id]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "position failed", path);
}
@@ -769,7 +758,7 @@
external static _position(int id);
int positionSync() {
- _checkNotClosed();
+ _checkAvailable();
var result = _position(_id);
if (result is OSError) {
throw new FileException("position failed", path, result);
@@ -778,8 +767,7 @@
}
Future<RandomAccessFile> setPosition(int position) {
- if (closed) return _closedException();
- return _IOService.dispatch(_FILE_SET_POSITION, [_id, position])
+ return _dispatch(_FILE_SET_POSITION, [_id, position])
.then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "setPosition failed", path);
@@ -791,7 +779,7 @@
external static _setPosition(int id, int position);
void setPositionSync(int position) {
- _checkNotClosed();
+ _checkAvailable();
var result = _setPosition(_id, position);
if (result is OSError) {
throw new FileException("setPosition failed", path, result);
@@ -799,8 +787,7 @@
}
Future<RandomAccessFile> truncate(int length) {
- if (closed) return _closedException();
- return _IOService.dispatch(_FILE_TRUNCATE, [_id, length]).then((response) {
+ return _dispatch(_FILE_TRUNCATE, [_id, length]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "truncate failed", path);
}
@@ -811,7 +798,7 @@
external static _truncate(int id, int length);
void truncateSync(int length) {
- _checkNotClosed();
+ _checkAvailable();
var result = _truncate(_id, length);
if (result is OSError) {
throw new FileException("truncate failed", path, result);
@@ -819,8 +806,7 @@
}
Future<int> length() {
- if (closed) return _closedException();
- return _IOService.dispatch(_FILE_LENGTH, [_id]).then((response) {
+ return _dispatch(_FILE_LENGTH, [_id]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "length failed", path);
}
@@ -831,7 +817,7 @@
external static _length(int id);
int lengthSync() {
- _checkNotClosed();
+ _checkAvailable();
var result = _length(_id);
if (result is OSError) {
throw new FileException("length failed", path, result);
@@ -840,8 +826,7 @@
}
Future<RandomAccessFile> flush() {
- if (closed) return _closedException();
- return _IOService.dispatch(_FILE_FLUSH, [_id]).then((response) {
+ return _dispatch(_FILE_FLUSH, [_id]).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"flush failed",
@@ -854,7 +839,7 @@
external static _flush(int id);
void flushSync() {
- _checkNotClosed();
+ _checkAvailable();
var result = _flush(_id);
if (result is OSError) {
throw new FileException("flush failed", path, result);
@@ -863,13 +848,32 @@
bool get closed => _id == 0;
- void _checkNotClosed() {
+ Future _dispatch(int request, List data, { bool markClosed: false }) {
+ if (closed) {
+ return new Future.error(new FileException("File closed", path));
+ }
+ if (_asyncDispatched) {
+ var msg = "An async operation is currently pending";
+ return new Future.error(new FileException(msg, path));
+ }
+ if (markClosed) {
+ // Set the id_ to 0 (NULL) to ensure the no more async requests
+ // can be issued for this file.
+ _id = 0;
+ }
+ _asyncDispatched = true;
+ return _IOService.dispatch(request, data)
+ .whenComplete(() {
+ _asyncDispatched = false;
+ });
+ }
+
+ void _checkAvailable() {
+ if (_asyncDispatched) {
+ throw new FileException("An async operation is currently pending", path);
+ }
if (closed) {
throw new FileException("File closed", path);
}
}
-
- Future _closedException() {
- return new Future.error(new FileException("File closed", path));
- }
}
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 31f6b97..ee63d1a 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -186,6 +186,13 @@
int get port;
/**
+ * Returns the address that the server is listening on. This can be
+ * used to get the actual address used, when the address is fetched by
+ * a lookup from a hostname.
+ */
+ InternetAddress get address;
+
+ /**
* Sets the timeout, in seconds, for sessions of this [HttpServer].
* The default timeout is 20 minutes.
*/
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 99c2806..fcaf191 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -2012,6 +2012,11 @@
return _serverSocket.port;
}
+ InternetAddress get address {
+ if (closed) throw new HttpException("HttpServer is not bound to a socket");
+ return _serverSocket.address;
+ }
+
set sessionTimeout(int timeout) {
_sessionManager.sessionTimeout = timeout;
}
diff --git a/sdk/lib/io/io_service.dart b/sdk/lib/io/io_service.dart
index 760d022..037cdd1 100644
--- a/sdk/lib/io/io_service.dart
+++ b/sdk/lib/io/io_service.dart
@@ -4,6 +4,7 @@
part of dart.io;
+// This list must be kept in sync with the list in runtime/bin/io_service.h
const int _FILE_EXISTS = 0;
const int _FILE_CREATE = 1;
const int _FILE_DELETE = 2;
@@ -37,11 +38,12 @@
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;
+const int _DIRECTORY_CREATE_SYSTEM_TEMP = 33;
+const int _DIRECTORY_LIST_START = 34;
+const int _DIRECTORY_LIST_NEXT = 35;
+const int _DIRECTORY_LIST_STOP = 36;
+const int _DIRECTORY_RENAME = 37;
+const int _SSL_PROCESS_FILTER = 38;
class _IOService {
external static Future dispatch(int request, List data);
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index c5b4b8d..ce8ace5 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -202,6 +202,11 @@
int get port;
/**
+ * Returns the address used by this socket.
+ */
+ InternetAddress get address;
+
+ /**
* Closes the socket. The returned future completes when the socket
* is fully closed and is no longer bound.
*/
@@ -258,6 +263,11 @@
int get port;
/**
+ * Returns the address used by this socket.
+ */
+ InternetAddress get address;
+
+ /**
* Closes the socket. The returned future completes when the socket
* is fully closed and is no longer bound.
*/
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 3725526..766eee0 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -29,17 +29,6 @@
}
-class _StdinEventSink implements EventSink<String> {
- Function _add;
- Function _addError;
- Function _close;
- _StdinEventSink(this._add, this._addError, this._close);
-
- void add(String string) => _add(string);
- void addError(errorEvent) => _addError(errorEvent);
- void close() => _close();
-}
-
/**
* [Stdin] allows both synchronous and asynchronous reads from the standard
* input stream.
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index b13709c..e2bc326 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -572,9 +572,7 @@
StreamController _controller;
StreamSubscription _subscription;
bool _issuedPause = false;
- // Only report error if the last message was a user-provided message and not a
- // ping or pong message.
- bool _reportError = false;
+ bool _closed = false;
Completer _closeCompleter = new Completer();
Completer _completer;
@@ -602,6 +600,14 @@
}
}
+ void _cancel() {
+ if (_subscription != null) {
+ var subscription = _subscription;
+ _subscription = null;
+ subscription.cancel();
+ }
+ }
+
_ensureController() {
if (_controller != null) return;
_controller = new StreamController(sync: true,
@@ -612,19 +618,20 @@
new _WebSocketOutgoingTransformer(webSocket));
socket.addStream(stream)
.then((_) {
- _done();
- _closeCompleter.complete(webSocket);
- },
- onError: (error) {
- if (_reportError) {
- if (!_done(error)) {
- _closeCompleter.completeError(error);
- }
- } else {
- _done();
- _closeCompleter.complete(webSocket);
- }
- });
+ _done();
+ _closeCompleter.complete(webSocket);
+ }, onError: (error) {
+ _closed = true;
+ _cancel();
+ if (error is ArgumentError) {
+ if (!_done(error)) {
+ _closeCompleter.completeError(error);
+ }
+ } else {
+ _done();
+ _closeCompleter.complete(webSocket);
+ }
+ });
}
bool _done([error]) {
@@ -639,11 +646,14 @@
}
Future addStream(var stream) {
+ if (_closed) {
+ stream.listen(null).cancel();
+ return new Future.value(webSocket);
+ }
_ensureController();
_completer = new Completer();
_subscription = stream.listen(
(data) {
- _reportError = true;
_controller.add(data);
},
onDone: () {
@@ -663,17 +673,23 @@
Future close() {
_ensureController();
Future closeSocket() {
- return socket.close().then((_) => webSocket);
+ return socket.close().catchError((_) {}).then((_) => webSocket);
}
_controller.close();
return _closeCompleter.future.then((_) => closeSocket());
}
void add(data) {
+ if (_closed) return;
_ensureController();
- _reportError = false;
_controller.add(data);
}
+
+ void closeSocket() {
+ _closed = true;
+ _cancel();
+ close();
+ }
}
@@ -786,21 +802,20 @@
}
},
onError: (error) {
- if (error is ArgumentError) {
- close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
+ if (error is FormatException) {
+ _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
} else {
- close(WebSocketStatus.PROTOCOL_ERROR);
+ _close(WebSocketStatus.PROTOCOL_ERROR);
}
- _controller.addError(error);
_controller.close();
},
onDone: () {
if (_readyState == WebSocket.OPEN) {
_readyState = WebSocket.CLOSING;
if (!_isReservedStatusCode(transformer.closeCode)) {
- close(transformer.closeCode);
+ _close(transformer.closeCode);
} else {
- close();
+ _close();
}
_readyState = WebSocket.CLOSED;
}
@@ -840,7 +855,7 @@
_consumer.add(new _WebSocketPing());
_pingTimer = new Timer(_pingInterval, () {
// No pong received.
- close(WebSocketStatus.GOING_AWAY);
+ _close(WebSocketStatus.GOING_AWAY);
});
});
}
@@ -858,16 +873,24 @@
Future get done => _sink.done;
Future close([int code, String reason]) {
- if (!_writeClosed) {
- if (_isReservedStatusCode(code)) {
- throw new WebSocketException("Reserved status code $code");
- }
+ if (_isReservedStatusCode(code)) {
+ throw new WebSocketException("Reserved status code $code");
+ }
+ if (_outCloseCode == null) {
_outCloseCode = code;
_outCloseReason = reason;
- _writeClosed = true;
}
- if (!(_sink as _StreamSinkImpl)._isBound) _sink.close();
- return _sink.done;
+ return _sink.close();
+ }
+
+ void _close([int code, String reason]) {
+ if (_writeClosed) return;
+ if (_outCloseCode == null) {
+ _outCloseCode = code;
+ _outCloseReason = reason;
+ }
+ _writeClosed = true;
+ _consumer.closeSocket();
}
static bool _isReservedStatusCode(int code) {
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 7f806b7..64b4af0 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -5,11 +5,9 @@
library dart.js;
import 'dart:_foreign_helper' show JS;
-import 'dart:_js_helper' show convertDartClosureToJS;
+import 'dart:_js_helper' show Primitives, convertDartClosureToJS;
-JsObject get context {
- return new JsObject._fromJs(JS('=Object', 'window'));
-}
+final JsObject context = new JsObject._fromJs(Primitives.computeGlobalThis());
JsObject jsify(dynamic data) => data == null ? null : new JsObject._json(data);
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index 2ec2c0e..a0c48ea 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -76,15 +76,21 @@
SendPortSync _jsPortDeleteProperty = window.lookupPort('dart-js-delete-property');
SendPortSync _jsPortConvert = window.lookupPort('dart-js-convert');
+
+JsObject _context;
+
/**
* Returns a proxy to the global JavaScript context for this page.
*/
JsObject get context {
- var port = _jsPortSync;
- if (port == null) {
- return null;
+ if (_context == null) {
+ var port = _jsPortSync;
+ if (port == null) {
+ return null;
+ }
+ _context = _deserialize(_jsPortSync.callSync([]));
}
- return _deserialize(_jsPortSync.callSync([]));
+ return _context;
}
/**
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index be59cd9..0f88099 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -51,6 +51,12 @@
@DomName('SVGAElement.SVGAElement')
@DocsEditable()
factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AElement.created() : super.created();
@DomName('SVGAElement.target')
@DocsEditable()
@@ -86,6 +92,12 @@
@DomName('SVGAltGlyphElement.SVGAltGlyphElement')
@DocsEditable()
factory AltGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("altGlyph");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AltGlyphElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('altGlyph') && (new SvgElement.tag('altGlyph') is AltGlyphElement);
@@ -176,6 +188,12 @@
@DomName('SVGAnimateElement.SVGAnimateElement')
@DocsEditable()
factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnimateElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('animate') && (new SvgElement.tag('animate') is AnimateElement);
@@ -198,6 +216,12 @@
@DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
@DocsEditable()
factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnimateMotionElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('animateMotion') && (new SvgElement.tag('animateMotion') is AnimateMotionElement);
@@ -220,6 +244,12 @@
@DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
@DocsEditable()
factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnimateTransformElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('animateTransform') && (new SvgElement.tag('animateTransform') is AnimateTransformElement);
@@ -455,6 +485,12 @@
@DomName('SVGAnimationElement.SVGAnimationElement')
@DocsEditable()
factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnimationElement.created() : super.created();
@DomName('SVGAnimationElement.targetElement')
@DocsEditable()
@@ -527,6 +563,12 @@
@DomName('SVGCircleElement.SVGCircleElement')
@DocsEditable()
factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ CircleElement.created() : super.created();
@DomName('SVGCircleElement.cx')
@DocsEditable()
@@ -561,6 +603,12 @@
@DomName('SVGClipPathElement.SVGClipPathElement')
@DocsEditable()
factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ClipPathElement.created() : super.created();
@DomName('SVGClipPathElement.clipPathUnits')
@DocsEditable()
@@ -587,6 +635,12 @@
@DomName('SVGDefsElement.SVGDefsElement')
@DocsEditable()
factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DefsElement.created() : super.created();
// From SVGExternalResourcesRequired
@@ -609,6 +663,12 @@
@DomName('SVGDescElement.SVGDescElement')
@DocsEditable()
factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DescElement.created() : super.created();
}
// 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
@@ -1015,6 +1075,12 @@
@DomName('SVGEllipseElement.SVGEllipseElement')
@DocsEditable()
factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ EllipseElement.created() : super.created();
@DomName('SVGEllipseElement.cx')
@DocsEditable()
@@ -1072,6 +1138,12 @@
@DomName('SVGFEBlendElement.SVGFEBlendElement')
@DocsEditable()
factory FEBlendElement() => _SvgElementFactoryProvider.createSvgElement_tag("feBlend");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEBlendElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feBlend') && (new SvgElement.tag('feBlend') is FEBlendElement);
@@ -1153,6 +1225,12 @@
@DomName('SVGFEColorMatrixElement.SVGFEColorMatrixElement')
@DocsEditable()
factory FEColorMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEColorMatrixElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feColorMatrix') && (new SvgElement.tag('feColorMatrix') is FEColorMatrixElement);
@@ -1230,6 +1308,12 @@
@DomName('SVGFEComponentTransferElement.SVGFEComponentTransferElement')
@DocsEditable()
factory FEComponentTransferElement() => _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEComponentTransferElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feComponentTransfer') && (new SvgElement.tag('feComponentTransfer') is FEComponentTransferElement);
@@ -1271,6 +1355,12 @@
class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFECompositeElement" {
// To suppress missing implicit constructor warnings.
factory FECompositeElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FECompositeElement.created() : super.created();
@DomName('SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_ARITHMETIC')
@DocsEditable()
@@ -1369,6 +1459,12 @@
@DomName('SVGFEConvolveMatrixElement.SVGFEConvolveMatrixElement')
@DocsEditable()
factory FEConvolveMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEConvolveMatrixElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feConvolveMatrix') && (new SvgElement.tag('feConvolveMatrix') is FEConvolveMatrixElement);
@@ -1478,6 +1574,12 @@
@DomName('SVGFEDiffuseLightingElement.SVGFEDiffuseLightingElement')
@DocsEditable()
factory FEDiffuseLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEDiffuseLightingElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feDiffuseLighting') && (new SvgElement.tag('feDiffuseLighting') is FEDiffuseLightingElement);
@@ -1543,6 +1645,12 @@
@DomName('SVGFEDisplacementMapElement.SVGFEDisplacementMapElement')
@DocsEditable()
factory FEDisplacementMapElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEDisplacementMapElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feDisplacementMap') && (new SvgElement.tag('feDisplacementMap') is FEDisplacementMapElement);
@@ -1628,6 +1736,12 @@
@DomName('SVGFEDistantLightElement.SVGFEDistantLightElement')
@DocsEditable()
factory FEDistantLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEDistantLightElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feDistantLight') && (new SvgElement.tag('feDistantLight') is FEDistantLightElement);
@@ -1659,6 +1773,12 @@
@DomName('SVGFEFloodElement.SVGFEFloodElement')
@DocsEditable()
factory FEFloodElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFlood");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFloodElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feFlood') && (new SvgElement.tag('feFlood') is FEFloodElement);
@@ -1704,6 +1824,12 @@
@DomName('SVGFEFuncAElement.SVGFEFuncAElement')
@DocsEditable()
factory FEFuncAElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncA");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFuncAElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feFuncA') && (new SvgElement.tag('feFuncA') is FEFuncAElement);
@@ -1727,6 +1853,12 @@
@DomName('SVGFEFuncBElement.SVGFEFuncBElement')
@DocsEditable()
factory FEFuncBElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncB");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFuncBElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feFuncB') && (new SvgElement.tag('feFuncB') is FEFuncBElement);
@@ -1750,6 +1882,12 @@
@DomName('SVGFEFuncGElement.SVGFEFuncGElement')
@DocsEditable()
factory FEFuncGElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncG");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFuncGElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feFuncG') && (new SvgElement.tag('feFuncG') is FEFuncGElement);
@@ -1773,6 +1911,12 @@
@DomName('SVGFEFuncRElement.SVGFEFuncRElement')
@DocsEditable()
factory FEFuncRElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncR");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFuncRElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feFuncR') && (new SvgElement.tag('feFuncR') is FEFuncRElement);
@@ -1796,6 +1940,12 @@
@DomName('SVGFEGaussianBlurElement.SVGFEGaussianBlurElement')
@DocsEditable()
factory FEGaussianBlurElement() => _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEGaussianBlurElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feGaussianBlur') && (new SvgElement.tag('feGaussianBlur') is FEGaussianBlurElement);
@@ -1857,6 +2007,12 @@
@DomName('SVGFEImageElement.SVGFEImageElement')
@DocsEditable()
factory FEImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("feImage");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEImageElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feImage') && (new SvgElement.tag('feImage') is FEImageElement);
@@ -1918,6 +2074,12 @@
@DomName('SVGFEMergeElement.SVGFEMergeElement')
@DocsEditable()
factory FEMergeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMerge");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEMergeElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feMerge') && (new SvgElement.tag('feMerge') is FEMergeElement);
@@ -1963,6 +2125,12 @@
@DomName('SVGFEMergeNodeElement.SVGFEMergeNodeElement')
@DocsEditable()
factory FEMergeNodeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEMergeNodeElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feMergeNode') && (new SvgElement.tag('feMergeNode') is FEMergeNodeElement);
@@ -1986,6 +2154,12 @@
class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEMorphologyElement" {
// To suppress missing implicit constructor warnings.
factory FEMorphologyElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEMorphologyElement.created() : super.created();
@DomName('SVGFEMorphologyElement.SVG_MORPHOLOGY_OPERATOR_DILATE')
@DocsEditable()
@@ -2060,6 +2234,12 @@
@DomName('SVGFEOffsetElement.SVGFEOffsetElement')
@DocsEditable()
factory FEOffsetElement() => _SvgElementFactoryProvider.createSvgElement_tag("feOffset");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEOffsetElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feOffset') && (new SvgElement.tag('feOffset') is FEOffsetElement);
@@ -2117,6 +2297,12 @@
@DomName('SVGFEPointLightElement.SVGFEPointLightElement')
@DocsEditable()
factory FEPointLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("fePointLight");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEPointLightElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('fePointLight') && (new SvgElement.tag('fePointLight') is FEPointLightElement);
@@ -2152,6 +2338,12 @@
@DomName('SVGFESpecularLightingElement.SVGFESpecularLightingElement')
@DocsEditable()
factory FESpecularLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FESpecularLightingElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feSpecularLighting') && (new SvgElement.tag('feSpecularLighting') is FESpecularLightingElement);
@@ -2213,6 +2405,12 @@
@DomName('SVGFESpotLightElement.SVGFESpotLightElement')
@DocsEditable()
factory FESpotLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FESpotLightElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feSpotLight') && (new SvgElement.tag('feSpotLight') is FESpotLightElement);
@@ -2268,6 +2466,12 @@
@DomName('SVGFETileElement.SVGFETileElement')
@DocsEditable()
factory FETileElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTile");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FETileElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feTile') && (new SvgElement.tag('feTile') is FETileElement);
@@ -2317,6 +2521,12 @@
@DomName('SVGFETurbulenceElement.SVGFETurbulenceElement')
@DocsEditable()
factory FETurbulenceElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FETurbulenceElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('feTurbulence') && (new SvgElement.tag('feTurbulence') is FETurbulenceElement);
@@ -2410,6 +2620,12 @@
@DomName('SVGFilterElement.SVGFilterElement')
@DocsEditable()
factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FilterElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('filter') && (new SvgElement.tag('filter') is FilterElement);
@@ -2514,6 +2730,12 @@
@DomName('SVGForeignObjectElement.SVGForeignObjectElement')
@DocsEditable()
factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ForeignObjectElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('foreignObject') && (new SvgElement.tag('foreignObject') is ForeignObjectElement);
@@ -2555,6 +2777,12 @@
@DomName('SVGGElement.SVGGElement')
@DocsEditable()
factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ GElement.created() : super.created();
// From SVGExternalResourcesRequired
@@ -2573,6 +2801,12 @@
class GraphicsElement extends SvgElement implements Tests native "SVGGraphicsElement" {
// To suppress missing implicit constructor warnings.
factory GraphicsElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ GraphicsElement.created() : super.created();
@DomName('SVGGraphicsElement.farthestViewportElement')
@DocsEditable()
@@ -2648,6 +2882,12 @@
@DomName('SVGImageElement.SVGImageElement')
@DocsEditable()
factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ImageElement.created() : super.created();
@DomName('SVGImageElement.height')
@DocsEditable()
@@ -2862,6 +3102,12 @@
@DomName('SVGLineElement.SVGLineElement')
@DocsEditable()
factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LineElement.created() : super.created();
@DomName('SVGLineElement.x1')
@DocsEditable()
@@ -2900,6 +3146,12 @@
@DomName('SVGLinearGradientElement.SVGLinearGradientElement')
@DocsEditable()
factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LinearGradientElement.created() : super.created();
@DomName('SVGLinearGradientElement.x1')
@DocsEditable()
@@ -2932,6 +3184,12 @@
@DomName('SVGMarkerElement.SVGMarkerElement')
@DocsEditable()
factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MarkerElement.created() : super.created();
@DomName('SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH')
@DocsEditable()
@@ -3024,6 +3282,12 @@
@DomName('SVGMaskElement.SVGMaskElement')
@DocsEditable()
factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MaskElement.created() : super.created();
@DomName('SVGMaskElement.height')
@DocsEditable()
@@ -3162,6 +3426,12 @@
class MetadataElement extends SvgElement native "SVGMetadataElement" {
// To suppress missing implicit constructor warnings.
factory MetadataElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MetadataElement.created() : super.created();
}
// 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
@@ -3280,6 +3550,12 @@
@DomName('SVGPathElement.SVGPathElement')
@DocsEditable()
factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PathElement.created() : super.created();
@DomName('SVGPathElement.animatedNormalizedPathSegList')
@DocsEditable()
@@ -4075,6 +4351,12 @@
@DomName('SVGPatternElement.SVGPatternElement')
@DocsEditable()
factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PatternElement.created() : super.created();
@DomName('SVGPatternElement.height')
@DocsEditable()
@@ -4223,6 +4505,12 @@
@DomName('SVGPolygonElement.SVGPolygonElement')
@DocsEditable()
factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PolygonElement.created() : super.created();
@DomName('SVGPolygonElement.animatedPoints')
@DocsEditable()
@@ -4253,6 +4541,12 @@
@DomName('SVGPolylineElement.SVGPolylineElement')
@DocsEditable()
factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PolylineElement.created() : super.created();
@DomName('SVGPolylineElement.animatedPoints')
@DocsEditable()
@@ -4357,6 +4651,12 @@
@DomName('SVGRadialGradientElement.SVGRadialGradientElement')
@DocsEditable()
factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ RadialGradientElement.created() : super.created();
@DomName('SVGRadialGradientElement.cx')
@DocsEditable()
@@ -4423,6 +4723,12 @@
@DomName('SVGRectElement.SVGRectElement')
@DocsEditable()
factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ RectElement.created() : super.created();
@DomName('SVGRectElement.height')
@DocsEditable()
@@ -4503,6 +4809,12 @@
@DomName('SVGScriptElement.SVGScriptElement')
@DocsEditable()
factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ScriptElement.created() : super.created();
@DomName('SVGScriptElement.type')
@DocsEditable()
@@ -4538,6 +4850,12 @@
@DomName('SVGSetElement.SVGSetElement')
@DocsEditable()
factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SetElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('set') && (new SvgElement.tag('set') is SetElement);
@@ -4557,6 +4875,12 @@
@DomName('SVGStopElement.SVGStopElement')
@DocsEditable()
factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ StopElement.created() : super.created();
@JSName('offset')
@DomName('SVGStopElement.offset')
@@ -4667,6 +4991,12 @@
@DomName('SVGStyleElement.SVGStyleElement')
@DocsEditable()
factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ StyleElement.created() : super.created();
@DomName('SVGStyleElement.disabled')
@DocsEditable()
@@ -4856,6 +5186,12 @@
}
// To suppress missing implicit constructor warnings.
factory SvgElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SvgElement.created() : super.created();
// Shadowing definition.
AnimatedString get _svgClassName => JS("AnimatedString", "#.className", this);
@@ -4904,6 +5240,12 @@
// To suppress missing implicit constructor warnings.
factory SvgSvgElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SvgSvgElement.created() : super.created();
@DomName('SVGSVGElement.contentScriptType')
@DocsEditable()
@@ -5107,6 +5449,12 @@
@DomName('SVGSwitchElement.SVGSwitchElement')
@DocsEditable()
factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SwitchElement.created() : super.created();
// From SVGExternalResourcesRequired
@@ -5129,6 +5477,12 @@
@DomName('SVGSymbolElement.SVGSymbolElement')
@DocsEditable()
factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SymbolElement.created() : super.created();
// From SVGExternalResourcesRequired
@@ -5161,6 +5515,12 @@
@DomName('SVGTSpanElement.SVGTSpanElement')
@DocsEditable()
factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TSpanElement.created() : super.created();
}
// 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
@@ -5191,6 +5551,12 @@
class TextContentElement extends GraphicsElement implements ExternalResourcesRequired native "SVGTextContentElement" {
// To suppress missing implicit constructor warnings.
factory TextContentElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextContentElement.created() : super.created();
@DomName('SVGTextContentElement.LENGTHADJUST_SPACING')
@DocsEditable()
@@ -5269,6 +5635,12 @@
@DomName('SVGTextElement.SVGTextElement')
@DocsEditable()
factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextElement.created() : super.created();
}
// 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
@@ -5281,6 +5653,12 @@
class TextPathElement extends TextContentElement implements UriReference native "SVGTextPathElement" {
// To suppress missing implicit constructor warnings.
factory TextPathElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextPathElement.created() : super.created();
@DomName('SVGTextPathElement.TEXTPATH_METHODTYPE_ALIGN')
@DocsEditable()
@@ -5335,6 +5713,12 @@
class TextPositioningElement extends TextContentElement native "SVGTextPositioningElement" {
// To suppress missing implicit constructor warnings.
factory TextPositioningElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextPositioningElement.created() : super.created();
@DomName('SVGTextPositioningElement.dx')
@DocsEditable()
@@ -5371,6 +5755,12 @@
@DomName('SVGTitleElement.SVGTitleElement')
@DocsEditable()
factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TitleElement.created() : super.created();
}
// 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
@@ -5592,6 +5982,12 @@
@DomName('SVGUseElement.SVGUseElement')
@DocsEditable()
factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ UseElement.created() : super.created();
@DomName('SVGUseElement.animatedInstanceRoot')
@DocsEditable()
@@ -5662,6 +6058,12 @@
@DomName('SVGViewElement.SVGViewElement')
@DocsEditable()
factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ViewElement.created() : super.created();
@DomName('SVGViewElement.viewTarget')
@DocsEditable()
@@ -5869,6 +6271,12 @@
class _GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired native "SVGGradientElement" {
// To suppress missing implicit constructor warnings.
factory _GradientElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _GradientElement.created() : super.created();
@DomName('SVGGradientElement.SVG_SPREADMETHOD_PAD')
@DocsEditable()
@@ -5921,6 +6329,12 @@
abstract class _SVGAltGlyphDefElement extends SvgElement native "SVGAltGlyphDefElement" {
// To suppress missing implicit constructor warnings.
factory _SVGAltGlyphDefElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGAltGlyphDefElement.created() : super.created();
}
// 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
@@ -5933,6 +6347,12 @@
abstract class _SVGAltGlyphItemElement extends SvgElement native "SVGAltGlyphItemElement" {
// To suppress missing implicit constructor warnings.
factory _SVGAltGlyphItemElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGAltGlyphItemElement.created() : super.created();
}
// 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
@@ -5945,6 +6365,12 @@
abstract class _SVGAnimateColorElement extends AnimationElement native "SVGAnimateColorElement" {
// To suppress missing implicit constructor warnings.
factory _SVGAnimateColorElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGAnimateColorElement.created() : super.created();
}
// 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
@@ -5970,6 +6396,12 @@
abstract class _SVGComponentTransferFunctionElement extends SvgElement native "SVGComponentTransferFunctionElement" {
// To suppress missing implicit constructor warnings.
factory _SVGComponentTransferFunctionElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGComponentTransferFunctionElement.created() : super.created();
}
// 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
@@ -5986,6 +6418,12 @@
@DomName('SVGCursorElement.SVGCursorElement')
@DocsEditable()
factory _SVGCursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGCursorElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => SvgElement.isTagSupported('cursor') && (new SvgElement.tag('cursor') is _SVGCursorElement);
@@ -6007,6 +6445,12 @@
abstract class _SVGFEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEDropShadowElement" {
// To suppress missing implicit constructor warnings.
factory _SVGFEDropShadowElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFEDropShadowElement.created() : super.created();
// From SVGFilterPrimitiveStandardAttributes
}
@@ -6021,6 +6465,12 @@
abstract class _SVGFontElement extends SvgElement native "SVGFontElement" {
// To suppress missing implicit constructor warnings.
factory _SVGFontElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontElement.created() : super.created();
}
// 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
@@ -6033,6 +6483,12 @@
abstract class _SVGFontFaceElement extends SvgElement native "SVGFontFaceElement" {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceElement.created() : super.created();
}
// 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
@@ -6045,6 +6501,12 @@
abstract class _SVGFontFaceFormatElement extends SvgElement native "SVGFontFaceFormatElement" {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceFormatElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceFormatElement.created() : super.created();
}
// 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
@@ -6057,6 +6519,12 @@
abstract class _SVGFontFaceNameElement extends SvgElement native "SVGFontFaceNameElement" {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceNameElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceNameElement.created() : super.created();
}
// 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
@@ -6069,6 +6537,12 @@
abstract class _SVGFontFaceSrcElement extends SvgElement native "SVGFontFaceSrcElement" {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceSrcElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceSrcElement.created() : super.created();
}
// 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
@@ -6081,6 +6555,12 @@
abstract class _SVGFontFaceUriElement extends SvgElement native "SVGFontFaceUriElement" {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceUriElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceUriElement.created() : super.created();
}
// 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
@@ -6097,6 +6577,12 @@
@DomName('SVGGlyphElement.SVGGlyphElement')
@DocsEditable()
factory _SVGGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGGlyphElement.created() : super.created();
}
// 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
@@ -6109,6 +6595,12 @@
abstract class _SVGGlyphRefElement extends SvgElement implements UriReference native "SVGGlyphRefElement" {
// To suppress missing implicit constructor warnings.
factory _SVGGlyphRefElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGGlyphRefElement.created() : super.created();
// From SVGURIReference
}
@@ -6127,6 +6619,12 @@
@DomName('SVGHKernElement.SVGHKernElement')
@DocsEditable()
factory _SVGHKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGHKernElement.created() : super.created();
}
// 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
@@ -6142,6 +6640,12 @@
@DomName('SVGMPathElement.SVGMPathElement')
@DocsEditable()
factory _SVGMPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGMPathElement.created() : super.created();
// From SVGExternalResourcesRequired
@@ -6158,6 +6662,12 @@
abstract class _SVGMissingGlyphElement extends SvgElement native "SVGMissingGlyphElement" {
// To suppress missing implicit constructor warnings.
factory _SVGMissingGlyphElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGMissingGlyphElement.created() : super.created();
}
// 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
@@ -6186,6 +6696,12 @@
@DomName('SVGTRefElement.SVGTRefElement')
@DocsEditable()
factory _SVGTRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGTRefElement.created() : super.created();
// From SVGURIReference
}
@@ -6204,4 +6720,10 @@
@DomName('SVGVKernElement.SVGVKernElement')
@DocsEditable()
factory _SVGVKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGVKernElement.created() : super.created();
}
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 2201493..785f717 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -42,6 +42,12 @@
@DomName('SVGAElement.SVGAElement')
@DocsEditable()
factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AElement.created() : super.created();
@DomName('SVGAElement.target')
@DocsEditable()
@@ -76,6 +82,12 @@
@DomName('SVGAltGlyphElement.SVGAltGlyphElement')
@DocsEditable()
factory AltGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("altGlyph");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AltGlyphElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -190,6 +202,12 @@
@DomName('SVGAnimateElement.SVGAnimateElement')
@DocsEditable()
factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnimateElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -215,6 +233,12 @@
@DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
@DocsEditable()
factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnimateMotionElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -240,6 +264,12 @@
@DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
@DocsEditable()
factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnimateTransformElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -534,6 +564,12 @@
@DomName('SVGAnimationElement.SVGAnimationElement')
@DocsEditable()
factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ AnimationElement.created() : super.created();
@DomName('SVGAnimationElement.targetElement')
@DocsEditable()
@@ -605,6 +641,12 @@
@DomName('SVGCircleElement.SVGCircleElement')
@DocsEditable()
factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ CircleElement.created() : super.created();
@DomName('SVGCircleElement.cx')
@DocsEditable()
@@ -640,6 +682,12 @@
@DomName('SVGClipPathElement.SVGClipPathElement')
@DocsEditable()
factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ClipPathElement.created() : super.created();
@DomName('SVGClipPathElement.clipPathUnits')
@DocsEditable()
@@ -667,6 +715,12 @@
@DomName('SVGDefsElement.SVGDefsElement')
@DocsEditable()
factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DefsElement.created() : super.created();
@DomName('SVGDefsElement.externalResourcesRequired')
@DocsEditable()
@@ -690,6 +744,12 @@
@DomName('SVGDescElement.SVGDescElement')
@DocsEditable()
factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ DescElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -1115,6 +1175,12 @@
@DomName('SVGEllipseElement.SVGEllipseElement')
@DocsEditable()
factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ EllipseElement.created() : super.created();
@DomName('SVGEllipseElement.cx')
@DocsEditable()
@@ -1178,6 +1244,12 @@
@DomName('SVGFEBlendElement.SVGFEBlendElement')
@DocsEditable()
factory FEBlendElement() => _SvgElementFactoryProvider.createSvgElement_tag("feBlend");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEBlendElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1260,6 +1332,12 @@
@DomName('SVGFEColorMatrixElement.SVGFEColorMatrixElement')
@DocsEditable()
factory FEColorMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEColorMatrixElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1338,6 +1416,12 @@
@DomName('SVGFEComponentTransferElement.SVGFEComponentTransferElement')
@DocsEditable()
factory FEComponentTransferElement() => _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEComponentTransferElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1380,6 +1464,12 @@
class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
// To suppress missing implicit constructor warnings.
factory FECompositeElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FECompositeElement.created() : super.created();
@DomName('SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_ARITHMETIC')
@DocsEditable()
@@ -1479,6 +1569,12 @@
@DomName('SVGFEConvolveMatrixElement.SVGFEConvolveMatrixElement')
@DocsEditable()
factory FEConvolveMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEConvolveMatrixElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1589,6 +1685,12 @@
@DomName('SVGFEDiffuseLightingElement.SVGFEDiffuseLightingElement')
@DocsEditable()
factory FEDiffuseLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEDiffuseLightingElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1655,6 +1757,12 @@
@DomName('SVGFEDisplacementMapElement.SVGFEDisplacementMapElement')
@DocsEditable()
factory FEDisplacementMapElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEDisplacementMapElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1741,6 +1849,12 @@
@DomName('SVGFEDistantLightElement.SVGFEDistantLightElement')
@DocsEditable()
factory FEDistantLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEDistantLightElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1775,6 +1889,12 @@
@DomName('SVGFEFloodElement.SVGFEFloodElement')
@DocsEditable()
factory FEFloodElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFlood");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFloodElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1821,6 +1941,12 @@
@DomName('SVGFEFuncAElement.SVGFEFuncAElement')
@DocsEditable()
factory FEFuncAElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncA");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFuncAElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1847,6 +1973,12 @@
@DomName('SVGFEFuncBElement.SVGFEFuncBElement')
@DocsEditable()
factory FEFuncBElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncB");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFuncBElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1873,6 +2005,12 @@
@DomName('SVGFEFuncGElement.SVGFEFuncGElement')
@DocsEditable()
factory FEFuncGElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncG");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFuncGElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1899,6 +2037,12 @@
@DomName('SVGFEFuncRElement.SVGFEFuncRElement')
@DocsEditable()
factory FEFuncRElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncR");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEFuncRElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1925,6 +2069,12 @@
@DomName('SVGFEGaussianBlurElement.SVGFEGaussianBlurElement')
@DocsEditable()
factory FEGaussianBlurElement() => _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEGaussianBlurElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -1987,6 +2137,12 @@
@DomName('SVGFEImageElement.SVGFEImageElement')
@DocsEditable()
factory FEImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("feImage");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEImageElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2045,6 +2201,12 @@
@DomName('SVGFEMergeElement.SVGFEMergeElement')
@DocsEditable()
factory FEMergeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMerge");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEMergeElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2091,6 +2253,12 @@
@DomName('SVGFEMergeNodeElement.SVGFEMergeNodeElement')
@DocsEditable()
factory FEMergeNodeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEMergeNodeElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2117,6 +2285,12 @@
class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes {
// To suppress missing implicit constructor warnings.
factory FEMorphologyElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEMorphologyElement.created() : super.created();
@DomName('SVGFEMorphologyElement.SVG_MORPHOLOGY_OPERATOR_DILATE')
@DocsEditable()
@@ -2192,6 +2366,12 @@
@DomName('SVGFEOffsetElement.SVGFEOffsetElement')
@DocsEditable()
factory FEOffsetElement() => _SvgElementFactoryProvider.createSvgElement_tag("feOffset");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEOffsetElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2250,6 +2430,12 @@
@DomName('SVGFEPointLightElement.SVGFEPointLightElement')
@DocsEditable()
factory FEPointLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("fePointLight");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FEPointLightElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2288,6 +2474,12 @@
@DomName('SVGFESpecularLightingElement.SVGFESpecularLightingElement')
@DocsEditable()
factory FESpecularLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FESpecularLightingElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2350,6 +2542,12 @@
@DomName('SVGFESpotLightElement.SVGFESpotLightElement')
@DocsEditable()
factory FESpotLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FESpotLightElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2408,6 +2606,12 @@
@DomName('SVGFETileElement.SVGFETileElement')
@DocsEditable()
factory FETileElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTile");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FETileElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2458,6 +2662,12 @@
@DomName('SVGFETurbulenceElement.SVGFETurbulenceElement')
@DocsEditable()
factory FETurbulenceElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FETurbulenceElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2552,6 +2762,12 @@
@DomName('SVGFilterElement.SVGFilterElement')
@DocsEditable()
factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ FilterElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2675,6 +2891,12 @@
@DomName('SVGForeignObjectElement.SVGForeignObjectElement')
@DocsEditable()
factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ForeignObjectElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -2717,6 +2939,12 @@
@DomName('SVGGElement.SVGGElement')
@DocsEditable()
factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ GElement.created() : super.created();
@DomName('SVGGElement.externalResourcesRequired')
@DocsEditable()
@@ -2736,6 +2964,12 @@
class GraphicsElement extends SvgElement implements Tests {
// To suppress missing implicit constructor warnings.
factory GraphicsElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ GraphicsElement.created() : super.created();
@DomName('SVGGraphicsElement.farthestViewportElement')
@DocsEditable()
@@ -2810,6 +3044,12 @@
@DomName('SVGImageElement.SVGImageElement')
@DocsEditable()
factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ImageElement.created() : super.created();
@DomName('SVGImageElement.height')
@DocsEditable()
@@ -3041,6 +3281,12 @@
@DomName('SVGLineElement.SVGLineElement')
@DocsEditable()
factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LineElement.created() : super.created();
@DomName('SVGLineElement.x1')
@DocsEditable()
@@ -3080,6 +3326,12 @@
@DomName('SVGLinearGradientElement.SVGLinearGradientElement')
@DocsEditable()
factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ LinearGradientElement.created() : super.created();
@DomName('SVGLinearGradientElement.x1')
@DocsEditable()
@@ -3115,6 +3367,12 @@
@DomName('SVGMarkerElement.SVGMarkerElement')
@DocsEditable()
factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MarkerElement.created() : super.created();
@DomName('SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH')
@DocsEditable()
@@ -3206,6 +3464,12 @@
@DomName('SVGMaskElement.SVGMaskElement')
@DocsEditable()
factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MaskElement.created() : super.created();
@DomName('SVGMaskElement.height')
@DocsEditable()
@@ -3370,6 +3634,12 @@
class MetadataElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory MetadataElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ MetadataElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -3501,6 +3771,12 @@
@DomName('SVGPathElement.SVGPathElement')
@DocsEditable()
factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PathElement.created() : super.created();
@DomName('SVGPathElement.animatedNormalizedPathSegList')
@DocsEditable()
@@ -4573,6 +4849,12 @@
@DomName('SVGPatternElement.SVGPatternElement')
@DocsEditable()
factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PatternElement.created() : super.created();
@DomName('SVGPatternElement.height')
@DocsEditable()
@@ -4730,6 +5012,12 @@
@DomName('SVGPolygonElement.SVGPolygonElement')
@DocsEditable()
factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PolygonElement.created() : super.created();
@DomName('SVGPolygonElement.animatedPoints')
@DocsEditable()
@@ -4761,6 +5049,12 @@
@DomName('SVGPolylineElement.SVGPolylineElement')
@DocsEditable()
factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ PolylineElement.created() : super.created();
@DomName('SVGPolylineElement.animatedPoints')
@DocsEditable()
@@ -4877,6 +5171,12 @@
@DomName('SVGRadialGradientElement.SVGRadialGradientElement')
@DocsEditable()
factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ RadialGradientElement.created() : super.created();
@DomName('SVGRadialGradientElement.cx')
@DocsEditable()
@@ -4965,6 +5265,12 @@
@DomName('SVGRectElement.SVGRectElement')
@DocsEditable()
factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ RectElement.created() : super.created();
@DomName('SVGRectElement.height')
@DocsEditable()
@@ -5049,6 +5355,12 @@
@DomName('SVGScriptElement.SVGScriptElement')
@DocsEditable()
factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ScriptElement.created() : super.created();
@DomName('SVGScriptElement.type')
@DocsEditable()
@@ -5087,6 +5399,12 @@
@DomName('SVGSetElement.SVGSetElement')
@DocsEditable()
factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SetElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -5109,6 +5427,12 @@
@DomName('SVGStopElement.SVGStopElement')
@DocsEditable()
factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ StopElement.created() : super.created();
@DomName('SVGStopElement.offset')
@DocsEditable()
@@ -5224,6 +5548,12 @@
@DomName('SVGStyleElement.SVGStyleElement')
@DocsEditable()
factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ StyleElement.created() : super.created();
@DomName('SVGStyleElement.disabled')
@DocsEditable()
@@ -5434,6 +5764,12 @@
}
// To suppress missing implicit constructor warnings.
factory SvgElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SvgElement.created() : super.created();
@DomName('SVGElement.className')
@DocsEditable()
@@ -5499,6 +5835,12 @@
// To suppress missing implicit constructor warnings.
factory SvgSvgElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SvgSvgElement.created() : super.created();
@DomName('SVGSVGElement.contentScriptType')
@DocsEditable()
@@ -5702,6 +6044,12 @@
@DomName('SVGSwitchElement.SVGSwitchElement')
@DocsEditable()
factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SwitchElement.created() : super.created();
@DomName('SVGSwitchElement.externalResourcesRequired')
@DocsEditable()
@@ -5725,6 +6073,12 @@
@DomName('SVGSymbolElement.SVGSymbolElement')
@DocsEditable()
factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ SymbolElement.created() : super.created();
@DomName('SVGSymbolElement.externalResourcesRequired')
@DocsEditable()
@@ -5756,6 +6110,12 @@
@DomName('SVGTSpanElement.SVGTSpanElement')
@DocsEditable()
factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TSpanElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -5800,6 +6160,12 @@
class TextContentElement extends GraphicsElement implements ExternalResourcesRequired {
// To suppress missing implicit constructor warnings.
factory TextContentElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextContentElement.created() : super.created();
@DomName('SVGTextContentElement.LENGTHADJUST_SPACING')
@DocsEditable()
@@ -5879,6 +6245,12 @@
@DomName('SVGTextElement.SVGTextElement')
@DocsEditable()
factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -5894,6 +6266,12 @@
class TextPathElement extends TextContentElement implements UriReference {
// To suppress missing implicit constructor warnings.
factory TextPathElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextPathElement.created() : super.created();
@DomName('SVGTextPathElement.TEXTPATH_METHODTYPE_ALIGN')
@DocsEditable()
@@ -5949,6 +6327,12 @@
class TextPositioningElement extends TextContentElement {
// To suppress missing implicit constructor warnings.
factory TextPositioningElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TextPositioningElement.created() : super.created();
@DomName('SVGTextPositioningElement.dx')
@DocsEditable()
@@ -5988,6 +6372,12 @@
@DomName('SVGTitleElement.SVGTitleElement')
@DocsEditable()
factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ TitleElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6225,6 +6615,12 @@
@DomName('SVGUseElement.SVGUseElement')
@DocsEditable()
factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ UseElement.created() : super.created();
@DomName('SVGUseElement.animatedInstanceRoot')
@DocsEditable()
@@ -6292,6 +6688,12 @@
@DomName('SVGViewElement.SVGViewElement')
@DocsEditable()
factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ ViewElement.created() : super.created();
@DomName('SVGViewElement.viewTarget')
@DocsEditable()
@@ -6522,6 +6924,12 @@
class _GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired {
// To suppress missing implicit constructor warnings.
factory _GradientElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _GradientElement.created() : super.created();
@DomName('SVGGradientElement.SVG_SPREADMETHOD_PAD')
@DocsEditable()
@@ -6573,6 +6981,12 @@
abstract class _SVGAltGlyphDefElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGAltGlyphDefElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGAltGlyphDefElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6588,6 +7002,12 @@
abstract class _SVGAltGlyphItemElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGAltGlyphItemElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGAltGlyphItemElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6603,6 +7023,12 @@
abstract class _SVGAnimateColorElement extends AnimationElement {
// To suppress missing implicit constructor warnings.
factory _SVGAnimateColorElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGAnimateColorElement.created() : super.created();
}
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
@@ -6631,6 +7057,12 @@
abstract class _SVGComponentTransferFunctionElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGComponentTransferFunctionElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGComponentTransferFunctionElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6650,6 +7082,12 @@
@DomName('SVGCursorElement.SVGCursorElement')
@DocsEditable()
factory _SVGCursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGCursorElement.created() : super.created();
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -6668,6 +7106,12 @@
abstract class _SVGFEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes {
// To suppress missing implicit constructor warnings.
factory _SVGFEDropShadowElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFEDropShadowElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6683,6 +7127,12 @@
abstract class _SVGFontElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGFontElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6698,6 +7148,12 @@
abstract class _SVGFontFaceElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6713,6 +7169,12 @@
abstract class _SVGFontFaceFormatElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceFormatElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceFormatElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6728,6 +7190,12 @@
abstract class _SVGFontFaceNameElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceNameElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceNameElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6743,6 +7211,12 @@
abstract class _SVGFontFaceSrcElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceSrcElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceSrcElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6758,6 +7232,12 @@
abstract class _SVGFontFaceUriElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGFontFaceUriElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGFontFaceUriElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6777,6 +7257,12 @@
@DomName('SVGGlyphElement.SVGGlyphElement')
@DocsEditable()
factory _SVGGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGGlyphElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6792,6 +7278,12 @@
abstract class _SVGGlyphRefElement extends SvgElement implements UriReference {
// To suppress missing implicit constructor warnings.
factory _SVGGlyphRefElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGGlyphRefElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6811,6 +7303,12 @@
@DomName('SVGHKernElement.SVGHKernElement')
@DocsEditable()
factory _SVGHKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGHKernElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6829,6 +7327,12 @@
@DomName('SVGMPathElement.SVGMPathElement')
@DocsEditable()
factory _SVGMPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGMPathElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6844,6 +7348,12 @@
abstract class _SVGMissingGlyphElement extends SvgElement {
// To suppress missing implicit constructor warnings.
factory _SVGMissingGlyphElement._() { throw new UnsupportedError("Not supported"); }
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGMissingGlyphElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6878,6 +7388,12 @@
@DomName('SVGTRefElement.SVGTRefElement')
@DocsEditable()
factory _SVGTRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGTRefElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -6897,5 +7413,11 @@
@DomName('SVGVKernElement.SVGVKernElement')
@DocsEditable()
factory _SVGVKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ _SVGVKernElement.created() : super.created();
}
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index c911f20..2859980 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -3,25 +3,12 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dartanalyzer ]
-# not clear: g([var foo = foo + 10]) is parameter 'foo' in the scope of its own initialzer?
-Language/06_Functions/2_Formal_Parameters_A02_t02: fail
-
-# not clear: null..[1](1)[2](2).foo(3, bar: 4)=5 - it seems that verything before =5 it not assignable
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: fail
-
# invalid argument for constant constructor
Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t02: fail
-# TBF: _f is private, so does not collide
-Language/07_Classes/1_Instance_Methods_A05_t08: fail
-
# TBD: should we check that argument for dynamic parameter of constant constructor is not compatible with operation that is performed with it?
Language/12_Expressions/01_Constants_A16_t03: fail
-# TBD: should we report _error_ when constant creation uses arguments with types incompatible with parameters?
-Language/12_Expressions/12_Instance_Creation/2_Const_A09_t02: fail
-Language/12_Expressions/12_Instance_Creation/2_Const_A09_t03: fail
-
# TBF: infinite look: class A {const A();final m = const A();}
Language/12_Expressions/01_Constants_A17_t03: fail
@@ -29,16 +16,6 @@
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
-
# co19 issue #380, Strings class has been removed
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
@@ -49,9 +26,6 @@
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
-Language/05_Variables/05_Variables_A12_t06: fail, OK
-Language/05_Variables/05_Variables_A13_t01: fail, OK
Language/07_Classes/07_Classes_A02_t11: fail, OK
# co19 issue #442, undefined name "Expect"
@@ -90,7 +64,6 @@
Language/12_Expressions/12_Instance_Creation_A01_t06: fail, OK
# co19 issue #433 (wrongly closed), missing @static-warning annotation
-Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t01: fail, OK
Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t07: fail, OK
# co19 issue #541: tests contain unqualified reference to static members defined in superclass
@@ -100,20 +73,54 @@
# co19 issue #543: invocation of a non-function
Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
-# 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 #609, return type of "factory M" is M, so we need static warning for "return;".
+Language/13_Statements/11_Return_A07_t01: fail, OK
-# co19 issue #597: concrete class with abstract method
-Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail, OK
-
+Language/09_Mixins/1_Mixin_Application_A01_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/01_Constants_A22_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/07_Maps_A13_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/12_Instance_Creation_A01_t08: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A02_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A04_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A04_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t04: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t04: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/16_Getter_Lookup_A02_t05: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/16_Getter_Lookup_A02_t06: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A01_t07: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A04_t09: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/02_Expression_Statements_A01_t13: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/first_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/reduce_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isAccessor_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isAccessor_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isGetter_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isGetter_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isMethod_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isMethod_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isSetter_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isSetter_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/memberName_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/namedArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/RuneIterator/currentAsString_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/RuneIterator/current_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/isEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/isNotEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/lastWhere_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/length_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: Fail # co19-roll r607: Please triage this failure
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 4a00538..cb338fd 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -3,9 +3,6 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2analyzer ]
-# not clear: g([var foo = foo + 10]) is parameter 'foo' in the scope of its own initialzer?
-Language/06_Functions/2_Formal_Parameters_A02_t02: fail
-
# not clear: null..[1](1)[2](2).foo(3, bar: 4)=5 - it seems that verything before =5 it not assignable
Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: fail
@@ -32,55 +29,18 @@
# 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
-
-# co19 issue #380, Strings class has been removed
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
-
-# co19 issue #400, collection library reorg
-LibTest/core/String/concat_A01_t01: fail, OK
-LibTest/core/String/concat_A02_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
-Language/05_Variables/05_Variables_A12_t06: fail, OK
-Language/05_Variables/05_Variables_A13_t01: fail, OK
-Language/07_Classes/07_Classes_A02_t11: fail, OK
-
# co19 issue #442, undefined name "Expect"
Language/15_Types/4_Interface_Types_A08_t03: fail, OK
# co19 issue #455, undeclared identifier is static warning
Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t10: fail, OK
-Language/13_Statements/04_Local_Function_Declaration_A02_t02: fail, OK
Language/14_Libraries_and_Scripts/1_Imports_A02_t12: fail, OK
Language/14_Libraries_and_Scripts/1_Imports_A02_t15: fail, OK
-# 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
@@ -90,7 +50,6 @@
Language/12_Expressions/12_Instance_Creation_A01_t06: fail, OK
# co19 issue #433 (wrongly closed), missing @static-warning annotation
-Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t01: fail, OK
Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t07: fail, OK
# co19 issue #541: tests contain unqualified reference to static members defined in superclass
@@ -100,20 +59,51 @@
# co19 issue #543: invocation of a non-function
Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
-# 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
-
+Language/09_Mixins/1_Mixin_Application_A01_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/01_Constants_A22_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/07_Maps_A13_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/12_Instance_Creation_A01_t08: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A02_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A04_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A04_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t04: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t04: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/16_Getter_Lookup_A02_t05: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/16_Getter_Lookup_A02_t06: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A01_t07: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A04_t09: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/02_Expression_Statements_A01_t13: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/first_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/reduce_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isAccessor_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isAccessor_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isGetter_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isGetter_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isMethod_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isMethod_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isSetter_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isSetter_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/memberName_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/namedArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/RuneIterator/currentAsString_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/RuneIterator/current_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/isEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/isNotEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/lastWhere_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/length_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: Fail # co19-roll r607: Please triage this failure
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 3bd647f..5dcead1 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -10,13 +10,32 @@
[ $runtime == vm || $compiler == dart2dart || $compiler == dart2js ]
+Language/12_Expressions/05_Strings_A02_t46: fail, pass, ok # co19 issue 612
+Language/12_Expressions/05_Strings_A02_t48: fail, pass, ok # co19 issue 612
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
-LibTest/core/Uri/decodeQueryComponent_A02_t01: fail # co19 Issue 591
LibTest/core/Uri/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
# Maybe we should wait until isolate library is sealed before triaging these.
LibTest/isolate/isolate_api/spawnFunction_A04_t01: fail, timeout # co19-roll r546: Please triage this failure
LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: fail, timeout # co19-roll r546: Please triage this failure
+Language/15_Types/1_Static_Types_A03_t01: Fail # co19-roll r607: Please triage this failure
+
+Language/09_Mixins/1_Mixin_Application_A01_t01: CompileTimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: CompileTimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/first_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A01_t07: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A04_t09: RuntimeError # co19-roll r607: Please triage this failure
+Language/13_Statements/04_Local_Function_Declaration_A04_t01: MissingCompileTimeError # co19-roll r607: Please triage this failure
+Language/13_Statements/02_Expression_Statements_A01_t13: MissingCompileTimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Runes/lastWhere_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/forEach_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/reduce_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/namedArguments_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: RuntimeError # co19-roll r607: Please triage this failure
[ $runtime == vm || $compiler == dart2dart || $compiler == dart2js ]
LibTest/typed_data/ByteData/elementSizeInBytes_A01_t01: fail # co19-roll r569: Please triage this failure
@@ -32,21 +51,15 @@
LibTest/math/atan_A01_t01: PASS, FAIL, OK # co19 issue 44
LibTest/math/cos_A01_t01: PASS, FAIL, OK # co19 issue 44
LibTest/math/exp_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/max_A01_t03: FAIL, OK # co19 issue 467
-LibTest/math/min_A01_t03: FAIL, OK # co19 issue 467
LibTest/math/sin_A01_t01: PASS, FAIL, OK # co19 issue 44
LibTest/math/tan_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/collection/Queue/iterator_current_A01_t02: FAIL, OK # co19 issue 475
-
LibTest/core/double/ceil_A01_t03: FAIL, OK # co19 issue 389
LibTest/core/double/ceil_A01_t04: FAIL, OK # co19 issue 389
LibTest/core/double/floor_A01_t03: FAIL, OK # co19 issue 389
LibTest/core/double/floor_A01_t04: FAIL, OK # co19 issue 389
LibTest/core/double/round_A01_t02: FAIL, OK # co19 issue 389
LibTest/core/double/round_A01_t04: FAIL, OK # co19 issue 389
-LibTest/core/double/truncate_A01_t03: FAIL, OK # co19 issue 389
-LibTest/core/double/truncate_A01_t04: FAIL, OK # co19 issue 389
LibTest/async/Stream/Stream.periodic_A01_t01: TIMEOUT, PASS, FAIL, OK # co19 issue 538
LibTest/async/Stream/Stream.periodic_A03_t01: PASS, FAIL, OK # co19 issue 538
@@ -61,61 +74,19 @@
LibTest/isolate/SendPort/send_A02_t03: SKIP # co19 issue 495
LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: PASS, FAIL, OK # co19 issue 540
-LibTest/isolate/isolate_api/streamSpawnFunction_A02_t03: PASS, FAIL, OK # co19 issue 540
LibTest/isolate/IsolateStream/contains_A02_t01: PASS, FAIL, OK # co19 issue 540
LibTest/async/EventTransformStream/listen_A04_t01: Pass, Timeout # co19 issue 542
LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Float32List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Float32x4List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Float32x4List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Float64List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Float64List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Int16List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Int16List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Int32List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Int32List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Int64List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Int64List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Int8List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Int8List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint16List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint16List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint32List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint32List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint64List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint64List/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint8ClampedList/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint8ClampedList/retainAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint8List/removeAll_A01_t01: Fail # co19 issue 548
-LibTest/typed_data/Uint8List/retainAll_A01_t01: Fail # co19 issue 548
-
-LibTest/core/String/concat_A01_t01: Fail # co19 issue 561
-LibTest/core/String/concat_A02_t01: Fail # co19 issue 561
-
-[ $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
-
### CHECKED MODE FAILURES ###
[ ($runtime == vm || $compiler == dart2js) && $checked]
Language/07_Classes/6_Constructors/2_Factories_A12_t02: fail # co19-roll r587: Please triage this failure
Language/13_Statements/09_Switch_A05_t01: FAIL, OK # co19 issue 498
-Language/14_Libraries_and_Scripts/1_Imports_A03_t26: FAIL, OK # co19 issue 498
Language/14_Libraries_and_Scripts/1_Imports_A03_t46: PASS, FAIL, OK # co19 issue 560
Language/14_Libraries_and_Scripts/1_Imports_A03_t66: PASS, FAIL, OK # co19 issue 560
-Language/15_Types/1_Static_Types_A03_t01: Fail # co19-roll r559: Please triage this failure
LibTest/async/EventTransformStream/contains_A01_t01: FAIL, OK # co19 issue 498
-LibTest/core/DateTime/compareTo_A02_t01: FAIL, OK # co19 issue 498
LibTest/core/List/removeAt_A02_t01: FAIL, OK # co19 issue 498
-LibTest/core/TypeError/column_A01_t01: FAIL, OK # co19 issue 510
-LibTest/core/TypeError/dstName_A01_t01: FAIL, OK # co19 issue 510
-LibTest/core/TypeError/dstType_A01_t01: FAIL, OK # co19 issue 510
-LibTest/core/TypeError/failedAssertion_A01_t01: FAIL, OK # co19 issue 510
-LibTest/core/TypeError/line_A01_t01: FAIL, OK # co19 issue 510
-LibTest/core/TypeError/srcType_A01_t01: FAIL, OK # co19 issue 510
-LibTest/core/TypeError/url_A01_t01: FAIL, OK # co19 issue 510
+LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 788a3df..5da24a9 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -4,6 +4,15 @@
[ $compiler == dart2dart ]
LibTest/async/Stream/Stream.periodic_A01_t01: Pass, Fail # Issue 12562.
+LibTest/core/Symbol/Symbol_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
+
+Language/12_Expressions/12_Instance_Creation/1_New_A04_t02: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: Pass, RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/memberName_A01_t01: Pass, RuntimeError # co18-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t03: Fail # TODO(dart2dart-team): Please triage this failure.
@@ -13,20 +22,9 @@
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_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_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
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A02_t02: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # inherited from VM
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: Fail # http://dartbug.com/5519
Language/06_Functions/4_External_Functions_A01_t01: Fail # inherited from VM
-Language/07_Classes/07_Classes_A02_t11: Fail # http://dartbug.com/5519
Language/07_Classes/3_Setters_A04_t01: Fail # inherited from VM
Language/07_Classes/3_Setters_A04_t02: Fail # inherited from VM
Language/07_Classes/3_Setters_A04_t03: Fail # inherited from VM
@@ -35,20 +33,17 @@
Language/07_Classes/3_Setters_A04_t06: Fail # inherited from VM
Language/07_Classes/3_Setters_A04_t07: Fail # inherited from VM
Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Fail # http://dartbug.com/5519
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t01: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t02: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t03: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t02: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t03: Fail # inherited from VM
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: Fail # Issue 13652
Language/07_Classes/6_Constructors_A02_t01: Fail # http://dartbug.com/5519
-Language/12_Expressions/07_Maps_A12_t03: Fail # http://dartbug.com/5519
+Language/12_Expressions/01_Constants_A03_t01: Fail # Issue 13652
+Language/13_Statements/09_Switch_A02_t04: Fail # co19 issue 605
+Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: Fail # co19 issue 606
+
LibTest/core/Match/operator_subscript_A01_t01: Fail # inherited from VM
LibTest/core/Match/operator_subscript_A01_t01: Fail, OK # co19 issue 294
LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # inherited from VM
LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail, OK # co19 issue 294
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # inherited from VM
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail # inherited from VM
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail
LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # inherited from VM
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # inherited from VM
@@ -66,14 +61,11 @@
LibTest/isolate/isolate_api/spawnUri_A01_t03: Fail, OK # Problems with the test: encoded file name
LibTest/isolate/isolate_api/spawnUri_A01_t04: Fail, OK # Problems with the test: encoded file name
LibTest/isolate/isolate_api/spawnUri_A01_t05: Fail, OK # Problems with the test: encoded file name
+LibTest/isolate/IsolateSink/add_A01_t01: CompileTimeError # Issue 13683
+LibTest/isolate/SendPort/send_A02_t01: CompileTimeError # Issue 13683
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
@@ -101,8 +93,6 @@
Language/14_Libraries_and_Scripts/1_Imports_A01_t17: Fail # co19 Issue 603
Language/14_Libraries_and_Scripts/1_Imports_A04_t01: Fail # co19 Issue 603
-Language/14_Libraries_and_Scripts/2_Exports_A05_t01: Fail # co19 Issue 604
-
# co19-roll r546 (11.08.2013) caused these failures
[ $compiler == dart2dart ]
@@ -124,60 +114,9 @@
Language/07_Classes/4_Abstract_Instance_Members_A03_t04: 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
-Language/12_Expressions/01_Constants_A03_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A03_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A03_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A05_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A05_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A05_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A08_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A09_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A10_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A10_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A11_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A11_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A11_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A12_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A12_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A14_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t06: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t07: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t08: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t09: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t10: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t11: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t12: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t13: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t14: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t15: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t16: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t17: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t18: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t20: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t21: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t31: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A16_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A17_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A17_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A17_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A19_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A19_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A19_t04: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/01_Constants_A20_t02: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/01_Constants_A20_t03: fail # co19-roll r546: Please triage this failure
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/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
-Language/12_Expressions/07_Maps_A02_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/12_Instance_Creation/1_New_A02_t03: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/12_Instance_Creation/1_New_A02_t05: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/12_Instance_Creation/1_New_A02_t06: fail # co19-roll r546: Please triage this failure
@@ -190,10 +129,6 @@
Language/12_Expressions/12_Instance_Creation/1_New_A06_t06: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/12_Instance_Creation/1_New_A09_t09: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/2_Const_A06_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/2_Const_A06_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A05_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/22_Equality_A01_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/22_Equality_A01_t19: fail # co19-roll r546: Please triage this failure
@@ -201,9 +136,6 @@
Language/12_Expressions/22_Equality_A05_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/27_Unary_Expressions_A01_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/30_Identifier_Reference_A02_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A04_t09: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A05_t12: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/30_Identifier_Reference_A08_t02: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/32_Type_Test_A04_t02: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/32_Type_Test_A04_t03: fail # co19-roll r546: Please triage this failure
@@ -221,7 +153,6 @@
Language/14_Libraries_and_Scripts/1_Imports_A03_t08: fail # co19-roll r546: Please triage this failure
Language/14_Libraries_and_Scripts/1_Imports_A03_t09: fail # co19-roll r546: Please triage this failure
Language/14_Libraries_and_Scripts/1_Imports_A03_t10: 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_t28: fail # co19-roll r546: Please triage this failure
Language/14_Libraries_and_Scripts/1_Imports_A03_t29: fail # co19-roll r546: Please triage this failure
Language/14_Libraries_and_Scripts/1_Imports_A03_t30: fail # co19-roll r546: Please triage this failure
@@ -257,4 +188,4 @@
LibTest/json/stringify_A02_t01: fail # co19-roll r587: Please triage this failure
LibTest/json/stringify_A03_t02: fail # co19-roll r587: Please triage this failure
LibTest/json/printOn_A02_t01: fail # co19-roll r587: Please triage this failure
-LibTest/json/printOn_A03_t02: fail # co19-roll r587: Please triage this failure
+LibTest/json/printOn_A03_t02: fail # co19-roll r587: Please triage this failure
\ No newline at end of file
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 9bc5de1..0021c0c 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -5,6 +5,7 @@
[ $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.
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
[ $compiler == dart2js && $checked && $runtime == ie9 ]
LibTest/core/Uri/encodeQueryComponent_A01_t02: Pass, Timeout # co19-roll r576: Please triage this failure
@@ -21,7 +22,6 @@
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/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
@@ -64,7 +64,7 @@
LibTest/isolate/isolate_api/spawnFunction_A03_t01: Fail, Pass # TODO(ahe): Please triage this failure.
LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail, Pass # TODO(ahe): Please triage this failure.
LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail, Pass # TODO(ahe): Please triage this failure.
-
+LibTest/core/Uri/Uri_A06_t03: Pass, Slow
[ $compiler == dart2js ]
@@ -101,10 +101,11 @@
LibTest/core/double/round_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
LibTest/core/int/operator_truncating_division_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # TODO(ngeoaffray): Please triage these failure.
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail # TODO(ngeoaffray): Please triage these failure.
[ $compiler == dart2js && $checked ]
Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t03: Fail # TODO(ahe): Please triage this failure.
+Language/15_Types/2_Dynamic_Type_System_A01_t02: RuntimeError # co19-roll r607: Please triage this failure
+Language/15_Types/8_Parameterized_Types_A03_t07: RuntimeError # co19-roll r607: Please triage this failure
[ $compiler == dart2js ]
@@ -127,8 +128,11 @@
LibTest/core/int/isOdd_A01_t01: RuntimeError, OK # co19 issue 277
LibTest/core/int/isEven_A01_t01: RuntimeError, OK # co19 issue 277
+Language/12_Expressions/01_Constants_A20_t03: MissingCompileTimeError # co19 Issue 611
+
[ $compiler == dart2js ]
-LibTest/isolate/SendPort/send_A02_t01: CompileTimeError # Compile-time error: error: not a compile-time constant
+LibTest/isolate/IsolateSink/add_A01_t01: CompileTimeError # Issue 13683
+LibTest/isolate/SendPort/send_A02_t01: CompileTimeError # Issue 13683
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.
@@ -223,19 +227,10 @@
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
-
Language/14_Libraries_and_Scripts/1_Imports_A01_t17: Fail # co19 Issue 603
Language/14_Libraries_and_Scripts/1_Imports_A04_t01: Fail # co19 Issue 603
-Language/14_Libraries_and_Scripts/2_Exports_A05_t01: Fail # co19 Issue 604
-
[ $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: RuntimeError, OK # This is not rejected by V8.
LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: RuntimeError, OK # co19 issue 92.
@@ -254,6 +249,10 @@
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 ]
+Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/02_Null_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/add_A01_t01: Pass, Timeout # co19-roll r607: Please triage this failure
LibTest/core/Uri/Uri_A06_t03: Pass, Timeout # Issue 13511
LibTest/math/cos_A01_t01: Fail # co19 issue 44
@@ -314,21 +313,7 @@
# Missing compile-time errors.
#
[ $compiler == dart2js ]
-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.
@@ -345,6 +330,9 @@
Language/07_Classes/3_Setters_A04_t06: CompileTimeError # http://dartbug.com/5023
Language/07_Classes/3_Setters_A04_t07: CompileTimeError # http://dartbug.com/5023
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: CompileTimeError # Issue 13652
+Language/12_Expressions/01_Constants_A03_t01: CompileTimeError # Issue 13652
+
[ $compiler == dart2js && $runtime == ie9 ]
# These are most likey due to the fact that IE9 doesn't support typed data
@@ -414,7 +402,6 @@
LibTest/typed_data/ByteData/setUint8_A01_t01: fail # co19-roll r569: Please triage this failure
LibTest/typed_data/ByteData/toString_A01_t01: fail # co19-roll r569: Please triage this failure
-
[ $compiler == dart2js ]
Language/03_Overview/1_Scoping_A02_t28: fail # co19-roll r559: Please triage this failure
Language/05_Variables/05_Variables_A05_t01: fail # co19-roll r546: Please triage this failure
@@ -427,8 +414,6 @@
Language/07_Classes/4_Abstract_Instance_Members_A03_t04: 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
-Language/12_Expressions/01_Constants_A03_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/03_Numbers_A01_t06: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/03_Numbers_A01_t09: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/05_Strings_A20_t01: fail # co19-roll r546: Please triage this failure
@@ -459,7 +444,6 @@
Language/14_Libraries_and_Scripts/1_Imports_A03_t08: fail # co19-roll r546: Please triage this failure
Language/14_Libraries_and_Scripts/1_Imports_A03_t09: fail # co19-roll r546: Please triage this failure
Language/14_Libraries_and_Scripts/1_Imports_A03_t10: 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_t28: fail # co19-roll r546: Please triage this failure
Language/14_Libraries_and_Scripts/1_Imports_A03_t29: fail # co19-roll r546: Please triage this failure
Language/14_Libraries_and_Scripts/1_Imports_A03_t30: fail # co19-roll r546: Please triage this failure
@@ -484,7 +468,6 @@
LibTest/isolate/isolate_api/spawnUri_A02_t02: fail # co19-roll r546: Please triage this failure
LibTest/isolate/isolate_api/spawnUri_A02_t03: fail # co19-roll r546: Please triage this failure
LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateSink/add_A01_t01: fail # co19-roll r546: Please triage this failure
LibTest/isolate/IsolateSink/addError_A01_t01: fail # co19-roll r546: Please triage this failure
LibTest/isolate/IsolateSink/addError_A01_t02: fail # co19-roll r546: Please triage this failure
LibTest/isolate/IsolateStream/any_A02_t01: fail # co19-roll r546: Please triage this failure
@@ -532,6 +515,7 @@
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
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: CompileTimeError # co19-roll r607: Please triage this failure
[ $compiler == dart2js && $checked ]
Language/10_Generics/09_Generics_A03_t01: fail # co19-roll r546: Please triage this failure
@@ -540,7 +524,6 @@
Language/12_Expressions/06_Lists_A09_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/06_Lists_A09_t04: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/07_Maps_A10_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A11_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/12_Instance_Creation/1_New_A07_t01: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/12_Instance_Creation/1_New_A12_t02: fail # co19-roll r546: Please triage this failure
Language/12_Expressions/12_Instance_Creation/2_Const_A09_t02: Fail # co19-roll r559: Please triage this failure
@@ -595,6 +578,9 @@
LibTest/async/Timer/Timer_A01_t01: fail # co19-roll r546: Please triage this failure
LibTest/typed_data/Float32x4List/Float32x4List.view_A01_t02: fail # co19-roll r587: Please triage this failure
LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: fail # co19-roll r587: Please triage this failure
+Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/02_Null_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: RuntimeError # co19-roll r607: Please triage this failure
[ $compiler == dart2js && $minified ]
Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: fail # co19-roll r559: Please triage this failure
@@ -627,10 +613,12 @@
Language/07_Classes/6_Constructors/2_Factories_A10_t02: fail # co19-roll r587: Please triage this failure
Language/07_Classes/6_Constructors/2_Factories_A10_t03: fail # co19-roll r587: Please triage this failure
Language/10_Generics/09_Generics_A01_t17: fail # co19-roll r587: Please triage this failure
+Language/15_Types/5_Function_Types_A07_t01: CompileTimeError # co19-roll r607: Please triage this failure
+Language/15_Types/5_Function_Types_A07_t01: CompileTimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/07_Maps_A13_t01: MissingCompileTimeError # co19-roll r607: Please triage this failure
[ $compiler == dart2js ]
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: fail # co19-roll r587: Please triage this failure
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: fail # co19-roll r587: Please triage this failure
LibTest/json/stringify_A01_t01: fail # co19-roll r587: Please triage this failure
LibTest/json/stringify_A02_t01: fail # co19-roll r587: Please triage this failure
LibTest/json/printOn_A01_t01: fail # co19-roll r587: Please triage this failure
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
new file mode 100644
index 0000000..471d509
--- /dev/null
+++ b/tests/co19/co19-dartium.status
@@ -0,0 +1,117 @@
+# 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.
+
+[ $compiler == none && $runtime == dartium ]
+Language/03_Overview/2_Privacy_A01_t06: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A05_t01: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A05_t02: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t01: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t02: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t03: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t04: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t05: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t06: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A16_t02: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Issue 13719: Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Fail # Issue 13719: Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: Fail # Issue 13719: Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: Fail # Issue 13719: Please triage this failure.
+Language/09_Mixins/1_Mixin_Application_A01_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/01_Constants_A16_t01: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/01_Constants_A16_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/01_Constants_A16_t04: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/01_Constants_A16_t05: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/12_Instance_Creation/1_New_A09_t09: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/18_Assignment_A01_t07: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A04_t09: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/30_Identifier_Reference_A08_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/32_Type_Test_A04_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/32_Type_Test_A04_t03: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/32_Type_Test_A04_t04: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/33_Type_Cast_A03_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/33_Type_Cast_A03_t03: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/02_Expression_Statements_A01_t13: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t01: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t02: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t05: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t06: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t07: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/03_Variable_Declaration_A04_t08: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/04_Local_Function_Declaration_A04_t01: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/06_For_A01_t11: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/09_Switch_A01_t02: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/09_Switch_A02_t04: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/12_Labels_A01_t03: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/2_Exports_A04_t02: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/2_Exports_A04_t03: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/4_Scripts_A03_t02: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t04: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t05: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t14: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t15: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t24: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t25: Fail # Issue 13719: Please triage this failure.
+Language/15_Types/1_Static_Types_A03_t01: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail # co19-roll r607: Please triage this failure
+LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Issue 13719: Please triage this failure.
+LibTest/async/Stream/Stream.periodic_A01_t01: Timeout # Issue 13719: Please triage this failure.
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/first_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/forEach_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/reduce_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/DateTime/parse_A03_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/ceil_A01_t03: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/ceil_A01_t04: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/floor_A01_t03: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/floor_A01_t04: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/round_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/round_A01_t04: Fail # Issue 13719: Please triage this failure.
+LibTest/core/int/toRadixString_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/Invocation/namedArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Match/operator_subscript_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/firstMatch_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A03_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/lastWhere_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t03: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t05: Fail # co19-roll r607: Please triage this failure
+LibTest/isolate/isolate_api/spawnFunction_A04_t01: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnFunction_A04_t02: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnFunction_A04_t03: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t01: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t02: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t03: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t04: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t05: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/IsolateSink/addError_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/IsolateSink/addError_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/IsolateStream/any_A02_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/ReceivePort/receive_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/SendPort/send_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/typed_data/ByteData/elementSizeInBytes_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/typed_data/Float32x4/clamp_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: Fail # Issue 13719: Please triage this failure.
\ No newline at end of file
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 719fc5d..6796d88 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -2,13 +2,13 @@
# 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.
-[ $runtime == vm ]
+[ $compiler == none && $runtime == vm ]
Language/12_Expressions/01_Constants_A16_t04: fail # Issue 392
Language/12_Expressions/01_Constants_A16_t05: fail # Issue 392
-
-[ $runtime == vm && $system == windows ]
-LibTest/core/Stopwatch/elapsed_A01_t01: Pass, Fail # Issue 11382.
-LibTest/core/Stopwatch/elapsed_A01_t03: Pass, Fail # Issue 12383.
+Language/13_Statements/03_Variable_Declaration_A04_t01: MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t02: MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t05: MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t06: MissingCompileTimeError # Issue 7052
[ $compiler == none && $runtime == vm ]
Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Dart issue 5802
@@ -18,7 +18,6 @@
LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # Issue 12508
LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Issue 12508
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # Issue 12508
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail # Issue 12508
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 12508
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # Issue 12508
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 12508
@@ -70,12 +69,10 @@
Language/05_Variables/05_Variables_A06_t06: fail # Dart issue 12543
Language/05_Variables/05_Variables_A16_t02: fail # Dart issue 12544
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/00_Object_Identity/1_Object_Identity_A04_t02: fail # co19 issue 606
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
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A05_t01: fail # Dart issue 12550
Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: fail # Dart issue 12549
Language/12_Expressions/30_Identifier_Reference_A08_t02: fail # Dart issue 12593
Language/12_Expressions/32_Type_Test_A04_t02: fail # co19 issue 503
@@ -86,12 +83,11 @@
Language/13_Statements/03_Variable_Declaration_A04_t07: fail # co19 issue 535
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_A02_t04: fail # co19 issue 605
Language/13_Statements/09_Switch_A01_t02: fail # Dart issue 12908
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_t04: fail # Issue 12521
Language/14_Libraries_and_Scripts/5_URIs_A01_t05: fail # Issue 12521
Language/14_Libraries_and_Scripts/5_URIs_A01_t14: fail # Issue 12521
@@ -136,6 +132,7 @@
LibTest/typed_data/Float32x4List/skip_A01_t01: Fail # Dart issue 12861
LibTest/typed_data/Float32x4List/take_A01_t01: Fail # Dart issue 12861
LibTest/typed_data/Float32x4List/take_A02_t01: Fail # Dart issue 12861
+Language/12_Expressions/12_Instance_Creation_A01_t08: CompileTimeError # co19-roll r607: Please triage this failure
[ $compiler == none && $runtime == vm && $system == windows && $mode == debug ]
Language/15_Types/4_Interface_Types_A11_t01: pass, timeout # Issue 13349
@@ -146,8 +143,15 @@
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
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: MissingCompileTimeError # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: MissingCompileTimeError # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
+
+[ $compiler == none && $runtime == vm && $mode == debug && $checked ]
+LibTest/collection/LinkedList/add_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/iterator_current_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/single_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
diff --git a/tests/co19/test_config.dart b/tests/co19/test_config.dart
index 547ea88..d37b5fa 100644
--- a/tests/co19/test_config.dart
+++ b/tests/co19/test_config.dart
@@ -20,7 +20,8 @@
"tests/co19/co19-analyzer2.status",
"tests/co19/co19-runtime.status",
"tests/co19/co19-dart2dart.status",
- "tests/co19/co19-dart2js.status"]);
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartium.status"]);
bool isTestFile(String filename) => _testRegExp.hasMatch(filename);
bool get listRecursively => true;
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 8af47af..3e76675 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -148,14 +148,13 @@
element = compiler.coreLibrary.find(sourceName);
}
Expect.isNotNull(element, 'Could not locate $name');
- var dartType = element.computeType(compiler);
switch (how) {
- case 'exact': return new types.TypeMask.exact(dartType);
- case 'nonNullExact': return new types.TypeMask.nonNullExact(dartType);
- case 'subclass': return new types.TypeMask.subclass(dartType);
- case 'nonNullSubclass': return new types.TypeMask.nonNullSubclass(dartType);
- case 'subtype': return new types.TypeMask.subtype(dartType);
- case 'nonNullSubtype': return new types.TypeMask.nonNullSubtype(dartType);
+ case 'exact': return new types.TypeMask.exact(element);
+ case 'nonNullExact': return new types.TypeMask.nonNullExact(element);
+ case 'subclass': return new types.TypeMask.subclass(element);
+ case 'nonNullSubclass': return new types.TypeMask.nonNullSubclass(element);
+ case 'subtype': return new types.TypeMask.subtype(element);
+ case 'nonNullSubtype': return new types.TypeMask.nonNullSubtype(element);
}
Expect.fail('Unknown HType constructor $how');
}
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index ab3b4be..044d9f3 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -1375,7 +1375,7 @@
final String source2 = r"""
import 'dart:foreign';
-
+
main () {
var x = "__dynamic_for_test".truncate();
JS('double', 'foo');
@@ -1480,24 +1480,24 @@
for (ClassElement cls in [a, b, c, d]) {
Expect.equals(convert(singleton(cls)),
- new TypeMask.nonNullExact(cls.rawType));
+ new TypeMask.nonNullExact(cls));
}
for (ClassElement cls in [a, b, c, d]) {
Expect.equals(convert(singleton(cls).union(nullSingleton)),
- new TypeMask.exact(cls.rawType));
+ new TypeMask.exact(cls));
}
Expect.equals(convert(singleton(a).union(singleton(b))),
- new TypeMask.nonNullSubclass(a.rawType));
+ new TypeMask.nonNullSubclass(a));
Expect.equals(
convert(singleton(a).union(singleton(b)).union(nullSingleton)),
- new TypeMask.subclass(a.rawType));
+ new TypeMask.subclass(a));
Expect.equals(
convert(singleton(b).union(singleton(d))).simplify(result.compiler),
- new TypeMask.nonNullSubtype(a.rawType));
+ new TypeMask.nonNullSubtype(a));
});
}
@@ -1545,20 +1545,20 @@
Expect.equals(
inferredType(foo).simplify(result.compiler),
- new TypeMask.nonNullSubclass(abc.rawType));
+ new TypeMask.nonNullSubclass(abc));
Expect.equals(
- inferredType(new TypedSelector.subclass(x.rawType, foo)),
- new TypeMask.nonNullExact(b.rawType));
+ inferredType(new TypedSelector.subclass(x, foo)),
+ new TypeMask.nonNullExact(b));
Expect.equals(
- inferredType(new TypedSelector.subclass(y.rawType, foo)),
- new TypeMask.nonNullExact(c.rawType));
+ inferredType(new TypedSelector.subclass(y, foo)),
+ new TypeMask.nonNullExact(c));
Expect.equals(
- inferredType(new TypedSelector.subclass(z.rawType, foo)),
- new TypeMask.nonNullExact(a.rawType));
+ inferredType(new TypedSelector.subclass(z, foo)),
+ new TypeMask.nonNullExact(a));
Expect.equals(
inferredType(new TypedSelector.subclass(
- xy.rawType, foo)).simplify(result.compiler),
- new TypeMask.nonNullSubclass(bc.rawType));
+ xy, foo)).simplify(result.compiler),
+ new TypeMask.nonNullSubclass(bc));
Selector bar = new Selector.call(buildSourceString("bar"), null, 0);
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index 508010c..5469890 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -269,14 +269,14 @@
'var globalVarInitialized=6,globalVarInitialized2=7;'
'class A{A(){}A.fromFoo(){}static staticfoo(){}foo(){}'
'static const field=5;}'
- 'p_globalfoo(){}'
- 'var p_globalVar;var p_globalVarInitialized=6,p_globalVarInitialized2=7;'
- 'class p_A{p_A(){}p_A.p_fromFoo(){}static p_staticfoo(){}foo(){}'
- 'static const p_field=5;}'
- 'main(){p_globalVar;p_globalVarInitialized;'
- 'p_globalVarInitialized2;p_globalfoo();'
- 'p_A.p_field;p_A.p_staticfoo();'
- 'new p_A();new p_A.p_fromFoo();new p_A().foo();'
+ 'A_globalfoo(){}'
+ 'var A_globalVar;var A_globalVarInitialized=6,A_globalVarInitialized2=7;'
+ 'class A_A{A_A(){}A_A.A_fromFoo(){}static A_staticfoo(){}foo(){}'
+ 'static const A_field=5;}'
+ 'main(){A_globalVar;A_globalVarInitialized;'
+ 'A_globalVarInitialized2;A_globalfoo();'
+ 'A_A.A_field;A_A.A_staticfoo();'
+ 'new A_A();new A_A.A_fromFoo();new A_A().foo();'
'globalVar;globalVarInitialized;globalVarInitialized2;globalfoo();'
'A.field;A.staticfoo();'
'new A();new A.fromFoo();new A().foo();}';
@@ -383,11 +383,11 @@
var expectedResult =
'topfoo(){}'
'class A{foo(){}}'
- 'p_topfoo(){var x=5;}'
- 'class p_A{num foo(){}p_A.fromFoo(){}A myliba;List<p_A> mylist;}'
+ 'A_topfoo(){var x=5;}'
+ 'class A_A{num foo(){}A_A.fromFoo(){}A myliba;List<A_A> mylist;}'
'A getA()=>null;'
- 'main(){var a=new A();a.foo();var b=new p_A.fromFoo();b.foo();'
- 'var GREATVAR=b.myliba;b.mylist;a=getA();p_topfoo();topfoo();}';
+ 'main(){var a=new A();a.foo();var b=new A_A.fromFoo();b.foo();'
+ 'var GREATVAR=b.myliba;b.mylist;a=getA();A_topfoo();topfoo();}';
testDart2DartWithLibrary(mainSrc, librarySrc,
continuation: (String result) { Expect.equals(expectedResult, result); });
}
@@ -426,9 +426,9 @@
var expectedResult =
'get topgetset=>5;'
'set topgetset(arg){}'
- 'get p_topgetset=>6;'
- 'set p_topgetset(arg){}'
- 'main(){p_topgetset;p_topgetset=6;topgetset;topgetset=5;}';
+ 'get A_topgetset=>6;'
+ 'set A_topgetset(arg){}'
+ 'main(){A_topgetset;A_topgetset=6;topgetset;topgetset=5;}';
testDart2DartWithLibrary(mainSrc, librarySrc,
continuation: (String result) { Expect.equals(expectedResult, result); });
}
@@ -504,12 +504,12 @@
'class T{}'
'class B<T>{}'
'class A<T> extends B<T>{T f;}'
- 'typedef void p_MyFunction<p_T extends num>(p_T arg);'
- 'class p_T{}'
- 'class p_B<p_T>{}'
- 'class p_A<p_T> extends p_B<p_T>{p_T f;}'
- 'main(){p_MyFunction myf1;MyFunction myf2;new p_A<int>().f;'
- 'new p_T();new A<int>().f;new T();}';
+ 'typedef void A_MyFunction<A_T extends num>(A_T arg);'
+ 'class A_T{}'
+ 'class A_B<A_T>{}'
+ 'class A_A<A_T> extends A_B<A_T>{A_T f;}'
+ 'main(){A_MyFunction myf1;MyFunction myf2;new A_A<int>().f;'
+ 'new A_T();new A<int>().f;new T();}';
testDart2DartWithLibrary(mainSrc, librarySrc,
continuation: (String result) { Expect.equals(expectedResult, result); });
}
@@ -536,9 +536,9 @@
var expectedResult =
'class I{}'
'class A<T extends I>{}'
- 'class p_I{}'
- 'class p_A<p_T extends p_I>{}'
- 'main(){new p_A();new A();}';
+ 'class A_I{}'
+ 'class A_A<A_T extends A_I>{}'
+ 'main(){new A_A();new A();}';
testDart2DartWithLibrary(mainSrc, librarySrc,
continuation: (String result) { Expect.equals(expectedResult, result); });
}
@@ -555,8 +555,8 @@
}
''';
var expectedResult =
- 'p_main(){}'
- 'main(){p_main();}';
+ 'A_main(){}'
+ 'main(){A_main();}';
testDart2DartWithLibrary(mainSrc, librarySrc,
continuation: (String result) { Expect.equals(expectedResult, result); });
}
@@ -667,8 +667,8 @@
}
''';
var expectedResult = 'import "dart:html" as p;'
- 'class A{static String get p_userAgent=>p.window.navigator.userAgent;}'
- 'main(){A.p_userAgent;}';
+ 'class A{static String get A_userAgent=>p.window.navigator.userAgent;}'
+ 'main(){A.A_userAgent;}';
testDart2Dart(src,
continuation: (String result) { Expect.equals(expectedResult, result); });
}
@@ -684,8 +684,8 @@
print('local');
}
''';
- var expectedResult = "p_print(x){throw 'fisk';}"
- "main(){print('corelib');p_print('local');}";
+ var expectedResult = "A_print(x){throw 'fisk';}"
+ "main(){print('corelib');A_print('local');}";
testDart2Dart(src,
continuation: (String result) { Expect.equals(expectedResult, result); });
}
@@ -701,7 +701,7 @@
new A.named();
}
''';
- var expectedResult = "class A{A(){}}main(){new A();new p_Unresolved();}";
+ var expectedResult = "class A{A(){}}main(){new A();new A_Unresolved();}";
testDart2Dart(src,
continuation: (String result) { Expect.equals(expectedResult, result); });
}
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 4aee0ac..7961fe6 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -515,7 +515,7 @@
runTest(TEST_15, {'f': (compiler) {
ClassElement cls =
compiler.typesTask.compiler.backend.jsIndexableClass;
- return new TypeMask.nonNullSubtype(cls.rawType);
+ return new TypeMask.nonNullSubtype(cls);
}});
runTest(TEST_16, {'f': subclassOfInterceptor});
runTest(TEST_17, {'f': (compiler) => compiler.typesTask.intType.nullable()});
diff --git a/tests/compiler/dart2js/licm_test.dart b/tests/compiler/dart2js/licm_test.dart
index 0b16cba..3e1a98a 100644
--- a/tests/compiler/dart2js/licm_test.dart
+++ b/tests/compiler/dart2js/licm_test.dart
@@ -25,6 +25,6 @@
''';
main() {
- compileAndMatch(
- TEST, 'main', new RegExp("if \\(count == null\\)(.|\\n)*while"));
+ compileAndMatch(TEST, 'main',
+ new RegExp('if \\(typeof count !== "number"\\)(.|\\n)*while'));
}
diff --git a/tests/compiler/dart2js/list_tracer_node_type_test.dart b/tests/compiler/dart2js/list_tracer_node_type_test.dart
index dfefd9b..4296d74 100644
--- a/tests/compiler/dart2js/list_tracer_node_type_test.dart
+++ b/tests/compiler/dart2js/list_tracer_node_type_test.dart
@@ -68,26 +68,19 @@
main() {
asyncTest(() => compileAll(TEST1).then((generated) {
- // Check that we only do a null check on the receiver for
- // [: a[0] + 42 :]. We can do a null check because we inferred that
- // the list is of type int or null.
- Expect.isFalse(generated.contains('if (typeof t1'));
- Expect.isTrue(generated.contains('if (t1 == null)'));
+ Expect.isTrue(generated.contains('if (typeof t1'));
}));
asyncTest(() => compileAll(TEST2).then((generated) {
- Expect.isFalse(generated.contains('if (typeof t1'));
- Expect.isTrue(generated.contains('if (t1 == null)'));
+ Expect.isTrue(generated.contains('if (typeof t1'));
}));
asyncTest(() => compileAll(TEST3).then((generated) {
- Expect.isFalse(generated.contains('if (typeof t1'));
- Expect.isTrue(generated.contains('if (t1 == null)'));
+ Expect.isTrue(generated.contains('if (typeof t1'));
}));
asyncTest(() => compileAll(TEST4).then((generated) {
- Expect.isFalse(generated.contains('if (typeof t1'));
- Expect.isTrue(generated.contains('if (t1 == null)'));
+ Expect.isTrue(generated.contains('if (typeof t1'));
}));
asyncTest(() => compileAll(TEST5).then((generated) {
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index 936dd17..5668c63 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -222,12 +222,13 @@
checkType('listPassedToClosure', typesTask.dynamicType);
checkType('listReturnedFromClosure', typesTask.dynamicType);
checkType('listUsedWithNonOkSelector', typesTask.dynamicType);
- checkType('listPassedAsOptionalParameter', typesTask.dynamicType);
- checkType('listPassedAsNamedParameter', typesTask.dynamicType);
+ checkType('listPassedAsOptionalParameter', typesTask.numType);
+ checkType('listPassedAsNamedParameter', typesTask.numType);
if (!allocation.contains('filled')) {
checkType('listUnset', new TypeMask.nonNullEmpty());
- checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
+ // TODO(ngeoffray): Re-enable this test.
+ // checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
}
}));
}
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 065da51..1f25936 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -92,20 +92,14 @@
});
}
- // There should at least be three metadata constants:
- // 1. The type literal 'Foo'.
- // 2. The list 'const [Foo]'.
- // 3. The constructed constant for 'MirrorsUsed'.
- Expect.isTrue(compiler.metadataHandler.compiledConstants.length >= 3);
+ // There should at least be one metadata constant:
+ // 1. The constructed constant for 'MirrorsUsed'.
+ Expect.isTrue(compiler.backend.metadataConstants.length >= 1);
// Make sure that most of the metadata constants aren't included in the
// generated code.
- for (Constant constant in compiler.metadataHandler.compiledConstants) {
- if (constant is TypeConstant && '${constant.representedType}' == 'Foo') {
- // The type literal 'Foo' is retained as a constant because it is being
- // passed to reflectClass.
- continue;
- }
+ for (var dependency in compiler.backend.metadataConstants) {
+ Constant constant = dependency.constant;
Expect.isFalse(
compiler.constantHandler.compiledConstants.contains(constant),
'$constant');
@@ -114,7 +108,7 @@
// The type literal 'Foo' is both used as metadata, and as a plain value in
// the program. Make sure that it isn't duplicated.
int fooConstantCount = 0;
- for (Constant constant in compiler.metadataHandler.compiledConstants) {
+ for (Constant constant in compiler.constantHandler.compiledConstants) {
if (constant is TypeConstant && '${constant.representedType}' == 'Foo') {
fooConstantCount++;
}
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 5fb2d85..73eea5c 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -250,6 +250,7 @@
// Set up the library imports.
importHelperLibrary(coreLibrary);
libraryLoader.importLibrary(jsHelperLibrary, coreLibrary, null);
+ libraryLoader.importLibrary(foreignLibrary, coreLibrary, null);
libraryLoader.importLibrary(interceptorsLibrary, coreLibrary, null);
libraryLoader.importLibrary(isolateHelperLibrary, coreLibrary, null);
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 9881810..34bf187 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -730,7 +730,7 @@
// typed selector.
var selector = new Selector.call(
buildSourceString('method'), compiler.coreLibrary, 0);
- var typedSelector = new TypedSelector.exact(cls.rawType, selector);
+ var typedSelector = new TypedSelector.exact(cls, selector);
Element method =
cls.implementation.lookupLocalMember(buildSourceString('method'));
Expect.isTrue(selector.applies(method, compiler));
@@ -740,7 +740,7 @@
// for a typed selector.
selector = new Selector.call(
buildSourceString('clear'), compiler.coreLibrary, 0);
- typedSelector = new TypedSelector.exact(cls.rawType, selector);
+ typedSelector = new TypedSelector.exact(cls, selector);
method = cls.lookupLocalMember(buildSourceString('clear'));
Expect.isTrue(selector.applies(method, compiler));
Expect.isTrue(typedSelector.applies(method, compiler));
@@ -749,7 +749,7 @@
// for a typed selector on a subclass.
cls = ensure(compiler, "B", compiler.coreLibrary.find);
cls.ensureResolved(compiler);
- typedSelector = new TypedSelector.exact(cls.rawType, selector);
+ typedSelector = new TypedSelector.exact(cls, selector);
Expect.isTrue(selector.applies(method, compiler));
Expect.isTrue(typedSelector.applies(method, compiler));
}));
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index a8093aa..4746044 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -145,6 +145,6 @@
typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
}
var cls = findElement(compiler, 'A');
- checkReturnInClass('A', 'foo', new TypeMask.nonNullExact(cls.rawType));
+ checkReturnInClass('A', 'foo', new TypeMask.nonNullExact(cls));
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 45b882a..879f819 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -505,6 +505,39 @@
return a;
}
+testReturnNull1(a) {
+ if (a == null) return a;
+ return null;
+}
+
+testReturnNull2(a) {
+ if (a != null) return null;
+ return a;
+}
+
+testReturnNull3(a) {
+ if (a == null) return 42;
+ return a;
+}
+
+testReturnNull4() {
+ var a = topLeveGetter();
+ if (a == null) return a;
+ return null;
+}
+
+testReturnNull5() {
+ var a = topLeveGetter();
+ if (a != null) return null;
+ return a;
+}
+
+testReturnNull6() {
+ var a = topLeveGetter();
+ if (a == null) return 42;
+ return a;
+}
+
testReturnInvokeDynamicGetter() => new A().myFactory();
var topLevelConstList = const [42];
@@ -656,6 +689,12 @@
testSpecialization1();
testSpecialization2();
testSpecialization3();
+ testReturnNull1(topLevelGetter());
+ testReturnNull2(topLevelGetter());
+ testReturnNull3(topLevelGetter());
+ testReturnNull4();
+ testReturnNull5();
+ testReturnNull6();
}
""";
@@ -692,7 +731,7 @@
checkReturn('returnInt8', typesTask.intType);
checkReturn('returnEmpty1', const TypeMask.nonNullEmpty());
checkReturn('returnEmpty2', const TypeMask.nonNullEmpty());
- TypeMask intType = new TypeMask.nonNullSubtype(compiler.intClass.rawType);
+ TypeMask intType = new TypeMask.nonNullSubtype(compiler.intClass);
checkReturn('testIsCheck1', intType);
checkReturn('testIsCheck2', intType);
checkReturn('testIsCheck3', intType.nullable());
@@ -725,7 +764,7 @@
checkReturn('testIf1', typesTask.intType.nullable());
checkReturn('testIf2', typesTask.intType.nullable());
checkReturn('returnAsString',
- new TypeMask.subtype(compiler.stringClass.computeType(compiler)));
+ new TypeMask.subtype(compiler.stringClass));
checkReturn('returnIntAsNum', typesTask.intType);
checkReturn('returnAsTypedef', typesTask.functionType.nullable());
checkReturn('returnTopLevelGetter', typesTask.intType);
@@ -780,16 +819,22 @@
checkFactoryConstructor(String className, String factoryName) {
var cls = findElement(compiler, className);
var element = cls.localLookup(buildSourceString(factoryName));
- Expect.equals(new TypeMask.nonNullExact(cls.rawType),
+ Expect.equals(new TypeMask.nonNullExact(cls),
typesInferrer.getReturnTypeOfElement(element));
}
checkFactoryConstructor('A', '');
checkReturn('testCascade1', typesTask.growableListType);
checkReturn('testCascade2', new TypeMask.nonNullExact(
- findElement(compiler, 'CascadeHelper').rawType));
+ findElement(compiler, 'CascadeHelper')));
checkReturn('testSpecialization1', typesTask.numType);
checkReturn('testSpecialization2', typesTask.dynamicType);
checkReturn('testSpecialization3', typesTask.intType.nullable());
+ checkReturn('testReturnNull1', typesTask.nullType);
+ checkReturn('testReturnNull2', typesTask.nullType);
+ checkReturn('testReturnNull3', typesTask.dynamicType);
+ checkReturn('testReturnNull4', typesTask.nullType);
+ checkReturn('testReturnNull5', typesTask.nullType);
+ checkReturn('testReturnNull6', typesTask.dynamicType);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index aa29c72..55ed3a7 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -183,7 +183,7 @@
checkReturn('returnInt4', typesTask.intType);
checkReturn('returnInt5', typesTask.intType);
checkReturn('returnInt6',
- new TypeMask.nonNullSubtype(compiler.intClass.rawType));
+ new TypeMask.nonNullSubtype(compiler.intClass));
var subclassOfInterceptor =
findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index f1a1366..8947932 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -518,7 +518,7 @@
rule(jsIndexable, nonPrimitive1, CONFLICTING);
rule(jsIndexable, nonPrimitive2, CONFLICTING);
rule(jsIndexable, potentialArray, new HType.nonNullSubtype(
- compiler.backend.jsArrayClass.computeType(compiler), compiler));
+ compiler.backend.jsArrayClass, compiler));
rule(jsIndexable, potentialString, jsString);
rule(jsIndexable, BOOLEAN_OR_NULL, CONFLICTING);
rule(jsIndexable, NUMBER_OR_NULL, CONFLICTING);
@@ -668,7 +668,7 @@
void testRegressions(MockCompiler compiler) {
HType nonNullPotentialString = new HType.nonNullSubtype(
- patternClass.computeType(compiler), compiler);
+ patternClass, compiler);
Expect.equals(
potentialString, jsStringOrNull.union(nonNullPotentialString, compiler));
}
@@ -690,41 +690,41 @@
patternClass = compiler.coreLibrary.find(buildSourceString('Pattern'));
nonPrimitive1 = new HType.nonNullSubtype(
- compiler.mapClass.computeType(compiler), compiler);
+ compiler.mapClass, compiler);
nonPrimitive2 = new HType.nonNullSubtype(
- compiler.functionClass.computeType(compiler), compiler);
+ compiler.functionClass, compiler);
potentialArray = new HType.subtype(
- compiler.listClass.computeType(compiler), compiler);
+ compiler.listClass, compiler);
potentialString = new HType.subtype(
- patternClass.computeType(compiler), compiler);
+ patternClass, compiler);
jsInterceptor = new HType.nonNullSubclass(
- compiler.backend.jsInterceptorClass.computeType(compiler), compiler);
+ compiler.backend.jsInterceptorClass, compiler);
jsArrayOrNull = new HType.subclass(
- compiler.backend.jsArrayClass.computeType(compiler), compiler);
+ compiler.backend.jsArrayClass, compiler);
jsReadableArray = new HType.nonNullSubclass(
- compiler.backend.jsArrayClass.computeType(compiler), compiler);
+ compiler.backend.jsArrayClass, compiler);
jsMutableArrayOrNull = new HType.subclass(
- compiler.backend.jsMutableArrayClass.computeType(compiler), compiler);
+ compiler.backend.jsMutableArrayClass, compiler);
jsMutableArray = new HType.nonNullSubclass(
- compiler.backend.jsMutableArrayClass.computeType(compiler), compiler);
+ compiler.backend.jsMutableArrayClass, compiler);
jsFixedArrayOrNull = new HType.exact(
- compiler.backend.jsFixedArrayClass.computeType(compiler), compiler);
+ compiler.backend.jsFixedArrayClass, compiler);
jsFixedArray = new HType.nonNullExact(
- compiler.backend.jsFixedArrayClass.computeType(compiler), compiler);
+ compiler.backend.jsFixedArrayClass, compiler);
jsExtendableArrayOrNull = new HType.exact(
- compiler.backend.jsExtendableArrayClass.computeType(compiler), compiler);
+ compiler.backend.jsExtendableArrayClass, compiler);
jsExtendableArray = new HType.nonNullExact(
- compiler.backend.jsExtendableArrayClass.computeType(compiler), compiler);
+ compiler.backend.jsExtendableArrayClass, compiler);
jsIndexableOrNull = new HType.subtype(
- compiler.backend.jsIndexableClass.computeType(compiler), compiler);
+ compiler.backend.jsIndexableClass, compiler);
jsIndexable = new HType.nonNullSubtype(
- compiler.backend.jsIndexableClass.computeType(compiler), compiler);
+ compiler.backend.jsIndexableClass, compiler);
jsInterceptorOrNull = new HType.subclass(
- compiler.backend.jsInterceptorClass.computeType(compiler), compiler);
+ compiler.backend.jsInterceptorClass, compiler);
jsStringOrNull = new HType.exact(
- compiler.backend.jsStringClass.computeType(compiler), compiler);
+ compiler.backend.jsStringClass, compiler);
jsString = new HType.nonNullExact(
- compiler.backend.jsStringClass.computeType(compiler), compiler);
+ compiler.backend.jsStringClass, compiler);
testUnion(compiler);
testIntersection(compiler);
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index 5e6b7c5..e222971 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -94,7 +94,7 @@
// List
expect('$List_rep', List_.rawType);
// List<dynamic>
- expect('[$List_rep, null]', instantiate(List_, [dynamic_]));
+ expect('$List_rep', instantiate(List_, [dynamic_]));
// List<int>
expect('[$List_rep, $int_rep]', instantiate(List_, [int_]));
// List<Typedef>
@@ -102,11 +102,12 @@
instantiate(List_, [Typedef_]));
// Map<K,V>
- expect('[$Map_rep, $Map_K_rep, $Map_V_rep]', Map_.computeType(env.compiler));
+ expect('[$Map_rep, $Map_K_rep, $Map_V_rep]',
+ Map_.computeType(env.compiler));
// Map
expect('$Map_rep', Map_.rawType);
// Map<dynamic,dynamic>
- expect('[$Map_rep, null, null]', instantiate(Map_, [dynamic_, dynamic_]));
+ expect('$Map_rep', instantiate(Map_, [dynamic_, dynamic_]));
// Map<int,String>
expect('[$Map_rep, $int_rep, $String_rep]',
instantiate(Map_, [int_, String_]));
diff --git a/tests/compiler/dart2js/union_type_test.dart b/tests/compiler/dart2js/union_type_test.dart
index 2b48e04..7cc13ba 100644
--- a/tests/compiler/dart2js/union_type_test.dart
+++ b/tests/compiler/dart2js/union_type_test.dart
@@ -15,9 +15,9 @@
compiler.stringClass.ensureResolved(compiler);
FlatTypeMask mask1 =
- new FlatTypeMask.exact(new InterfaceType(compiler.intClass));
+ new FlatTypeMask.exact(compiler.intClass);
FlatTypeMask mask2 =
- new FlatTypeMask.exact(new InterfaceType(compiler.stringClass));
+ new FlatTypeMask.exact(compiler.stringClass);
UnionTypeMask union1 = mask1.nonNullable().union(mask2, compiler);
UnionTypeMask union2 = mask2.nonNullable().union(mask1, compiler);
Expect.equals(union1, union2);
diff --git a/tests/compiler/dart2js_extra/field_initializer_test.dart b/tests/compiler/dart2js_extra/field_initializer_test.dart
index cb4a34b..b06f763 100644
--- a/tests/compiler/dart2js_extra/field_initializer_test.dart
+++ b/tests/compiler/dart2js_extra/field_initializer_test.dart
@@ -15,7 +15,7 @@
static const i = false;
static const j = n;
static const k = 4.99;
- static const l;
+ static const l = null;
static const m = l;
static const n = 42;
}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 2c2c7b9..7902d5a 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -81,6 +81,7 @@
int_parse_radix_test: fail
list_insert_test: fail
list_removeat_test: fail
+symbol_test/01: fail # test issue 13730; It is static type warning if "const" instance creation argument type is not compatible with parameter type
[ $compiler == dart2analyzer ]
symbol_test/02: Fail
diff --git a/tests/html/custom/attribute_changed_callback_test.dart b/tests/html/custom/attribute_changed_callback_test.dart
index 955399f..3a9271a 100644
--- a/tests/html/custom/attribute_changed_callback_test.dart
+++ b/tests/html/custom/attribute_changed_callback_test.dart
@@ -3,13 +3,17 @@
// BSD-style license that can be found in the LICENSE file.
library attribute_changed_callback_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+
import 'dart:html';
+import 'dart:js' as js;
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import '../utils.dart';
class A extends HtmlElement {
static final tag = 'x-a';
factory A() => new Element.tag(tag);
+ A.created() : super.created();
static var attributeChangedInvocations = 0;
@@ -21,10 +25,11 @@
class B extends HtmlElement {
static final tag = 'x-b';
factory B() => new Element.tag(tag);
+ B.created() : super.created();
static var invocations = [];
- void created() {
+ void createdCallback() {
invocations.add('created');
}
@@ -33,44 +38,75 @@
}
}
+// Pump custom events polyfill events.
+void customElementsTakeRecords() {
+ if (js.context.hasProperty('CustomElements')) {
+ js.context['CustomElements'].callMethod('takeRecords');
+ }
+}
+
main() {
- useHtmlConfiguration();
+ useHtmlIndividualConfiguration();
// Adapted from Blink's fast/dom/custom/attribute-changed-callback test.
- test('transfer attribute changed callback', () {
- document.register(A.tag, A);
- var element = new A();
-
- element.attributes['a'] = 'b';
- expect(A.attributeChangedInvocations, 1);
+ var registered = false;
+ setUp(() {
+ return loadPolyfills().then((_) {
+ if (!registered) {
+ registered = true;
+ document.register(A.tag, A);
+ document.register(B.tag, B);
+ }
+ });
});
- test('add, change and remove an attribute', () {
- document.register(B.tag, B);
- var b = new B();
- b.id = 'x';
- expect(B.invocations, ['created', 'id: null => x']);
+ group('fully_supported', () {
+ test('transfer attribute changed callback', () {
+ var element = new A();
- B.invocations = [];
- b.attributes.remove('id');
- expect(B.invocations, ['id: x => null']);
+ element.attributes['a'] = 'b';
+ expect(A.attributeChangedInvocations, 1);
+ });
- B.invocations = [];
- b.attributes['data-s'] = 't';
- expect(B.invocations, ['data-s: null => t']);
+ test('add, change and remove an attribute', () {
+ var b = new B();
- B.invocations = [];
- b.classList.toggle('u');
- expect(B.invocations, ['class: null => u']);
+ B.invocations = [];
+ b.attributes['data-s'] = 't';
+ expect(B.invocations, ['data-s: null => t']);
- b.attributes['data-v'] = 'w';
- B.invocations = [];
- b.attributes['data-v'] = 'x';
- expect(B.invocations, ['data-v: w => x']);
+ b.attributes['data-v'] = 'w';
+ B.invocations = [];
+ b.attributes['data-v'] = 'x';
+ expect(B.invocations, ['data-v: w => x']);
- B.invocations = [];
- b.attributes['data-v'] = 'x';
- expect(B.invocations, []);
+ B.invocations = [];
+ b.attributes['data-v'] = 'x';
+ expect(B.invocations, []);
+
+ b.attributes.remove('data-v');
+ expect(B.invocations, ['data-v: x => null']);
+ });
+ });
+
+ group('unsupported_on_polyfill', () {
+ test('add, change ID', () {
+ var b = new B();
+ b.id = 'x';
+ expect(B.invocations, ['created', 'id: null => x']);
+
+ B.invocations = [];
+ b.attributes.remove('id');
+ expect(B.invocations, ['id: x => null']);
+ });
+
+ test('add, change classes', () {
+ var b = new B();
+
+ B.invocations = [];
+ b.classes.toggle('u');
+ expect(B.invocations, ['class: null => u']);
+ });
});
}
diff --git a/tests/html/custom/constructor_calls_created_synchronously_test.dart b/tests/html/custom/constructor_calls_created_synchronously_test.dart
index edd689a..2238df6 100644
--- a/tests/html/custom/constructor_calls_created_synchronously_test.dart
+++ b/tests/html/custom/constructor_calls_created_synchronously_test.dart
@@ -7,14 +7,16 @@
import 'package:unittest/html_config.dart';
import 'dart:html';
import '../utils.dart';
+import 'dart:mirrors';
class A extends HtmlElement {
static final tag = 'x-a';
factory A() => new Element.tag(tag);
+ A.created() : super.created();
static int ncallbacks = 0;
- void created() {
+ void createdCallback() {
ncallbacks++;
}
}
diff --git a/tests/html/custom/created_callback_test.dart b/tests/html/custom/created_callback_test.dart
index ebd3fba..dfcd28f 100644
--- a/tests/html/custom/created_callback_test.dart
+++ b/tests/html/custom/created_callback_test.dart
@@ -6,15 +6,17 @@
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'dart:js' as js;
import '../utils.dart';
class A extends HtmlElement {
static final tag = 'x-a';
factory A() => new Element.tag(tag);
+ A.created() : super.created();
static int createdInvocations = 0;
- void created() {
+ void createdCallback() {
createdInvocations++;
}
}
@@ -22,16 +24,18 @@
class B extends HtmlElement {
static final tag = 'x-b';
factory B() => new Element.tag(tag);
+ B.created() : super.created();
}
class C extends HtmlElement {
static final tag = 'x-c';
factory C() => new Element.tag(tag);
+ C.created() : super.created();
static int createdInvocations = 0;
static var div;
- void created() {
+ void createdCallback() {
createdInvocations++;
if (this.id != 'u') {
@@ -60,7 +64,17 @@
// Adapted from Blink's
// fast/dom/custom/created-callback test.
- setUp(loadPolyfills);
+ var registered = false;
+ setUp(() {
+ return loadPolyfills().then((_) {
+ if (!registered) {
+ registered = true;
+ document.register(B.tag, B);
+ document.register(C.tag, C);
+ ErrorConstructorElement.register();
+ }
+ });
+ });
test('transfer created callback', () {
document.register(A.tag, A);
@@ -68,10 +82,7 @@
expect(A.createdInvocations, 1);
});
- test(':unresolved and created callback timing', () {
- document.register(B.tag, B);
- document.register(C.tag, C);
-
+ test('unresolved and created callback timing', () {
var div = new DivElement();
C.div = div;
div.setInnerHtml("""
@@ -87,6 +98,194 @@
expect(div.query('#w') is B, isTrue);
});
+ test('nesting of constructors', NestedElement.test);
+
+ test('access while upgrading gets unupgraded element',
+ AccessWhileUpgradingElement.test);
+
+ test('cannot call created constructor', () {
+ expect(() {
+ new B.created();
+ }, throws);
+ });
+
+ test('cannot register without created', () {
+ expect(() {
+ document.register(MissingCreatedElement.tag, MissingCreatedElement);
+ }, throws);
+ });
+
+ test('throw on createElement does not upgrade', () {
+ ErrorConstructorElement.callCount = 0;
+
+ var e;
+ expectGlobalError(() {
+ e = new Element.tag(ErrorConstructorElement.tag);
+ });
+ expect(ErrorConstructorElement.callCount, 1);
+ expect(e is HtmlElement, isTrue);
+ expect(e is ErrorConstructorElement, isFalse);
+
+ var dummy = new DivElement();
+ dummy.append(e);
+ e = dummy.firstChild;
+ expect(ErrorConstructorElement.callCount, 1);
+ });
+
+ test('throw on innerHtml does not upgrade', () {
+ ErrorConstructorElement.callCount = 0;
+
+ var dummy = new DivElement();
+ var tag = ErrorConstructorElement.tag;
+ expectGlobalError(() {
+ dummy.setInnerHtml('<$tag></$tag>',
+ treeSanitizer: new NullTreeSanitizer());
+ });
+
+ expect(ErrorConstructorElement.callCount, 1);
+
+ var e = dummy.firstChild;
+ // Accessing should not re-run the constructor.
+ expect(ErrorConstructorElement.callCount, 1);
+ expect(e is HtmlElement, isTrue);
+ expect(e is ErrorConstructorElement, isFalse);
+ });
+
+ // Issue - 13711 Need to fix the handling of the created constructor.
+ // test('created cannot be called from nested constructor',
+ // NestedCreatedConstructorElement.test);
+
+
// TODO(vsm): Port additional test from upstream here:
// http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/dom/custom/created-callback.html?r1=156141&r2=156185
}
+
+
+class NestedElement extends HtmlElement {
+ static final tag = 'x-nested';
+
+ final Element b = new B();
+
+ factory NestedElement() => new Element.tag(tag);
+ NestedElement.created() : super.created();
+
+ static void register() {
+ document.register(tag, NestedElement);
+ }
+
+ static void test() {
+ register();
+
+ var e = new NestedElement();
+ expect(e.b, isNotNull);
+ expect(e.b is B, isTrue);
+ expect(e is NestedElement, isTrue);
+ }
+}
+
+
+class AccessWhileUpgradingElement extends HtmlElement {
+ static final tag = 'x-access-while-upgrading';
+
+ static Element upgradingContext;
+ static Element upgradingContextChild;
+
+ final foo = runInitializerCode();
+
+ factory AccessWhileUpgradingElement() => new Element.tag(tag);
+ AccessWhileUpgradingElement.created() : super.created();
+
+ static runInitializerCode() {
+ upgradingContextChild = upgradingContext.firstChild;
+
+ return 666;
+ }
+
+ static void register() {
+ document.register(tag, AccessWhileUpgradingElement);
+ }
+
+ static void test() {
+ register();
+
+ upgradingContext = new DivElement();
+ upgradingContext.setInnerHtml('<$tag></$tag>',
+ treeSanitizer: new NullTreeSanitizer());
+ var child = upgradingContext.firstChild;
+
+ expect(child.foo, 666);
+ expect(upgradingContextChild is HTMLElement, isTrue);
+ expect(upgradingContextChild is AccessWhileUpgradingElement, isFalse,
+ reason: 'Elements accessed while upgrading should not be upgraded.');
+ }
+}
+
+class MissingCreatedElement extends HtmlElement {
+ static final tag = 'x-missing-created';
+
+ factory MissingCreatedElement() => new Element.tag(tag);
+}
+
+class ErrorConstructorElement extends HtmlElement {
+ static final tag = 'x-throws-in-constructor';
+ static int callCount = 0;
+
+ factory ErrorConstructorElement() => new Element.tag(tag);
+
+ ErrorConstructorElement.created() : super.created() {
+ ++callCount;
+ throw new Exception('Just messin with ya');
+ }
+
+ static void register() {
+ document.register(tag, ErrorConstructorElement);
+ }
+}
+
+class NestedCreatedConstructorElement extends HtmlElement {
+ static final tag = 'x-nested-created-constructor';
+
+ // Should not be able to call this here.
+ final B b = constructB();
+ static B constructedB;
+
+ factory NestedCreatedConstructorElement() => new Element.tag(tag);
+ NestedCreatedConstructorElement.created() : super.created();
+
+ static void register() {
+ document.register(tag, NestedCreatedConstructorElement);
+ }
+
+ // Try to run the created constructor, and record the results.
+ static constructB() {
+ // This should throw an exception.
+ constructedB = new B.created();
+ return constructedB;
+ }
+
+ static void test() {
+ register();
+
+ // Exception should have occurred on upgrade.
+ var e = new Element.tag(tag);
+ expect(e is NestedCreatedConstructorElement, isFalse);
+ expect(e is HtmlElement, isTrue);
+ // Should not have been set.
+ expect(constructedB, isNull);
+ }
+}
+
+void expectGlobalError(Function test) {
+ js.context['testExpectsGlobalError'] = true;
+ try {
+ test();
+ } catch(e) {
+ rethrow;
+ } finally {
+ js.context['testExpectsGlobalError'] = false;
+ }
+ var errors = js.context['testSuppressedGlobalErrors'];
+ expect(errors['length'], 1);
+ // Clear out the errors;
+ js.context['testSuppressedGlobalErrors']['length'] = 0;
+}
diff --git a/tests/html/custom/document_register_basic_test.dart b/tests/html/custom/document_register_basic_test.dart
index c8964e5..7e094e8b 100644
--- a/tests/html/custom/document_register_basic_test.dart
+++ b/tests/html/custom/document_register_basic_test.dart
@@ -11,6 +11,7 @@
class Foo extends HtmlElement {
static final tag = 'x-foo';
factory Foo() => new Element.tag(tag);
+ Foo.created() : super.created();
get thisIsACustomClass => true;
}
@@ -18,6 +19,7 @@
class Bar extends HtmlElement {
static final tag = 'x-bar';
factory Bar() => new Element.tag(tag);
+ Bar.created() : super.created();
get thisIsACustomClass => true;
}
@@ -25,6 +27,7 @@
class Baz extends Foo {
static final tag = 'x-baz';
factory Baz() => new Element.tag(tag);
+ Baz.created() : super.created();
get thisIsAlsoACustomClass => true;
}
diff --git a/tests/html/custom/document_register_type_extensions_test.dart b/tests/html/custom/document_register_type_extensions_test.dart
index 79b036d..3f43234 100644
--- a/tests/html/custom/document_register_type_extensions_test.dart
+++ b/tests/html/custom/document_register_type_extensions_test.dart
@@ -14,12 +14,14 @@
'<x-foo></x-foo>',
'<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-foo></x-foo>'];
factory Foo() => new Element.tag(tag);
+ Foo.created() : super.created();
}
class Bar extends InputElement {
static const tag = 'x-bar';
static const outerHtmlString = '<input is="x-bar">';
factory Bar() => new Element.tag('input', tag);
+ Bar.created() : super.created();
}
class Baz extends Foo {
@@ -28,16 +30,19 @@
'<x-baz></x-baz>',
'<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-baz></x-baz>'];
factory Baz() => new Element.tag(tag);
+ Baz.created() : super.created();
}
class Qux extends Bar {
static const tag = 'x-qux';
factory Qux() => new Element.tag('input', tag);
+ Qux.created() : super.created();
}
class FooBad extends DivElement {
static const tag = 'x-foo';
factory FooBad() => new Element.tag('div', tag);
+ FooBad.created() : super.created();
}
main() {
diff --git a/tests/html/custom/entered_left_view_test.dart b/tests/html/custom/entered_left_view_test.dart
index 79f65c8..a523854 100644
--- a/tests/html/custom/entered_left_view_test.dart
+++ b/tests/html/custom/entered_left_view_test.dart
@@ -14,8 +14,9 @@
var invocations = [];
class Foo extends HtmlElement {
factory Foo() => null;
+ Foo.created() : super.created();
- void created() {
+ void createdCallback() {
invocations.add('created');
}
@@ -27,7 +28,7 @@
invocations.add('left');
}
- void attributeChanged() {
+ void attributeChanged(String name, String oldValue, String newValue) {
invocations.add('attribute changed');
}
}
@@ -62,7 +63,7 @@
});
group('standard_events', () {
- var a = new Element.tag('x-a');
+ var a;
setUp(() {
invocations = [];
});
@@ -105,7 +106,7 @@
});
group('viewless_document', () {
- var a = docB.createElement('x-a');
+ var a;
setUp(() {
invocations = [];
});
diff --git a/tests/html/custom_elements_test.dart b/tests/html/custom_elements_test.dart
index 3ad83a1..718898c 100644
--- a/tests/html/custom_elements_test.dart
+++ b/tests/html/custom_elements_test.dart
@@ -19,8 +19,10 @@
class CustomType extends HtmlElement with CustomMixin{
factory CustomType() => null;
+ CustomType.created(): super.created();
+
bool createdCalled; // = false;
- void created() {
+ void createdCallback() {
createdCalled = true;
customCreatedCount++;
}
diff --git a/tests/html/html.status b/tests/html/html.status
index 4905e0b..5db1caa 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -13,10 +13,10 @@
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
+custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # Polyfill does not support
[ $compiler == dart2js && $browser ]
-# Issue 9325 failures
-custom/attribute_changed_callback_test: Fail
+custom/created_callback_test: Fail # Support for created constructor.
[ $compiler == none && ($runtime == drt || $runtime == dartium) && $mode == debug && $system == macos]
audiobuffersourcenode_test: Pass, Fail, Crash # http://crbug.com/256601
@@ -29,9 +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
+async_test: Fail # Background timers not implemented.
[ $compiler == none && $runtime == drt && $system == windows ]
worker_test/functional: Pass, Crash # Issue 9929.
@@ -85,8 +85,6 @@
xhr_test: Pass, Fail # Issue 11884
xhr_cross_origin_test: Pass, Fail # Issue 11884
-fileapi_test/directoryReader: Fail # Issue 12573
-
[ $runtime == chrome || $runtime == chromeOnAndroid || $runtime == drt || $runtime == safari ]
audiocontext_test: Skip # Issue 9322
diff --git a/tests/html/htmloptionscollection_test.dart b/tests/html/htmloptionscollection_test.dart
index 8af54c7..9a633ab 100644
--- a/tests/html/htmloptionscollection_test.dart
+++ b/tests/html/htmloptionscollection_test.dart
@@ -33,7 +33,7 @@
// OPTIONALS optionsCollection[0] = new OptionElement(value: '42', data: 'Option42');
expect(() {
- optionsCollection[0] = new OptionElement('Option42', '42');
+ optionsCollection[0] = new OptionElement(data: 'Option42', value: '42');
}, throws);
});
}
diff --git a/tests/html/js_test.dart b/tests/html/js_test.dart
index ff6753d..290a0fb 100644
--- a/tests/html/js_test.dart
+++ b/tests/html/js_test.dart
@@ -151,6 +151,12 @@
_injectJs();
useHtmlConfiguration();
+ test('context instances should be identical', () {
+ var c1 = context;
+ var c2 = context;
+ expect(identical(c1, c2), isTrue);
+ });
+
test('read global field', () {
expect(context['x'], equals(42));
expect(context['y'], isNull);
diff --git a/tests/html/selectelement_test.dart b/tests/html/selectelement_test.dart
index 717502f..f88c4af 100644
--- a/tests/html/selectelement_test.dart
+++ b/tests/html/selectelement_test.dart
@@ -16,9 +16,11 @@
var options = [
new OptionElement(),
new DivElement(),
- new OptionElement('data', 'two', false, true),
+ new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+ selected: true),
new DivElement(),
- new OptionElement('data', 'two', false, true),
+ new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+ selected: true),
new OptionElement(),
];
element.children.addAll(options);
@@ -32,9 +34,11 @@
var options = [
new OptionElement(),
new DivElement(),
- new OptionElement('data', 'two', false, true),
+ new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+ selected: true),
new DivElement(),
- new OptionElement('data', 'two', false, true),
+ new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+ selected: true),
new OptionElement(),
];
element.children.addAll(options);
@@ -47,8 +51,10 @@
var element = new SelectElement();
var options = [
new OptionElement(),
- new OptionElement('data', 'two', false, true),
- new OptionElement('data', 'two', false, true),
+ new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+ selected: true),
+ new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+ selected: true),
new OptionElement(),
];
element.children.addAll(options);
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 700d27c..a74948a 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -89,9 +89,11 @@
[ $compiler == dart2js && ( $runtime == ff || $runtime == safari || $runtime == drt || $runtime == chrome ) ]
isolate_stress_test: Pass, Slow # Issue 10697
-[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
+[ $compiler == none && $runtime == drt ]
isolate_stress_test: Skip # Issue 12537
spawn_uri_multi_test/01: Fail # Issue 13615
+nested_spawn_stream2_test: Fail # Issue 13433
+cross_isolate_message_stream_test: Fail # Issue 13433
[ $csp ]
spawn_uri_multi_test/none: Fail # http://dartbug.com/13454
@@ -99,3 +101,6 @@
[ $jscl || $runtime == ie9 ]
spawn_uri_multi_test/none: RuntimeError # http://dartbug.com/13544
+
+[ $compiler == none && $runtime == dartium ]
+global_error_handler2_test: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/language/compile_time_constant11_test.dart b/tests/language/compile_time_constant11_test.dart
new file mode 100644
index 0000000..67ff3fe
--- /dev/null
+++ b/tests/language/compile_time_constant11_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Check that conditional expression can be a compile-time constant.
+
+import "package:expect/expect.dart";
+
+const C1 = true;
+const C2 = false;
+
+const nephew = C1 ? C2 ? "Tick" : "Trick" : "Track";
+
+main() {
+ const a = true ? 5 : 10;
+ const b = C2 ? "Track" : C1 ? "Trick" : "Tick";
+
+ Expect.equals(5, a);
+ Expect.equals("Trick", nephew);
+ Expect.equals(nephew, b);
+ Expect.identical(nephew, b);
+ var s = const Symbol(nephew);
+ var msg = "Donald is $nephew's uncle.";
+ Expect.equals("Donald is Trick's uncle.", msg);
+}
diff --git a/tests/language/const_conditional_test.dart b/tests/language/const_conditional_test.dart
new file mode 100644
index 0000000..97d4a93
--- /dev/null
+++ b/tests/language/const_conditional_test.dart
@@ -0,0 +1,56 @@
+// 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 for conditionals as compile-time constants.
+
+import 'package:expect/expect.dart';
+
+class Marker {
+ final field;
+ const Marker(this.field);
+}
+
+var var0 = const Marker(0);
+var var1 = const Marker(1);
+const const0 = const Marker(0);
+const const1 = const Marker(1);
+
+const trueConst = true;
+const falseConst = false;
+var nonConst = true;
+const zeroConst = 0;
+
+const cond1 = trueConst ? const0 : const1;
+const cond1a = trueConst ? nonConst : const1; /// 01: compile-time error
+const cond1b = trueConst ? const0 : nonConst; /// 02: compile-time error
+
+const cond2 = falseConst ? const0 : const1;
+const cond2a = falseConst ? nonConst : const1; /// 03: compile-time error
+const cond2b = falseConst ? const0 : nonConst; /// 04: compile-time error
+
+const cond3 = nonConst ? const0 : const1; /// 05: compile-time error
+const cond3a = nonConst ? nonConst : const1; /// 06: compile-time error
+const cond3b = nonConst ? const0 : nonConst; /// 07: compile-time error
+
+const cond4 = zeroConst ? const0 : const1; /// 08: compile-time error
+const cond4a = zeroConst ? nonConst : const1; /// 09: compile-time error
+const cond4b = zeroConst ? const0 : nonConst; /// 10: compile-time error
+
+void main() {
+ Expect.identical(var0, cond1);
+ Expect.identical(nonConst, cond1a); /// 01: continued
+ Expect.identical(var0, cond1b); /// 02: continued
+
+ Expect.identical(var1, cond2);
+ Expect.identical(var1, cond2a); /// 03: continued
+ Expect.identical(nonConst, cond2b); /// 04: continued
+
+ Expect.identical(var0, cond3); /// 05: continued
+ Expect.identical(nonConst, cond3a); /// 06: continued
+ Expect.identical(var0, cond3b); /// 07: continued
+
+ Expect.identical(var1, cond4); /// 08: continued
+ Expect.identical(var1, cond4a); /// 09: continued
+ Expect.identical(nonConst, cond4b); /// 10: continued
+}
\ No newline at end of file
diff --git a/tests/language/constant_locals_test.dart b/tests/language/constant_locals_test.dart
new file mode 100644
index 0000000..bd85240
--- /dev/null
+++ b/tests/language/constant_locals_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that constant local variables have constant initializers.
+
+import "package:expect/expect.dart";
+
+void main() {
+ const c1; /// 01: compile-time error
+ const c2 = 0;
+ const c3 = field; /// 02: compile-time error
+ const c4 = finalField; /// 03: compile-time error
+ const c5 = constField;
+ const c6 = method(); /// 04: compile-time error
+ const c7 = new Class(); /// 05: compile-time error
+ const c8 = const Class();
+}
+
+var field = 0;
+
+final finalField = 0;
+
+const constField = 0;
+
+method() => 0;
+
+class Class {
+ const Class();
+}
\ No newline at end of file
diff --git a/tests/language/language.status b/tests/language/language.status
index e567204..bd6e7e2 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -25,6 +25,18 @@
on_catch_malformed_type_test: Fail # Issue 8601
mixin_forwarding_constructor2_test: Fail # Issue 13641
+[ $compiler == none && $runtime == vm ]
+class_keyword_test/02: MissingCompileTimeError # Issue 13627
+
+
+[ $compiler == none && $runtime == vm && $checked ]
+compile_time_constant_checked3_test/01: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/02: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/03: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/04: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/05: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/06: MissingCompileTimeError # Issue 13685
+
[ $compiler == none && $unchecked ]
# Only checked mode reports an error on type assignment
# problems in compile time constants.
@@ -56,3 +68,21 @@
[ $compiler == dart2js && $runtime == ie9 ]
lazy_static3_test: Fail # Issue 13469
+
+[ $compiler == none && $runtime == dartium ]
+assertion_test: Fail # Issue 13719: Please triage this failure.
+call_test: Fail # Issue 13719: Please triage this failure.
+dynamic_prefix_core_test: Fail # Issue 13719: Please triage this failure.
+first_class_types_literals_test: Fail # Issue 13719: Please triage this failure.
+generic_test: Fail # Issue 13719: Please triage this failure.
+list_literal1_test/01: Fail # Issue 13719: Please triage this failure.
+list_literal4_test: Fail # Issue 13719: Please triage this failure.
+map_literal1_test/01: Fail # Issue 13719: Please triage this failure.
+map_literal4_test: Fail # Issue 13719: Please triage this failure.
+named_parameters_type_test/01: Fail # Issue 13719: Please triage this failure.
+named_parameters_type_test/02: Fail # Issue 13719: Please triage this failure.
+named_parameters_type_test/03: Fail # Issue 13719: Please triage this failure.
+positional_parameters_type_test/01: Fail # Issue 13719: Please triage this failure.
+positional_parameters_type_test/02: Fail # Issue 13719: Please triage this failure.
+type_checks_in_factory_method_test: Fail # Issue 13719: Please triage this failure.
+vm/type_vm_test: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index d229d47..536168e 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -3,17 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
[ $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
+switch_bad_case_test/02: Fail # missing error in double in switch case expr
# Runtime negative test. No static errors or warnings.
closure_call_wrong_argument_count_negative_test: skip
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index f43b9e8..17a459a 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -3,6 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2analyzer ]
+switch_bad_case_test/02: Fail
# Missing compile-time errors for parameters marked static.
static_parameter_test/02: Fail
@@ -123,9 +124,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
@@ -133,8 +131,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
@@ -185,7 +181,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_dart2js.status b/tests/language/language_dart2js.status
index 4bb4278..87857b1 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -5,7 +5,6 @@
[ $compiler == dart2js || $compiler == dart2dart ]
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
@@ -79,6 +78,7 @@
mixin_mixin6_test: Fail # Issue 12605.
[ $compiler == dart2js ]
+switch_bad_case_test/02: MissingCompileTimeError # switch case of type double
malformed_test/none: RuntimeError # Issue 12695
function_type_alias9_test/00: Crash # Issue 9792
branch_canonicalization_test: RuntimeError # Issue 638.
@@ -130,7 +130,6 @@
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: MissingCompileTimeError # Issue 12812
external_test/11: MissingCompileTimeError # Issue 12887
external_test/12: MissingCompileTimeError # Issue 12887
@@ -145,8 +144,6 @@
map_literal4_test: RuntimeError # Issue 12891
built_in_identifier_test/01: CompileTimeError # Issue 13022
-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
@@ -164,7 +161,6 @@
final_syntax_test/03: MissingCompileTimeError # Issue 13020
final_syntax_test/04: MissingCompileTimeError # Issue 13020
-assign_top_method_test: RuntimeError # Issue 13075
null_test/none: RuntimeError # Issue 12482
@@ -205,6 +201,7 @@
malformed_test/none: CompileTimeError # Issue 12695
mixin_super_constructor_named_test: Fail # Issue 12631
mixin_super_constructor_positionals_test: Fail # Issue 12631
+switch_bad_case_test/02: Fail # missing switch type check for double
built_in_identifier_prefix_test: Fail # Issue 6972
constructor_initializer_test/none: Fail # Issue 12633
@@ -245,21 +242,6 @@
setter_override_test/03: Fail # Issue 11496
setter_override2_test/02: Fail # Issue 11496
-compile_time_constant10_test/01: Fail # Issue 5519
-compile_time_constant10_test/02: Fail # Issue 5519
-compile_time_constant_arguments_test/01: Fail # Issue 5519
-compile_time_constant_arguments_test/02: Fail # Issue 5519
-compile_time_constant_arguments_test/03: Fail # Issue 5519
-compile_time_constant_arguments_test/05: Fail # Issue 5519
-compile_time_constant_arguments_test/06: Fail # Issue 5519
-const_syntax_test/03: Fail # Issue 12933
-const_syntax_test/04: Fail # Issue 12933
-const_syntax_test/05: Fail # Issue 12933
-const_syntax_test/06: Fail # Issue 12933
-const_syntax_test/07: Fail # Issue 12933
-const_syntax_test/08: Fail # Issue 12933
-const_syntax_test/10: 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
final_syntax_test/01: Fail # Issue 13020
@@ -299,7 +281,6 @@
function_type_alias5_test/00: Fail # Issue 12755
function_type_alias5_test/01: Fail # Issue 12755
function_type_alias5_test/02: Fail # Issue 12755
-parameter_initializer6_negative_test: Fail # Issue 3502
# DartVM problem.
constructor5_test: Fail
@@ -329,8 +310,6 @@
compile_time_constant_checked3_test/05: Fail, OK
compile_time_constant_checked3_test/06: Fail, OK
-final_is_not_const_test/01: Fail # Issue 12692
-
[ $compiler == dart2dart && $minified ]
super_getter_setter_test: Fail # Issue 11065.
f_bounded_quantification4_test: Fail # Issue 12605.
diff --git a/tests/language/list_length_tracer_test.dart b/tests/language/list_length_tracer_test.dart
new file mode 100644
index 0000000..f8c1070
--- /dev/null
+++ b/tests/language/list_length_tracer_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.
+
+// Test that dart2js' optimization on list length does not fold a
+// length getter to a constant if the receiver can be null.
+
+import "package:expect/expect.dart";
+
+var a = 42;
+var b;
+
+main() {
+ Expect.throws(() => b.length);
+ b = const [42];
+}
diff --git a/tests/language/list_tracer_call_last_test.dart b/tests/language/list_tracer_call_last_test.dart
new file mode 100644
index 0000000..dbaf136
--- /dev/null
+++ b/tests/language/list_tracer_call_last_test.dart
@@ -0,0 +1,13 @@
+// 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.
+
+// dart2js used to fail this test, by inferring that `a.last()`
+// returns the element type of the `a` list.
+
+main() {
+ var a = [() => 123];
+ if (a.last() is! num) {
+ throw 'Test failed';
+ }
+}
diff --git a/tests/language/list_tracer_closure_test.dart b/tests/language/list_tracer_closure_test.dart
new file mode 100644
index 0000000..acb226e
--- /dev/null
+++ b/tests/language/list_tracer_closure_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' inferrer: if we closurize a method, we
+// still need to collect the users of the parameters for the trace
+// container pass to work.
+
+main() {
+ var a = new List();
+ a.add;
+ var b = new List();
+ var c = new List(1);
+ b.add(c);
+ b[0][0] = 42;
+ if (c[0] is! int) {
+ throw 'Test failed';
+ }
+}
diff --git a/tests/language/mixin_black_listed_test.dart b/tests/language/mixin_black_listed_test.dart
new file mode 100644
index 0000000..809274b
--- /dev/null
+++ b/tests/language/mixin_black_listed_test.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.
+
+// Check mixin of black-listed types.
+
+import 'package:expect/expect.dart';
+
+class C {}
+class D {}
+
+class C1 extends Object
+with String /// 01: compile-time error
+{}
+
+class D1 extends Object with C
+, Null /// 02: compile-time error
+{}
+
+class E1 extends Object with
+int, /// 03: compile-time error
+C {}
+
+class F1 extends Object with C
+, double /// 04: compile-time error
+, D {}
+
+typedef C2 = Object with num; /// 05: compile-time error
+
+typedef D2 = Object with C
+, bool /// 06: compile-time error
+;
+
+typedef E2 = Object with
+String, /// 07: compile-time error
+C;
+
+typedef F2 = Object with C,
+dynamic, /// 08: compile-time error
+D;
+
+
+main() {
+ Expect.isNotNull(new C1());
+ Expect.isNotNull(new D1());
+ Expect.isNotNull(new E1());
+ Expect.isNotNull(new F1());
+ Expect.isNotNull(new C2()); /// 05: continued
+ Expect.isNotNull(new D2());
+ Expect.isNotNull(new E2());
+ Expect.isNotNull(new F2());
+}
diff --git a/tests/language/switch_bad_case_test.dart b/tests/language/switch_bad_case_test.dart
new file mode 100644
index 0000000..8211521
--- /dev/null
+++ b/tests/language/switch_bad_case_test.dart
@@ -0,0 +1,36 @@
+// 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 reporting a compile-time error if case expressions do not all have
+// the same type or are of type double.
+
+import "package:expect/expect.dart";
+
+void main() {
+ Expect.equals("IV", caesarSays(4));
+ Expect.equals(null, caesarSays(2));
+ Expect.equals(null, archimedesSays(3.14));
+}
+
+caesarSays(n) {
+ switch (n) {
+ case 1:
+ return "I";
+ case 4:
+ return "IV";
+ case "M": /// 01: compile-time error
+ return 1000; /// 01: continued
+ }
+ return null;
+}
+
+archimedesSays(n) {
+ switch (n) { /// 02: continued
+ case 3.14: /// 02: compile-time error
+ return "Pi"; /// 02: continued
+ case 2.71828: /// 02: continued
+ return "Huh?"; /// 02: continued
+ } /// 02: continued
+ return null;
+}
diff --git a/tests/language/switch_int_double_test.dart b/tests/language/switch_int_double_test.dart
deleted file mode 100644
index 8ae95e2..0000000
--- a/tests/language/switch_int_double_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.
-
-// Test reporting a compile-time error if case expressions do not all have
-// the same type.
-
-import "package:expect/expect.dart";
-
-void main() {
- Expect.equals(100, test(1.0));
- Expect.equals(75, test(0.75));
- Expect.equals(null, test(0.5));
-}
-
-int test(num ratio) {
- switch (ratio) {
- case 0.75:
- return 75;
- case 1.0:
- return 100;
- case 2: /// 01: compile-time error
- return 200; /// 01: continued
- case 'foo': /// 02: compile-time error
- return 400; /// 02: continued
- }
-}
\ No newline at end of file
diff --git a/tests/language/vm/function_equality_vm_test.dart b/tests/language/vm/function_equality_vm_test.dart
new file mode 100644
index 0000000..4077c66
--- /dev/null
+++ b/tests/language/vm/function_equality_vm_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.
+
+// Test function equality with null.
+
+import "package:expect/expect.dart";
+
+class A {
+ foo() { }
+}
+
+main() {
+ var a = new A();
+ var f = a.foo;
+ Expect.isFalse(f == null);
+ Expect.isFalse(null == f);
+}
+
diff --git a/tests/lib/convert/unicode_tests.dart b/tests/lib/convert/unicode_tests.dart
index 52a7b09..47bd510 100644
--- a/tests/lib/convert/unicode_tests.dart
+++ b/tests/lib/convert/unicode_tests.dart
@@ -63,6 +63,9 @@
const SMALLEST_4_UTF8_UNIT_BYTES = const [ 0xF0, 0x90, 0x80, 0x80 ];
const SMALLEST_4_UTF8_UNIT_STRING = "\u{10000}";
+const BIGGEST_4_UTF8_UNIT_BYTES = const [ 0xF4, 0x8F, 0xBF, 0xBF ];
+const BIGGEST_4_UTF8_UNIT_STRING = "\u{10FFFF}";
+
const _TEST_PAIRS = const [
const [ const [], "" ],
const [ INTER_BYTES, INTER_STRING ],
@@ -78,6 +81,7 @@
const [ SMALLEST_3_UTF8_UNIT_BYTES, SMALLEST_3_UTF8_UNIT_STRING ],
const [ BIGGEST_3_UTF8_UNIT_BYTES, BIGGEST_3_UTF8_UNIT_STRING ],
const [ SMALLEST_4_UTF8_UNIT_BYTES, SMALLEST_4_UTF8_UNIT_STRING ],
+ const [ BIGGEST_4_UTF8_UNIT_BYTES, BIGGEST_4_UTF8_UNIT_STRING ],
];
List<List> _expandTestPairs() {
diff --git a/tests/lib/convert/utf85_test.dart b/tests/lib/convert/utf85_test.dart
new file mode 100644
index 0000000..3b5edc0
--- /dev/null
+++ b/tests/lib/convert/utf85_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.
+
+library utf8_test;
+import "package:expect/expect.dart";
+import 'dart:convert';
+
+main() {
+ for (int i = 0; i <= 0x10FFFF; i++) {
+ if (i == UNICODE_BOM_CHARACTER_RUNE) continue;
+ Expect.equals(i,
+ UTF8.decode(UTF8.encode(new String.fromCharCode(i))).runes.first);
+ }
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 4276ffc..61ba7ee 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -40,6 +40,10 @@
mirrors/redirecting_factory_test/02: RuntimeError # Issue 6490
mirrors/closures_test/none: RuntimeError # Issue 6490
mirrors/library_metadata2_test/01: CompileTimeError # Issue 13633
+async/stream_controller_async_test: Pass, Fail # Issue 13608
+
+[ $compiler == dart2js && $checked ]
+mirrors/redirection_type_shuffling_test: RuntimeError # Issue 13706
[ $runtime == safari ]
mirrors/return_type_test: Pass, Timeout # Issue 12858
@@ -138,9 +142,6 @@
mirrors/hierarchy_test: Fail # TODO(ahe): This test is slightly broken. http://dartbug.com/12464
mirrors/mixin_test/01: Fail, OK # TODO(ahe): Slight broken test to ensure test coverage on dart2js.
mirrors/typedef_test/01: Fail, OK # Incorrect dart2js behavior.
-mirrors/redirecting_factory_test/none: Fail # Issue 13365
-mirrors/redirecting_factory_test/01: Fail # Issue 13365
-mirrors/redirecting_factory_test/02: Fail # Issue 13365
mirrors/closures_test/01: Fail, OK # Incorrect dart2js behavior.
[ $compiler == none && $runtime == drt ]
@@ -179,11 +180,23 @@
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
+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 == none && $runtime == dartium ]
+async/run_async3_test: Fail # Issue 13719: Please triage this failure.
+async/run_async4_test: Fail # Issue 13719: Please triage this failure.
+async/run_async6_test: Fail # Issue 13719: Please triage this failure.
+async/timer_not_available_test: Fail # Issue 13719: Please triage this failure.
+mirrors/closures_test/01: Fail # Issue 13719: Please triage this failure.
+mirrors/hierarchy_test: Fail # Issue 13719: Please triage this failure.
+mirrors/library_uri_io_test: Fail # Issue 13719: Please triage this failure.
+mirrors/local_isolate_test: Fail # Issue 13719: Please triage this failure.
+mirrors/mixin_test/01: Fail # Issue 13719: Please triage this failure.
+mirrors/typedef_test/01: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/lib/mirrors/circular_factory_redirection_test.dart b/tests/lib/mirrors/circular_factory_redirection_test.dart
new file mode 100644
index 0000000..a7b1882
--- /dev/null
+++ b/tests/lib/mirrors/circular_factory_redirection_test.dart
@@ -0,0 +1,37 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+ A();
+ A.circular() = B.circular; /// 01: compile-time error
+ const A.circular2() = B.circular2; /// 02: compile-time error
+}
+class B {
+ B();
+ B.circular() = C.circular; /// 01: continued
+ const B.circular2() = C.circular2; /// 02: continued
+}
+class C {
+ C();
+ C.circular() = A.circular; /// 01: continued
+ const C.circular2() = A.circular2; /// 02: continued
+}
+
+main() {
+ ClassMirror cm = reflectClass(A);
+
+ new A.circular(); /// 01: continued
+ new A.circular2(); /// 02: continued
+
+ Expect.throws(() => cm.newInstance(#circular, []),
+ (e) => e is NoSuchMethodError,
+ 'Should disallow circular redirection (non-const)');
+
+ Expect.throws(() => cm.newInstance(#circular2, []),
+ (e) => e is NoSuchMethodError,
+ 'Should disallow circular redirection (const)');
+}
diff --git a/tests/lib/mirrors/redirecting_factory_test.dart b/tests/lib/mirrors/redirecting_factory_test.dart
index 1d0059f..6509069 100644
--- a/tests/lib/mirrors/redirecting_factory_test.dart
+++ b/tests/lib/mirrors/redirecting_factory_test.dart
@@ -14,14 +14,14 @@
factory Class.redirectingFactoryNoOptional(a, b) = Class.factoryNoOptional;
factory Class.factoryUnnamedOptional(a, [b = 42]) => new Class<T1, T2>(a - b);
- factory Class.redirectingFactoryUnnamedOptional(a, [b]) =
+ factory Class.redirectingFactoryUnnamedOptional(a, [b = 5]) =
Class.factoryUnnamedOptional;
- factory Class.factoryNamedOptional(a, {b: 0}) {
+ factory Class.factoryNamedOptional(a, {b: 42}) {
return new Class<T1, T2>(a - b);
}
- factory Class.redirectingFactoryNamedOptional(a, {b: 42}) =
+ factory Class.redirectingFactoryNamedOptional(a, {b: 5}) =
Class.factoryNamedOptional;
factory Class.factoryMoreNamedOptional(a, {b: 0, c: 2}) {
diff --git a/tests/lib/mirrors/redirection_type_shuffling_test.dart b/tests/lib/mirrors/redirection_type_shuffling_test.dart
new file mode 100644
index 0000000..582b414
--- /dev/null
+++ b/tests/lib/mirrors/redirection_type_shuffling_test.dart
@@ -0,0 +1,36 @@
+// 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 "package:expect/expect.dart";
+
+class G<A extends int, B extends String> {
+ G();
+ factory G.swap() = G<B,A>; /// static type warning
+ factory G.retain() = G<A,B>;
+}
+
+bool get inCheckedMode {
+ try {
+ var i = 1;
+ String s = i;
+ return false;
+ } catch(e) {
+ return true;
+ }
+}
+
+main() {
+ ClassMirror cm = reflect(new G<int, String>()).type;
+
+ if (inCheckedMode) {
+ Expect.throws(() => cm.newInstance(#swap, []),
+ (e) => e is MirroredCompilationError,
+ 'Checked mode should not allow violation of type bounds');
+ } else {
+ Expect.isTrue(cm.newInstance(#swap, []).reflectee is G<String,int>);
+ }
+
+ Expect.isTrue(cm.newInstance(#retain, []).reflectee is G<int,String>);
+}
diff --git a/tests/standalone/debugger/step_in_equals_test.dart b/tests/standalone/debugger/step_in_equals_test.dart
new file mode 100644
index 0000000..0e10e5d
--- /dev/null
+++ b/tests/standalone/debugger/step_in_equals_test.dart
@@ -0,0 +1,59 @@
+// 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 "debug_lib.dart";
+
+class MyClass {
+ operator ==(other) {
+ print(other);
+ return true; // Breakpoint #3.
+ }
+}
+
+main() {
+ if (RunScript(testScript)) return;
+ var a = new MyClass();
+ var b = null;
+ var x = a == b; // Breakpoint #1.
+ print(x);
+ b = 123;
+ a == b; // Breakpoint #2.
+ print("after 2");
+ if (a == null) { // Breakpoint #4.
+ throw "unreachable";
+ }
+ print("after 4");
+ if (null == a) {
+ throw "unreachable";
+ }
+ print("ok");
+}
+
+var testScript = [
+ MatchFrames(["main"]),
+ SetBreakpoint(18),
+ SetBreakpoint(21),
+ SetBreakpoint(10),
+ SetBreakpoint(23),
+ Resume(),
+ MatchFrames(["main"]), // At breakpoint #1.
+ StepInto(),
+ MatchFrames(["main"]), // Don't step into == method because of null.
+ Resume(),
+ MatchFrames(["main"]), // At breakpoint #2.
+ StepInto(),
+ StepInto(),
+ MatchFrames(["MyClass.==", "main"]), // At MyClass.== entry.
+ Resume(),
+ MatchFrames(["MyClass.==", "main"]), // At breakpoint #3.
+ Resume(),
+ MatchFrames(["main"]), // At breakpoint #4.
+ StepInto(),
+ MatchFrames(["main"]), // After breakpoint #4.
+ Step(),
+ MatchFrames(["main"]), // At null == a.
+ StepInto(),
+ MatchFrames(["main"]), // After null == a.
+ Resume()
+];
diff --git a/tests/standalone/float_array_test.dart b/tests/standalone/float_array_test.dart
index 2fe83a2..2be1711 100644
--- a/tests/standalone/float_array_test.dart
+++ b/tests/standalone/float_array_test.dart
@@ -4,6 +4,8 @@
//
// Dart test program for testing native float arrays.
+// VMOptions=--optimization_counter_threshold=10
+
// Library tag to be able to run in html test framework.
library FloatArrayTest;
@@ -186,23 +188,34 @@
a[index] = value;
}
+testPolymorphicLoad(var list) {
+ return list[0];
+}
+
main() {
var a32 = new Float32List(5);
- for (int i = 0; i < 2000; i++) {
+ for (int i = 0; i < 20; i++) {
testCreateFloat32Array();
testSetRange32();
testIndexOutOfRange32();
testIndexOf32();
storeIt32(a32, 1, 2.0);
+ testPolymorphicLoad(a32);
}
var a64 = new Float64List(5);
- for (int i = 0; i < 2000; i++) {
+ for (int i = 0; i < 20; i++) {
testCreateFloat64Array();
testSetRange64();
testIndexOutOfRange64();
testIndexOf64();
storeIt64(a64, 1, 2.0);
+ testPolymorphicLoad(a64);
}
+ var f32x4 = new Float32x4List(5);
+ for (int i = 0; i < 20; i++) {
+ testPolymorphicLoad(f32x4);
+ }
+
// These two take a long time in checked mode.
testBadValues32();
testBadValues64();
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index aaedf1c..ea1e21c 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -452,9 +452,8 @@
var os = Platform.operatingSystem;
if (os == "windows") nestingDepth = 2;
if (createdDirectories.length < nestingDepth) {
- temp = new Directory(
- '${temp.path}/nested_temp_dir_${createdDirectories.length}_');
- temp.createTemp().then(createPhaseCallback);
+ temp.createTemp('nested_temp_dir_${createdDirectories.length}_')
+ .then(createPhaseCallback);
} else {
deletePhaseCallback();
}
diff --git a/tests/standalone/io/file_system_watcher_test.dart b/tests/standalone/io/file_system_watcher_test.dart
index fef2d6e..41f4948 100644
--- a/tests/standalone/io/file_system_watcher_test.dart
+++ b/tests/standalone/io/file_system_watcher_test.dart
@@ -29,7 +29,7 @@
throw e;
});
- runAsync(file.createSync);
+ file.createSync();
}
@@ -54,7 +54,7 @@
throw e;
});
- runAsync(() => file.writeAsStringSync('a'));
+ file.writeAsStringSync('a');
}
@@ -82,7 +82,7 @@
throw e;
});
- runAsync(() => file.renameSync(dir.path + '/file2'));
+ file.renameSync(dir.path + '/file2');
}
@@ -107,7 +107,7 @@
throw e;
});
- runAsync(file.deleteSync);
+ file.deleteSync();
}
@@ -130,10 +130,8 @@
throw e;
});
- runAsync(() {
- file.createSync();
- file.writeAsStringSync('a');
- });
+ file.createSync();
+ file.writeAsStringSync('a');
}
@@ -175,12 +173,10 @@
state = newState;
});
- runAsync(() {
- file.createSync();
- file.writeAsStringSync('a');
- file.renameSync(file2.path);
- file2.deleteSync();
- });
+ file.createSync();
+ file.writeAsStringSync('a');
+ file.renameSync(file2.path);
+ file2.deleteSync();
}
@@ -209,7 +205,7 @@
throw e;
});
- runAsync(file.createSync());
+ file.createSync();
}
@@ -232,7 +228,7 @@
throw e;
});
- runAsync(file.createSync);
+ file.createSync();
new Timer(const Duration(milliseconds: 300), () {
sub.cancel();
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index 3b8c383..4e3cc3d 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -1082,6 +1082,29 @@
});
}
+ static void testDoubleAsyncOperation() {
+ asyncTestStarted();
+ var file = new File(Platform.executable).openSync();
+ var completer = new Completer();
+ int done = 0;
+ bool error = false;
+ void getLength() {
+ file.length()
+ .catchError((e) { error = true; })
+ .whenComplete(() {
+ if (++done == 2) {
+ asyncTestDone("testDoubleAsyncOperation");
+ Expect.isTrue(error);
+ file.lengthSync();
+ file.closeSync();
+ }
+ });
+ }
+ getLength();
+ getLength();
+ Expect.throws(() => file.lengthSync());
+ }
+
static void testLastModifiedSync() {
var modified = new File(Platform.executable).lastModifiedSync();
Expect.isTrue(modified is DateTime);
@@ -1300,6 +1323,7 @@
testRename();
testRenameSync();
testLastModified();
+ testDoubleAsyncOperation();
asyncEnd();
});
}
diff --git a/tests/standalone/io/http_server_test.dart b/tests/standalone/io/http_server_test.dart
index b470b4d..f5018b4 100644
--- a/tests/standalone/io/http_server_test.dart
+++ b/tests/standalone/io/http_server_test.dart
@@ -41,6 +41,8 @@
ServerSocket.bind("127.0.0.1", 0).then((s) {
socket = s;
server = new HttpServer.listenOn(socket);
+ Expect.equals(server.address.address, '127.0.0.1');
+ Expect.equals(server.address.host, '127.0.0.1');
server.listen((HttpRequest request) {
request.listen(
(_) {},
@@ -51,6 +53,7 @@
test(() {
server.close();
Expect.throws(() => server.port);
+ Expect.throws(() => server.address);
socket.close();
asyncEnd();
});
diff --git a/tests/standalone/io/print_sync_script.dart b/tests/standalone/io/print_sync_script.dart
new file mode 100644
index 0000000..82f866b
--- /dev/null
+++ b/tests/standalone/io/print_sync_script.dart
@@ -0,0 +1,22 @@
+// 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:io';
+
+String get bigString {
+ var buffer = new StringBuffer();
+ for (var i = 0; i < 1000; i++) {
+ buffer.write(i);
+ for (var i = 0; i < 200; i++) {
+ buffer.write('=');
+ }
+ buffer.writeln();
+ }
+ return buffer.toString();
+}
+
+main() {
+ stdout; // Be sure to mark stdout as non-blocking.
+ print(bigString);
+}
diff --git a/tests/standalone/io/print_sync_test.dart b/tests/standalone/io/print_sync_test.dart
new file mode 100644
index 0000000..05f8014
--- /dev/null
+++ b/tests/standalone/io/print_sync_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.
+
+import 'dart:io';
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+void main() {
+ asyncStart();
+ Process.run(Platform.executable,
+ [new Uri.file(Platform.script)
+ .resolve('print_sync_script.dart').toString()])
+ .then((out) {
+ asyncEnd();
+ Expect.equals(1002, out.stdout.split('\n').length);
+ });
+}
diff --git a/tests/standalone/io/regress_7191_script.dart b/tests/standalone/io/regress_7191_script.dart
index 9f7c780..9f6a346 100644
--- a/tests/standalone/io/regress_7191_script.dart
+++ b/tests/standalone/io/regress_7191_script.dart
@@ -16,7 +16,10 @@
p.stderr.listen((_) { });
// When receiving data again, kill sub-process and exit.
subscription.onData((data) {
- p.kill();
+ // If a SIGTERM is sent before the child-process's main is invoked,
+ // there is a change that the SIGTERM is ignore on Mac OS X. Use
+ // SIGKILL to get around the issue.
+ p.kill(ProcessSignal.SIGKILL);
p.exitCode.then((_) => exit(0));
});
// Close stdout. If handles are incorrectly inherited this will
diff --git a/tests/standalone/io/secure_socket_bad_data_test.dart b/tests/standalone/io/secure_socket_bad_data_test.dart
index 0b6f813..bf7af89 100644
--- a/tests/standalone/io/secure_socket_bad_data_test.dart
+++ b/tests/standalone/io/secure_socket_bad_data_test.dart
@@ -141,17 +141,20 @@
Future test(bool hostnameInConnect) {
- return RawServerSocket.bind(HOST_NAME, 0)
- .then((server) {
+ return RawServerSocket.bind(HOST_NAME, 0).then((server) {
server.listen((client) {
RawSecureSocket.secureServer(client, CERTIFICATE)
- .then((secureClient) {
- Expect.throws(() => client.add([0]));
- return runServer(secureClient);
- })
- .then((_) => server.close());
+ .then((secureClient) {
+ Expect.throws(() => client.add([0]));
+ return runServer(secureClient);
+ },
+ onError: (e) {
+ Expect.isTrue(e is HandshakeException);
+ Expect.isTrue(e.toString().contains(
+ 'received a record with an incorrect Message Authentication'));
+ })
+ .whenComplete(server.close);
});
-
return connectClient(server.port, hostnameInConnect).then(runClient);
});
}
diff --git a/tests/standalone/io/socket_ipv6_test.dart b/tests/standalone/io/socket_ipv6_test.dart
index bded728..e3a2e91 100644
--- a/tests/standalone/io/socket_ipv6_test.dart
+++ b/tests/standalone/io/socket_ipv6_test.dart
@@ -5,6 +5,7 @@
import 'dart:io';
import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
const ANY = InternetAddressType.ANY;
@@ -13,6 +14,8 @@
InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
InternetAddress.lookup("::1", type: ANY).then((clientAddr) {
ServerSocket.bind(serverAddr.first, 0).then((server) {
+ Expect.equals('::0', server.address.host);
+ Expect.equals('::', server.address.address);
server.listen((socket) {
socket.destroy();
server.close();
@@ -30,6 +33,8 @@
asyncStart();
InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
ServerSocket.bind(serverAddr.first, 0).then((server) {
+ Expect.equals('::0', server.address.host);
+ Expect.equals('::', server.address.address);
server.listen((socket) {
socket.destroy();
server.close();
@@ -46,6 +51,8 @@
asyncStart();
InternetAddress.lookup("::1", type: ANY).then((clientAddr) {
ServerSocket.bind("127.0.0.1", 0).then((server) {
+ Expect.equals('127.0.0.1', server.address.host);
+ Expect.equals('127.0.0.1', server.address.address);
server.listen((socket) {
throw "Unexpected socket";
});
@@ -60,6 +67,8 @@
void testIPv4toIPv4() {
asyncStart();
ServerSocket.bind("127.0.0.1", 0).then((server) {
+ Expect.equals('127.0.0.1', server.address.host);
+ Expect.equals('127.0.0.1', server.address.address);
server.listen((socket) {
socket.destroy();
server.close();
@@ -87,7 +96,7 @@
void testIPv4Lookup() {
asyncStart();
InternetAddress.lookup("127.0.0.1").then((list) {
- if (list.length < 0) throw "no addresse";
+ if (list.length < 0) throw "no address";
for (var entry in list) {
if (entry.type != InternetAddressType.IP_V4) {
throw "Wrong IP type";
@@ -104,7 +113,7 @@
ServerSocket.bind(serverAddr.first, 0, v6Only: true)
.then((server) {
server.listen((socket) {
- throw "Unexpcted socket";
+ throw "Unexpected socket";
});
Socket.connect("127.0.0.1", server.port).catchError((error) {
server.close();
diff --git a/tests/standalone/io/web_socket_error_test.dart b/tests/standalone/io/web_socket_error_test.dart
new file mode 100644
index 0000000..439ad1d
--- /dev/null
+++ b/tests/standalone/io/web_socket_error_test.dart
@@ -0,0 +1,106 @@
+// 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=
+// VMOptions=--short_socket_read
+// VMOptions=--short_socket_write
+// VMOptions=--short_socket_read --short_socket_write
+
+library dart.io;
+
+import "dart:async";
+import "dart:io";
+import "dart:math";
+import "dart:typed_data";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "package:path/path.dart";
+
+part "../../../sdk/lib/io/crypto.dart";
+
+
+const String webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+const String CERT_NAME = 'localhost_cert';
+const String HOST_NAME = 'localhost';
+
+/**
+ * A SecurityConfiguration lets us run the tests over HTTP or HTTPS.
+ */
+class SecurityConfiguration {
+ final bool secure;
+
+ SecurityConfiguration({bool this.secure});
+
+ Future<HttpServer> createServer({int backlog: 0}) =>
+ secure ? HttpServer.bindSecure(HOST_NAME,
+ 0,
+ backlog: backlog,
+ certificateName: CERT_NAME)
+ : HttpServer.bind(HOST_NAME,
+ 0,
+ backlog: backlog);
+
+ Future<WebSocket> createClient(int port) =>
+ WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
+
+
+ void testForceCloseServerEnd(int totalConnections) {
+ createServer().then((server) {
+ server.listen((request) {
+ var response = request.response;
+ response.statusCode = HttpStatus.SWITCHING_PROTOCOLS;
+ response.headers.set(HttpHeaders.CONNECTION, "upgrade");
+ response.headers.set(HttpHeaders.UPGRADE, "websocket");
+ String key = request.headers.value("Sec-WebSocket-Key");
+ _SHA1 sha1 = new _SHA1();
+ sha1.add("$key$webSocketGUID".codeUnits);
+ String accept = _CryptoUtils.bytesToBase64(sha1.close());
+ response.headers.add("Sec-WebSocket-Accept", accept);
+ response.headers.contentLength = 0;
+ response.detachSocket().then((socket) {
+ socket.destroy();
+ });
+ });
+
+ int closeCount = 0;
+ for (int i = 0; i < totalConnections; i++) {
+ createClient(server.port).then((webSocket) {
+ webSocket.add("Hello, world!");
+ webSocket.listen(
+ (message) {
+ Expect.fail("unexpected message");
+ },
+ onDone: () {
+ closeCount++;
+ if (closeCount == totalConnections) {
+ server.close();
+ }
+ });
+ });
+ }
+ });
+ }
+
+ void runTests() {
+ testForceCloseServerEnd(10);
+ }
+}
+
+
+void initializeSSL() {
+ var testPkcertDatabase = join(dirname(Platform.script), 'pkcert');
+ SecureSocket.initialize(database: testPkcertDatabase,
+ password: "dartdart");
+}
+
+
+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 30a2a3a..f778bf7 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -51,11 +51,7 @@
io/directory_non_ascii_test: Pass, Fail
io/process_non_ascii_test: Pass, Fail
-[ $runtime == vm ]
-io/http_server_early_client_close_test: Crash, Pass # Issue 12982
-io/secure_socket_bad_data_test: Crash, Pass # 12982
-
-[ $compiler == none && $runtime == drt ]
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
typed_data_isolate_test: Skip # This test uses dart:io
io/*: Skip # Don't run tests using dart:io in the browser
package/*: Skip # Do not run those in Dartium.
@@ -177,3 +173,8 @@
io/test_extension_fail_test: Fail
io/dart_std_io_pipe_test: Fail
io/file_read_special_device_test: Fail
+
+[ $compiler == none && $runtime == dartium ]
+assert_test: Fail # Issue 13719: Please triage this failure.
+javascript_int_overflow_literal_test/01: Fail # Issue 13719: Please triage this failure.
+javascript_int_overflow_test: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index f2e6744..ab84052 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -22,3 +22,8 @@
[ $compiler == none && $runtime == drt && $system == linux ]
png_layout_test: Fail # Issue 13540
+
+[ $compiler == none && $runtime == dartium ]
+dart2js_test: Skip # Uses dart:io.
+png_layout_test: Skip # dartium doesn't support layout tests
+txt_layout_test: Skip # dartium doesn't support layout tests
diff --git a/tools/VERSION b/tools/VERSION
index 7dc526d..0a86806 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
-MINOR 7
-BUILD 6
-PATCH 4
+MINOR 8
+BUILD 0
+PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index f4264ab..b64ed3e 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -20,6 +20,7 @@
import bot
+DARTIUM_BUILDER = r'none-dartium-(linux|mac|windows)'
DART2JS_BUILDER = (
r'dart2js-(linux|mac|windows)(-(jsshell))?-(debug|release)(-(checked|host-checked))?(-(host-checked))?(-(minified))?(-(x64))?-?(\d*)-?(\d*)')
WEB_BUILDER = (
@@ -45,6 +46,7 @@
dart2js_pattern = re.match(DART2JS_BUILDER, builder_name)
web_pattern = re.match(WEB_BUILDER, builder_name)
+ dartium_pattern = re.match(DARTIUM_BUILDER, builder_name)
if web_pattern:
compiler = 'dart2js'
@@ -81,6 +83,11 @@
arch = 'x64'
shard_index = dart2js_pattern.group(13)
total_shards = dart2js_pattern.group(14)
+ elif dartium_pattern:
+ compiler = 'none'
+ runtime = 'dartium'
+ mode = 'release'
+ system = dartium_pattern.group(1)
else :
return None
@@ -104,7 +111,8 @@
def NeedsXterm(compiler, runtime):
- return runtime in ['ie9', 'ie10', 'chrome', 'safari', 'opera', 'ff', 'drt']
+ return runtime in ['ie9', 'ie10', 'chrome', 'safari', 'opera', 'ff', 'drt',
+ 'dartium']
def TestStepName(name, flags):
@@ -117,9 +125,9 @@
# supported platforms.
def UseBrowserController(runtime, system):
supported_platforms = {
- 'linux': ['ff', 'chromeOnAndroid', 'chrome'],
- 'mac': ['safari', 'chrome'],
- 'windows': ['ie9', 'ie10', 'ff', 'chrome']
+ 'linux': ['ff', 'chromeOnAndroid', 'chrome', 'dartium'],
+ 'mac': ['safari', 'chrome', 'dartium'],
+ 'windows': ['ie9', 'ie10', 'ff', 'chrome', 'dartium']
}
# Platforms that we run on the fyi waterfall only.
fyi_supported_platforms = {
@@ -187,7 +195,8 @@
bot.RunProcess(cmd)
-def TestCompiler(runtime, mode, system, flags, is_buildbot, test_set, arch):
+def TestCompiler(runtime, mode, system, flags, is_buildbot, test_set, arch,
+ compiler=None):
""" test the compiler.
Args:
- runtime: either 'd8', 'jsshell', or one of the browsers, see GetBuildInfo
@@ -198,8 +207,12 @@
emulating one.
- test_set: Specification of a non standard test set, default None
- arch: The architecture to run on.
+ - compiler: The compiler to use for test.py (default is 'dart2js').
"""
+ if not compiler:
+ compiler = 'dart2js'
+
def GetPath(runtime):
""" Helper to get the path to the Chrome or Firefox executable for a
particular platform on the buildbot. Throws a KeyError if runtime is not
@@ -219,7 +232,8 @@
'Local', 'Google', 'Chrome', 'Application', 'chrome.exe')}
return path_dict[runtime]
- if (runtime == 'ff' or runtime == 'chrome') and is_buildbot:
+ if (compiler == 'dart2js' and (runtime == 'ff' or runtime == 'chrome')
+ and is_buildbot):
# Print out browser version numbers if we're running on the buildbot (where
# we know the paths to these browser installations).
version_query_string = '"%s" --version' % GetPath(runtime)
@@ -248,23 +262,26 @@
TestStep("dart2js_unit", mode, system, 'none', 'vm', ['dart2js'],
unit_test_flags, arch)
- if system == 'windows' and runtime == 'ie10':
- TestStep("dart2js", mode, system, 'dart2js', runtime, ['html'], flags, arch)
+ if compiler == 'dart2js' and system == 'windows' and runtime == 'ie10':
+ TestStep("%s-%s" % (compiler, runtime), mode, system, compiler, runtime,
+ ['html'], flags, arch)
else:
# Run the default set of test suites.
- TestStep("dart2js", mode, system, 'dart2js', runtime, [], flags, arch)
+ TestStep("%s-%s" % (compiler, runtime), mode, system, compiler,
+ runtime, [], flags, arch)
- # TODO(kasperl): Consider running peg and css tests too.
- extras = ['dart2js_extra', 'dart2js_native']
- extras_flags = flags
- if (system == 'linux'
- and runtime == 'd8'
- and not '--host-checked' in extras_flags):
- # Run the extra tests in checked mode, but only on linux/d8.
- # Other systems have less resources and tend to time out.
- extras_flags = extras_flags + ['--host-checked']
- TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras,
- extras_flags, arch)
+ if compiler == 'dart2js':
+ # TODO(kasperl): Consider running peg and css tests too.
+ extras = ['dart2js_extra', 'dart2js_native']
+ extras_flags = flags
+ if (system == 'linux'
+ and runtime == 'd8'
+ and not '--host-checked' in extras_flags):
+ # Run the extra tests in checked mode, but only on linux/d8.
+ # Other systems have less resources and tend to time out.
+ extras_flags = extras_flags + ['--host-checked']
+ TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras,
+ extras_flags, arch)
def _DeleteTempWebdriverProfiles(directory):
@@ -364,13 +381,14 @@
TestCompiler(build_info.runtime, build_info.mode, build_info.system,
list(test_flags), build_info.is_buildbot, build_info.test_set,
- build_info.arch)
+ build_info.arch, compiler=build_info.compiler)
# See comment in GetHasHardCodedCheckedMode, this is a hack.
if (GetHasHardCodedCheckedMode(build_info)):
TestCompiler(build_info.runtime, build_info.mode, build_info.system,
test_flags + ['--checked'], build_info.is_buildbot,
- build_info.test_set, build_info.arch)
+ build_info.test_set, build_info.arch,
+ compiler=build_info.compiler)
if build_info.runtime != 'd8':
CleanUpTemporaryFiles(build_info.system, build_info.runtime)
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 3bb58bc..ef81ebd 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -11,7 +11,8 @@
import monitored
import os
import re
-from htmlrenamer import html_interface_renames, typed_array_renames
+from htmlrenamer import custom_html_constructors, html_interface_renames, \
+ typed_array_renames
_pure_interfaces = monitored.Set('generator._pure_interfaces', [
# TODO(sra): DOMStringMap should be a class implementing Map<String,String>.
@@ -313,7 +314,8 @@
info.idl_args = idl_args
info.declared_name = name
info.name = name
- info.constructor_name = None
+ info.constructor_name = ('_' if interface.id in custom_html_constructors
+ else None)
info.js_name = name
info.type_name = interface.id
info.param_infos = _BuildArguments(idl_args, interface, constructor=True)
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 7b7ca8e..97fa1ba 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -11,9 +11,9 @@
DartDomNameOfAttribute, FindMatchingAttribute, \
TypeOrNothing, ConvertToFuture, GetCallbackInfo
from copy import deepcopy
-from htmlrenamer import convert_to_future_members, keep_overloaded_members, \
- private_html_members, dom_private_html_members, renamed_html_members, renamed_overloads, \
- removed_html_members
+from htmlrenamer import convert_to_future_members, custom_html_constructors, \
+ keep_overloaded_members, private_html_members, dom_private_html_members, renamed_html_members, \
+ renamed_overloads, removed_html_members
import logging
import monitored
import sys
@@ -598,7 +598,8 @@
if not self._members_emitter:
return
- if base_class != self.RootClassName():
+ if (base_class != self.RootClassName() and
+ self._interface.id not in custom_html_constructors):
self._members_emitter.Emit(
' // To suppress missing implicit constructor warnings.\n'
' factory $CLASSNAME._() { '
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 791591b..7f85044 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -161,6 +161,13 @@
'EventTarget.removeEventListener',
])
+# Classes where we have customized constructors, but we need to keep the old
+# constructor for dispatch purposes.
+custom_html_constructors = monitored.Set(
+ 'htmlrenamer.custom_html_constructors', [
+ 'HTMLOptionElement',
+])
+
# Members from the standard dom that should not be exposed publicly in dart:html
# but need to be exposed internally to implement dart:html on top of a standard
# browser. They are exposed simply by placing an underscore in front of the
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 7c5ec12..8c5aa83 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -593,6 +593,20 @@
self._backend.AddConstructors(
constructors, factory_provider, factory_constructor_name)
+ isElement = False
+ for parent in self._database.Hierarchy(self._interface):
+ if parent.id == 'Element':
+ isElement = True
+ if isElement and self._interface.id != 'Element':
+ self._implementation_members_emitter.Emit(
+ ' /**\n'
+ ' * Constructor instantiated by the DOM when a custom element has been created.\n'
+ ' *\n'
+ ' * This can only be called by subclasses from their created constructor.\n'
+ ' */\n'
+ ' $CLASSNAME.created() : super.created();\n',
+ CLASSNAME=self._interface_type_info.implementation_name())
+
self._backend.EmitSupportCheck()
merged_interface = self._interface_type_info.merged_interface()
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index 8dbe0e2..1235e80 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -551,7 +551,8 @@
[attr],
'void',
False,
- 'SetterRaisesException' in attr.ext_attrs)
+ 'SetterRaisesException' in attr.ext_attrs,
+ requires_custom_element_callback=True)
def AddIndexer(self, element_type):
"""Adds all the methods required to complete implementation of List."""
@@ -730,7 +731,8 @@
arguments,
return_type,
return_type_is_nullable,
- raises_dom_exception):
+ raises_dom_exception,
+ requires_custom_element_callback=False):
ext_attrs = node.ext_attrs
@@ -789,7 +791,7 @@
if 'Reflect' in ext_attrs:
cpp_arguments = [self._GenerateWebCoreReflectionAttributeName(node)]
- if ext_attrs.get('CustomElementCallbacks') == 'Enable':
+ if ext_attrs.get('CustomElementCallbacks') == 'Enable' or requires_custom_element_callback:
self._cpp_impl_includes.add('"core/dom/CustomElementCallbackDispatcher.h"')
needs_custom_element_callbacks = True
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart
index aa2c8f0..a3fa0bf 100644
--- a/tools/dom/src/dart2js_CustomElementSupport.dart
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart
@@ -5,7 +5,7 @@
part of dart.dom.html;
_callCreated(receiver) {
- return receiver.created();
+ return receiver.createdCallback();
}
_callEnteredView(receiver) {
@@ -15,6 +15,9 @@
_callLeftView(receiver) {
return receiver.leftView();
}
+ _callAttributeChanged(receiver, name, oldValue, newValue) {
+ return receiver.attributeChanged(name, oldValue, newValue);
+}
_makeCallbackMethod(callback) {
return JS('',
@@ -26,6 +29,16 @@
convertDartClosureToJS(callback, 1));
}
+_makeCallbackMethod3(callback) {
+ return JS('',
+ '''((function(invokeCallback) {
+ return function(arg1, arg2, arg3) {
+ return invokeCallback(this, arg1, arg2, arg3);
+ };
+ })(#))''',
+ convertDartClosureToJS(callback, 4));
+}
+
const _typeNameToTag = const {
'HTMLAnchorElement': 'a',
'HTMLAudioElement': 'audio',
@@ -91,6 +104,8 @@
JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
JS('void', '#.leftViewCallback = #', properties,
JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
+ JS('void', '#.attributeChangedCallback = #', properties,
+ JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));
// TODO(blois): Bug 13220- remove once transition is complete
JS('void', '#.enteredDocumentCallback = #', properties,
@@ -117,3 +132,8 @@
JS('void', '#.register(#, #)', document, tag, options);
}
+
+//// Called by Element.created to do validation & initialization.
+void _initializeCustomElement(Element e) {
+ // TODO(blois): Add validation that this is only in response to an upgrade.
+}
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index 8991ee1..2c82ddd 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -106,7 +106,6 @@
static window() native "Utils_window";
static forwardingPrint(String message) native "Utils_forwardingPrint";
- static void spawnDomFunction(Function f, int replyTo) native "Utils_spawnDomFunction";
static int _getNewIsolateId() native "Utils_getNewIsolateId";
// The following methods were added for debugger integration to make working
@@ -289,6 +288,10 @@
if (_isBuiltinType(cls)) {
throw new UnsupportedError("Invalid custom element from $libName.");
}
+ var className = MirrorSystem.getName(cls.simpleName);
+ if (!cls.constructors.containsKey(new Symbol('$className.created'))) {
+ throw new UnsupportedError('Class is missing constructor $className.created');
+ }
_register(document, tag, type, extendsTagName);
}
@@ -296,13 +299,8 @@
String extendsTagName) native "Utils_register";
static Element createElement(Document document, String tagName) native "Utils_createElement";
-}
-class _NPObject extends NativeFieldWrapperClass1 {
- _NPObject.internal();
- static _NPObject retrieve(String key) native "NPObject_retrieve";
- property(String propertyName) native "NPObject_property";
- invoke(String methodName, [List args = null]) native "NPObject_invoke";
+ static void initializeCustomElement(HtmlElement element) native "Utils_initializeCustomElement";
}
class _DOMWindowCrossFrame extends NativeFieldWrapperClass1 implements
@@ -366,79 +364,10 @@
bool get isNotEmpty => Maps.isNotEmpty(this);
}
-// TODO(vsm): Remove DOM isolate code. This is only used to support
-// printing and timers in background isolates. Background isolates
-// should just forward to the main DOM isolate instead of requiring a
-// special DOM isolate.
-
-_makeSendPortFuture(spawnRequest) {
- final completer = new Completer<SendPort>.sync();
- final port = new ReceivePort();
- port.receive((result, _) {
- completer.complete(result);
- port.close();
- });
- // TODO: SendPort.hashCode is ugly way to access port id.
- spawnRequest(port.toSendPort().hashCode);
- return completer.future;
-}
-
-Future<SendPort> _spawnDomFunction(Function f) =>
- _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); });
-
-final Future<SendPort> __HELPER_ISOLATE_PORT =
- _spawnDomFunction(_helperIsolateMain);
-
-// Tricky part.
-// Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then
-// and to delay Timer.run is used. However, Timer.run will try to register
-// another Timer and here we got stuck: event cannot be posted as then
-// callback is not executed because it's delayed with timer.
-// Therefore once future is resolved, it's unsafe to call .then on it
-// in Timer code.
-SendPort __SEND_PORT;
-
-_sendToHelperIsolate(msg, SendPort replyTo) {
- if (__SEND_PORT != null) {
- __SEND_PORT.send(msg, replyTo);
- } else {
- __HELPER_ISOLATE_PORT.then((port) {
- __SEND_PORT = port;
- __SEND_PORT.send(msg, replyTo);
- });
- }
-}
-
-final _TIMER_REGISTRY = new Map<SendPort, Timer>();
-
-const _NEW_TIMER = 'NEW_TIMER';
-const _CANCEL_TIMER = 'CANCEL_TIMER';
-const _TIMER_PING = 'TIMER_PING';
-const _PRINT = 'PRINT';
-
-_helperIsolateMain() {
- port.receive((msg, replyTo) {
- final cmd = msg[0];
- if (cmd == _NEW_TIMER) {
- final duration = new Duration(milliseconds: msg[1]);
- bool periodic = msg[2];
- ping() { replyTo.send(_TIMER_PING); };
- _TIMER_REGISTRY[replyTo] = periodic ?
- new Timer.periodic(duration, (_) { ping(); }) :
- new Timer(duration, ping);
- } else if (cmd == _CANCEL_TIMER) {
- _TIMER_REGISTRY.remove(replyTo).cancel();
- } else if (cmd == _PRINT) {
- final message = msg[1];
- // TODO(antonm): we need somehow identify those isolates.
- print('[From isolate] $message');
- }
- });
-}
-
final _printClosure = window.console.log;
final _pureIsolatePrintClosure = (s) {
- _sendToHelperIsolate([_PRINT, s], null);
+ throw new UnimplementedError("Printing from a background isolate "
+ "is not supported in the browser");
};
final _forwardingPrintClosure = _Utils.forwardingPrint;
@@ -477,43 +406,11 @@
return new _Timer(milliSeconds, callback, repeating);
};
-
-class _PureIsolateTimer implements Timer {
- bool _isActive = true;
- final ReceivePort _port = new ReceivePort();
- SendPort _sendPort; // Effectively final.
-
- static SendPort _SEND_PORT;
-
- _PureIsolateTimer(int milliSeconds, callback, repeating) {
- _sendPort = _port.toSendPort();
- _port.receive((msg, replyTo) {
- assert(msg == _TIMER_PING);
- _isActive = repeating;
- callback(this);
- if (!repeating) _cancel();
- });
-
- _send([_NEW_TIMER, milliSeconds, repeating]);
- }
-
- void cancel() {
- _cancel();
- _send([_CANCEL_TIMER]);
- }
-
- void _cancel() {
- _isActive = false;
- _port.close();
- }
-
- _send(msg) {
- _sendToHelperIsolate(msg, _sendPort);
- }
-
- bool get isActive => _isActive;
-}
-
get _pureIsolateTimerFactoryClosure =>
((int milliSeconds, void callback(Timer time), bool repeating) =>
- new _PureIsolateTimer(milliSeconds, callback, repeating));
+ throw new UnimplementedError("Timers on background isolates "
+ "are not supported in the browser"));
+
+void _initializeCustomElement(Element e) {
+ _Utils.initializeCustomElement(e);
+}
diff --git a/tools/dom/src/native_DOMPublic.dart b/tools/dom/src/native_DOMPublic.dart
deleted file mode 100644
index f38c63d..0000000
--- a/tools/dom/src/native_DOMPublic.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of html;
-
-// testRunner implementation.
-// FIXME: provide a separate lib for testRunner.
-
-var _testRunner;
-
-TestRunner get testRunner {
- if (_testRunner == null)
- _testRunner = new TestRunner._(_NPObject.retrieve("testRunner"));
- return _testRunner;
-}
-
-class TestRunner {
- final _NPObject _npObject;
-
- TestRunner._(this._npObject);
-
- display() => _npObject.invoke('display');
- dumpAsText() => _npObject.invoke('dumpAsText');
- notifyDone() => _npObject.invoke('notifyDone');
- setCanOpenWindows() => _npObject.invoke('setCanOpenWindows');
- waitUntilDone() => _npObject.invoke('waitUntilDone');
-}
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index bf62f8b..554ad3f 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -119,8 +119,20 @@
// Dart issue 1990.
class HtmlElement extends Element native "HTMLElement" {
factory HtmlElement() { throw new UnsupportedError("Not supported"); }
+
+ /**
+ * Constructor instantiated by the DOM when a custom element has been created.
+ *
+ * This can only be called by subclasses from their created constructor.
+ */
+ HtmlElement.created() : super.created();
}
+// EntryArray type was removed, so explicitly adding it to allow support for
+// older Chrome versions.
+// Issue #12573.
+abstract class _EntryArray implements List<Entry> native "EntryArray" {}
+
// Support for Send/ReceivePortSync.
int _getNewIsolateId() {
if (JS('bool', r'!window.$dart$isolate$counter')) {
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index cde3552..ca7cc03 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -81,7 +81,6 @@
part '$AUXILIARY_DIR/dartium_KeyEvent.dart';
part '$AUXILIARY_DIR/dartium_Platform.dart';
-part '$AUXILIARY_DIR/native_DOMPublic.dart';
part '$AUXILIARY_DIR/native_DOMImplementation.dart';
Window _window;
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index 7cc7f09..3e66c9c 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -9,7 +9,6 @@
{
$!MEMBERS
-
/**
* Finds all descendant elements of this document that match the specified
* group of selectors.
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 5732c1e..100e017 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -334,6 +334,30 @@
}
/**
+ * Custom element creation constructor.
+ *
+ * This constructor is used by the DOM when a custom element has been
+ * created. It can only be invoked by subclasses of Element from
+ * that classes created constructor.
+ *
+ * class CustomElement extends Element {
+ * factory CustomElement() => new Element.tag('x-custom');
+ *
+ * CustomElement.created() : super.created() {
+ * // Perform any element initialization.
+ * }
+ * }
+ * document.register('x-custom', CustomElement);
+ */
+ Element.created() : super._created() {
+ // Validate that this is a custom element & perform any additional
+ // initialization.
+ _initializeCustomElement(this);
+
+ createdCallback();
+ }
+
+ /**
* Creates the HTML element specified by the tag name.
*
* This is similar to [Document.createElement].
@@ -676,9 +700,12 @@
/**
* Called by the DOM when this element has been instantiated.
+ *
+ * Will be replaced by created constructor.
*/
@Experimental()
- void created() {}
+ @deprecated
+ void createdCallback() {}
/**
* Called by the DOM when this element has been inserted into the live
@@ -694,6 +721,11 @@
@Experimental()
void leftView() {}
+ /**
+ * Called by the DOM whenever an attribute on this has been changed.
+ */
+ void attributeChanged(String name, String oldValue, String newValue) {}
+
// Hooks to support custom WebComponents.
$if DART2JS
diff --git a/tools/dom/templates/html/impl/impl_EventTarget.darttemplate b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
index 60f8fcc..06b24fb 100644
--- a/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
+++ b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
@@ -60,6 +60,9 @@
*/
$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+ // Custom element created callback.
+ EventTarget._created();
+
/**
* This is an ease-of-use accessor for event streams which should only be
* used when an explicit accessor is not available.
diff --git a/tools/dom/templates/html/impl/impl_HTMLOptionElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLOptionElement.darttemplate
new file mode 100644
index 0000000..b40c7be
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_HTMLOptionElement.darttemplate
@@ -0,0 +1,13 @@
+// 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 $LIBRARYNAME;
+
+$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+ factory OptionElement({String data, String value, bool defaultSelected,
+ bool selected}) {
+ return new OptionElement._(data, value, defaultSelected, selected);
+ }
+$!MEMBERS
+}
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index 8f2fc4a..b93bbc7 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -201,6 +201,10 @@
$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+
+ // Custom element created callback.
+ Node._created() : super._created();
+
List<Node> get nodes {
return new _ChildNodeListLazy(this);
}
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 646d6c3..642ce56 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -87,7 +87,7 @@
}
/**
- * Creates a URL request for the specified [url].
+ * Creates and sends a URL request for the specified [url].
*
* By default `request` will perform an HTTP GET request, but a different
* method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
diff --git a/tools/full-coverage.dart b/tools/full-coverage.dart
new file mode 100644
index 0000000..b48da50
--- /dev/null
+++ b/tools/full-coverage.dart
@@ -0,0 +1,485 @@
+// 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:convert";
+import "dart:io";
+import "dart:isolate";
+import "dart:mirrors";
+
+import "package:args/args.dart";
+import "package:path/path.dart";
+
+/// [Environment] stores gathered arguments information.
+class Environment {
+ String sdkRoot;
+ String pkgRoot;
+ var input;
+ var output;
+ int workers;
+ bool prettyPrint;
+ bool lcov;
+ bool expectMarkers;
+ bool verbose;
+}
+
+/// [Resolver] resolves imports with respect to a given environment.
+class Resolver {
+ const DART_PREFIX = "dart:";
+ const PACKAGE_PREFIX = "package:";
+ const FILE_PREFIX = "file://";
+ const HTTP_PREFIX = "http://";
+
+ Map _env;
+ List failed = [];
+
+ Resolver(this._env);
+
+ /// Returns the absolute path wrt. to the given environment or null, if the
+ /// import could not be resolved.
+ resolve(String import) {
+ if (import.startsWith(DART_PREFIX)) {
+ var slashPos = import.indexOf("/");
+ var filePath;
+ if (slashPos != -1) {
+ var path = import.substring(DART_PREFIX.length, slashPos);
+ // Drop patch files, since we don't have their source in the compiled
+ // SDK.
+ if (path.endsWith("-patch")) {
+ failed.add(import);
+ return null;
+ }
+ // Canonicalize path. For instance: _collection-dev => _collection_dev.
+ path = path.replaceAll("-", "_");
+ filePath = "${_env["sdkRoot"]}"
+ "/${path}${import.substring(slashPos, import.length)}";
+ } else {
+ // Resolve 'dart:something' to be something/something.dart in the SDK.
+ var lib = import.substring(DART_PREFIX.length, import.length);
+ filePath = "${_env["sdkRoot"]}/${lib}/${lib}.dart";
+ }
+ return filePath;
+ }
+ if (import.startsWith(PACKAGE_PREFIX)) {
+ var filePath =
+ "${_env["pkgRoot"]}"
+ "/${import.substring(PACKAGE_PREFIX.length, import.length)}";
+ return filePath;
+ }
+ if (import.startsWith(FILE_PREFIX)) {
+ var filePath = fromUri(Uri.parse(import));
+ return filePath;
+ }
+ if (import.startsWith(HTTP_PREFIX)) {
+ return import;
+ }
+ // We cannot deal with anything else.
+ failed.add(import);
+ return null;
+ }
+}
+
+/// Converts the given hitmap to lcov format and appends the result to
+/// env.output.
+///
+/// Returns a [Future] that completes as soon as all map entries have been
+/// emitted.
+Future lcov(Map hitmap) {
+ var emitOne = (key) {
+ var v = hitmap[key];
+ StringBuffer entry = new StringBuffer();
+ entry.write("SF:${key}\n");
+ v.keys.toList()
+ ..sort()
+ ..forEach((k) {
+ entry.write("DA:${k},${v[k]}\n");
+ });
+ entry.write("end_of_record\n");
+ env.output.write(entry.toString());
+ return new Future.value(null);
+ };
+
+ return Future.forEach(hitmap.keys, emitOne);
+}
+
+/// Converts the given hitmap to a pretty-print format and appends the result
+/// to env.output.
+///
+/// Returns a [Future] that completes as soon as all map entries have been
+/// emitted.
+Future prettyPrint(Map hitMap, List failedLoads) {
+ var emitOne = (key) {
+ var v = hitMap[key];
+ var c = new Completer();
+ loadResource(key).then((lines) {
+ if (lines == null) {
+ failedLoads.add(key);
+ c.complete();
+ return;
+ }
+ env.output.write("${key}\n");
+ for (var line = 1; line <= lines.length; line++) {
+ String prefix = " ";
+ if (v.containsKey(line)) {
+ prefix = v[line].toString();
+ StringBuffer b = new StringBuffer();
+ for (int i = prefix.length; i < 7; i++) {
+ b.write(" ");
+ }
+ b.write(prefix);
+ prefix = b.toString();
+ }
+ env.output.write("${prefix}|${lines[line-1]}\n");
+ }
+ c.complete();
+ });
+ return c.future;
+ };
+
+ return Future.forEach(hitMap.keys, emitOne);
+}
+
+/// Load an import resource and return a [Future] with a [List] of its lines.
+/// Returns [null] instead of a list if the resource could not be loaded.
+Future<List> loadResource(String import) {
+ if (import.startsWith("http")) {
+ Completer c = new Completer();
+ HttpClient client = new HttpClient();
+ client.getUrl(Uri.parse(import))
+ .then((HttpClientRequest request) {
+ return request.close();
+ })
+ .then((HttpClientResponse response) {
+ response.transform(new StringDecoder()).toList().then((data) {
+ c.complete(data);
+ httpClient.close();
+ });
+ })
+ .catchError((e) {
+ c.complete(null);
+ });
+ return c.future;
+ } else {
+ File f = new File(import);
+ return f.readAsLines()
+ .catchError((e) {
+ return new Future.value(null);
+ });
+ }
+}
+
+/// Creates a single hitmap from a raw json object. Throws away all entries that
+/// are not resolvable.
+Map createHitmap(String rawJson, Resolver resolver) {
+ Map<String, Map<int,int>> hitMap = {};
+
+ addToMap(source, line, count) {
+ if (!hitMap[source].containsKey(line)) {
+ hitMap[source][line] = 0;
+ }
+ hitMap[source][line] += count;
+ }
+
+ JSON.decode(rawJson).forEach((Map e) {
+ String source = resolver.resolve(e["source"]);
+ if (source == null) {
+ // Couldnt resolve import, so skip this entry.
+ return;
+ }
+ if (!hitMap.containsKey(source)) {
+ hitMap[source] = {};
+ }
+ var hits = e["hits"];
+ // hits is a flat array of the following format:
+ // [ <line|linerange>, <hitcount>,...]
+ // line: number.
+ // linerange: "<line>-<line>".
+ for (var i = 0; i < hits.length; i += 2) {
+ var k = hits[i];
+ if (k is num) {
+ // Single line.
+ addToMap(source, k, hits[i+1]);
+ }
+ if (k is String) {
+ // Linerange. We expand line ranges to actual lines at this point.
+ var splitPos = k.indexOf("-");
+ int start = int.parse(k.substring(0, splitPos));
+ int end = int.parse(k.substring(splitPos + 1, k.length));
+ for (var j = start; j <= end; j++) {
+ addToMap(source, j, hits[i+1]);
+ }
+ }
+ }
+ });
+ return hitMap;
+}
+
+/// Merges [newMap] into [result].
+mergeHitmaps(Map newMap, Map result) {
+ newMap.forEach((String file, Map v) {
+ if (result.containsKey(file)) {
+ v.forEach((int line, int cnt) {
+ if (result[file][line] == null) {
+ result[file][line] = cnt;
+ } else {
+ result[file][line] += cnt;
+ }
+ });
+ } else {
+ result[file] = v;
+ }
+ });
+}
+
+/// Given an absolute path absPath, this function returns a [List] of files
+/// are contained by it if it is a directory, or a [List] containing the file if
+/// it is a file.
+List filesToProcess(String absPath) {
+ if (FileSystemEntity.isDirectorySync(absPath)) {
+ Directory d = new Directory(absPath);
+ List files = [];
+ d.listSync(recursive: true).forEach((FileSystemEntity entity) {
+ if (entity is File) {
+ files.add(entity as File);
+ }
+ });
+ return files;
+ } else if (FileSystemEntity.isFileSync(absPath)) {
+ return [ new File(absPath) ];
+ }
+}
+
+worker() {
+ final start = new DateTime.now().millisecondsSinceEpoch;
+ String me = currentMirrorSystem().isolate.debugName;
+
+ port.receive((Message message, reply) {
+ if (message.type == Message.SHUTDOWN) {
+ port.close();
+ }
+
+ if (message.type == Message.WORK) {
+ var env = message.payload[0];
+ List files = message.payload[1];
+ Resolver resolver = new Resolver(env);
+ var workerHitmap = {};
+ files.forEach((File fileEntry) {
+ // Read file sync, as it only contains 1 object.
+ String contents = fileEntry.readAsStringSync();
+ if (contents.length > 0) {
+ mergeHitmaps(createHitmap(contents, resolver), workerHitmap);
+ }
+ });
+ if (env["verbose"]) {
+ final end = new DateTime.now().millisecondsSinceEpoch;
+ print("worker[${me}]: Finished processing files. "
+ "Took ${end - start} ms.");
+ }
+ reply.send(new Message(Message.RESULT, [workerHitmap, resolver.failed]));
+ }
+
+ });
+}
+
+class Message {
+ static const int SHUTDOWN = 1;
+ static const int RESULT = 2;
+ static const int WORK = 3;
+
+ final int type;
+ final payload;
+
+ Message(this.type, this.payload);
+}
+
+final env = new Environment();
+
+main() {
+ parseArgs();
+
+ List files = filesToProcess(env.input);
+ int filesPerWorker = files.length ~/ env.workers;
+ List workerPorts = [];
+ int doneCnt = 0;
+
+ List failedResolves = [];
+ List failedLoads = [];
+ Map globalHitmap = {};
+ int start = new DateTime.now().millisecondsSinceEpoch;
+
+ if (env.verbose) {
+ print("Environment:");
+ print(" # files: ${files.length}");
+ print(" # workers: ${env.workers}");
+ print(" sdk-root: ${env.sdkRoot}");
+ print(" package-root: ${env.pkgRoot}");
+ }
+
+ port.receive((Message message, reply) {
+ if (message.type == Message.RESULT) {
+ mergeHitmaps(message.payload[0], globalHitmap);
+ failedResolves.addAll(message.payload[1]);
+ doneCnt++;
+ }
+
+ // All workers are done. Process the data.
+ if (doneCnt == env.workers) {
+ workerPorts.forEach((p) => p.send(new Message(Message.SHUTDOWN, null)));
+ if (env.verbose) {
+ final end = new DateTime.now().millisecondsSinceEpoch;
+ print("Done creating a global hitmap. Took ${end - start} ms.");
+ }
+
+ Future out;
+ if (env.prettyPrint) {
+ out = prettyPrint(globalHitmap, failedLoads);
+ }
+ if (env.lcov) {
+ out = lcov(globalHitmap);
+ }
+
+ out.then((_) {
+ env.output.close().then((_) {
+ if (env.verbose) {
+ final end = new DateTime.now().millisecondsSinceEpoch;
+ print("Done flushing output. Took ${end - start} ms.");
+ }
+ });
+ port.close();
+
+ if (env.verbose) {
+ if (failedResolves.length > 0) {
+ print("Failed to resolve:");
+ failedResolves.toSet().forEach((e) {
+ print(" ${e}");
+ });
+ }
+ if (failedLoads.length > 0) {
+ print("Failed to load:");
+ failedLoads.toSet().forEach((e) {
+ print(" ${e}");
+ });
+ }
+ }
+
+ });
+ }
+ });
+
+ Map sharedEnv = {
+ "sdkRoot": env.sdkRoot,
+ "pkgRoot": env.pkgRoot,
+ "verbose": env.verbose,
+ };
+
+ // Create workers.
+ for (var i = 1; i < env.workers; i++) {
+ var p = spawnFunction(worker);
+ workerPorts.add(p);
+ var start = files.length - filesPerWorker;
+ var end = files.length;
+ var workerFiles = files.getRange(start, end).toList();
+ files.removeRange(start, end);
+ p.send(new Message(Message.WORK, [sharedEnv, workerFiles]), port);
+ }
+ // Let the last worker deal with the rest of the files (which should be only
+ // off by at max (#workers - 1).
+ var p = spawnFunction(worker);
+ workerPorts.add(p);
+ p.send(new Message(Message.WORK, [sharedEnv, files]), port);
+
+ return 0;
+}
+
+/// Checks the validity of the provided arguments. Does not initialize actual
+/// processing.
+parseArgs() {
+ var parser = new ArgParser();
+
+ parser.addOption("sdk-root", abbr: "s",
+ help: "path to the SDK root");
+ parser.addOption("package-root", abbr: "p",
+ help: "path to the package root",
+ defaultsTo: ".");
+ parser.addOption("in", abbr: "i",
+ help: "input(s): may be file or directory",
+ defaultsTo: "stdin");
+ parser.addOption("out", abbr: "o",
+ help: "output: may be file or stdout",
+ defaultsTo: "stdout");
+ parser.addOption("workers", abbr: "j",
+ help: "number of workers",
+ defaultsTo: "1");
+ parser.addFlag("pretty-print", abbr: "r",
+ help: "convert coverage data to pretty print format",
+ negatable: false);
+ parser.addFlag("lcov", abbr :"l",
+ help: "convert coverage data to lcov format",
+ negatable: false);
+ parser.addFlag("verbose", abbr :"v",
+ help: "verbose output",
+ negatable: false);
+ parser.addFlag("help", abbr: "h",
+ help: "show this help",
+ negatable: false);
+
+ var args = parser.parse(new Options().arguments);
+
+ if (args["help"]) {
+ print("Usage: coverage [OPTION...]\n");
+ print(parser.getUsage());
+ exit(0);
+ }
+
+ if (args["sdk-root"] == null) {
+ if (Platform.environment.containsKey("SDK_ROOT")) {
+ env.sdkRoot =
+ join(absolute(normalize(Platform.environment["SDK_ROOT"])), "lib");
+ } else {
+ throw "No SDK root found, please specify one using --sdk-root.";
+ }
+ } else {
+ env.sdkRoot = join(absolute(normalize(args["sdk-root"])), "lib");
+ }
+ if (!FileSystemEntity.isDirectorySync(env.sdkRoot)) {
+ throw "Provided SDK root ${args["sdk-root"]} is not a valid SDK "
+ "top-level directory";
+ }
+
+ if (args["package-root"] == null) {
+ env.pkgRoot = absolute(normalize("./packages"));
+ } else {
+ env.pkgRoot = absolute(normalize(args["package-root"]));
+ if (!FileSystemEntity.isDirectorySync(env.pkgRoot)) {
+ throw "Provided package root ${args["package-root"]} is not directory.";
+ }
+ }
+
+ if (args["in"] == "stdin") {
+ env.input = "stdin";
+ } else {
+ env.input = absolute(normalize(args["in"]));
+ if (!FileSystemEntity.isDirectorySync(env.input) &&
+ !FileSystemEntity.isFileSync(env.input)) {
+ throw "Provided input ${args["in"]} is neither a directory, nor a file.";
+ }
+ }
+
+ if (args["out"] == "stdout") {
+ env.output = stdout;
+ } else {
+ env.output = absolute(normalize(args["out"]));
+ env.output = new File(env.output).openWrite();
+ }
+
+ if (args["pretty-print"] &&
+ args["lcov"]) {
+ throw "Choose either pretty-print or lcov output";
+ }
+
+ env.prettyPrint = args["pretty-print"];
+ env.lcov = args["lcov"];
+ env.verbose = args["verbose"];
+ env.workers = int.parse("${args["workers"]}");
+}
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index f370863..b8727ea 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -53,6 +53,8 @@
return new Firefox();
} else if (name == 'chrome') {
return new Chrome();
+ } else if (name == 'dartium') {
+ return new Dartium();
} else if (name == 'safari') {
return new Safari();
} else if (name.startsWith('ie')) {
@@ -63,7 +65,7 @@
}
static const List<String> SUPPORTED_BROWSERS =
- const ['safari', 'ff', 'firefox', 'chrome', 'ie9', 'ie10'];
+ const ['safari', 'ff', 'firefox', 'chrome', 'ie9', 'ie10', 'dartium'];
static const List<String> BROWSERS_WITH_WINDOW_SUPPORT =
const ['safari', 'ff', 'firefox', 'chrome'];
@@ -109,8 +111,11 @@
* Start the browser using the supplied argument.
* This sets up the error handling and usage logging.
*/
- Future<bool> startBrowser(String command, List<String> arguments) {
- return Process.start(command, arguments).then((startedProcess) {
+ Future<bool> startBrowser(String command,
+ List<String> arguments,
+ {Map<String,String> environment}) {
+ return Process.start(command, arguments, environment: environment)
+ .then((startedProcess) {
process = startedProcess;
// Used to notify when exiting, and as a return value on calls to
// close().
@@ -316,24 +321,25 @@
class Chrome extends Browser {
- static String _binary = _getBinary();
-
+ String _binary;
String _version = "Version not found yet";
- // This is extracted to a function since we may need to support several
- // locations.
- static String _getWindowsBinary() {
- return "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe";
+ Chrome() {
+ _binary = _getBinary();
}
- static String _getBinary() {
- if (Platform.isWindows) return _getWindowsBinary();
- if (Platform.isMacOS) {
+ String _getBinary() {
+ if (Platform.isWindows) {
+ return "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe";
+ } else if (Platform.isMacOS) {
return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
}
- if (Platform.isLinux) return 'google-chrome';
+ assert(Platform.isLinux);
+ return 'google-chrome';
}
+ Map<String, String> _getEnvironment() => null;
+
Future<bool> _getVersion() {
if (Platform.isWindows) {
// The version flag does not work on windows.
@@ -375,7 +381,7 @@
var args = ["--user-data-dir=${userDir.path}", url,
"--disable-extensions", "--disable-popup-blocking",
"--bwsi", "--no-first-run"];
- return startBrowser(_binary, args);
+ return startBrowser(_binary, args, environment: _getEnvironment());
});
}).catchError((e) {
_logEvent("Running $_binary --version failed with $e");
@@ -386,6 +392,27 @@
String toString() => "Chrome";
}
+class Dartium extends Chrome {
+ String _getBinary() {
+ if (Platform.operatingSystem == 'macos') {
+ return new Path('client/tests/dartium/Chromium.app/Contents/'
+ 'MacOS/Chromium').toNativePath();
+ }
+ return new Path('client/tests/dartium/chrome').toNativePath();
+ }
+
+ Map<String, String> _getEnvironment() {
+ var environment = new Map<String,String>.from(Platform.environment);
+ // By setting this environment variable, dartium will forward "print()"
+ // calls in dart to the top-level javascript function "dartPrint()" if
+ // available.
+ environment['DART_FORWARDING_PRINT'] = '1';
+ return environment;
+ }
+
+ String toString() => "Dartium";
+}
+
class IE extends Browser {
static const String binary =
@@ -619,7 +646,7 @@
// If we do we need to provide developers with this information.
// We don't add urls to the cache until we have run it.
Map<int, String> testCache = new Map<int, String>();
- List<int> doubleReportingTests = new List<int>();
+ Map<int, String> doubleReportingOutputs = new Map<int, String>();
BrowserTestingServer testingServer;
@@ -696,7 +723,7 @@
void handleResults(String browserId, String output, int testId) {
var status = browserStatus[browserId];
if (testCache.containsKey(testId)) {
- doubleReportingTests.add(testId);
+ doubleReportingOutputs[testId] = output;
return;
}
@@ -831,15 +858,23 @@
}
void printDoubleReportingTests() {
- if (doubleReportingTests.length == 0) return;
+ if (doubleReportingOutputs.length == 0) return;
// TODO(ricow): die on double reporting.
// Currently we just report this here, we could have a callback to the
// encapsulating environment.
print("");
print("Double reporting tests");
- for (var id in doubleReportingTests) {
+ for (var id in doubleReportingOutputs.keys) {
print(" ${testCache[id]}");
}
+
+ DebugLogger.warning("Double reporting tests:");
+ for (var id in doubleReportingOutputs.keys) {
+ DebugLogger.warning("${testCache[id]}, output: ");
+ DebugLogger.warning("${doubleReportingOutputs[id]}");
+ DebugLogger.warning("");
+ DebugLogger.warning("");
+ }
}
Future<bool> terminate() {
diff --git a/tools/testing/dart/browser_test.dart b/tools/testing/dart/browser_test.dart
index dbfd7e5..e37d029 100644
--- a/tools/testing/dart/browser_test.dart
+++ b/tools/testing/dart/browser_test.dart
@@ -55,7 +55,7 @@
</html>
""";
-String dartTestWrapper(bool usePackageImport, String libraryPathComponent) {
+String dartUnittestWrapper(bool usePackageImport, String libraryPathComponent) {
// Tests inside "pkg" import unittest using "package:". All others use a
// relative path. The imports need to agree, so use a matching form here.
var unitTest;
@@ -77,3 +77,15 @@
}
""";
}
+
+String dartTestWrapper(String libraryPathComponent) {
+ return """
+import '$libraryPathComponent' as test;
+
+main() {
+ print("dart-calling-main");
+ test.main();
+ print("dart-main-done");
+}
+""";
+}
\ No newline at end of file
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index dd92951..db7a6b1 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -41,6 +41,8 @@
'--minified'],
const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
'--checked'],
+ const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk',
+ '--use_browser_controller', '--write-debug-log'],
];
void main() {
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index dc0f5ff..38d45a7 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -452,7 +452,7 @@
Set<String> _blacklistedOptions = new Set<String>.from([
'progress', 'failure-summary', 'step_name', 'report', 'tasks', 'verbose',
'time', 'dart', 'drt', 'dartium', 'build_directory', 'append_logs',
- 'write_debug_log', 'local_ip', 'shard', 'shards',
+ 'local_ip', 'shard', 'shards',
]);
List<String> _constructReproducingCommandArguments(Map config) {
@@ -676,7 +676,7 @@
if (configuration['mode'] == 'debug') {
timeout *= 2;
}
- if (const ['drt', 'dartium'].contains(configuration['runtime'])) {
+ if (const ['drt'].contains(configuration['runtime'])) {
timeout *= 4; // Allow additional time for browser testing to run.
}
break;
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index b93c3de..0a2e31f 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -1154,14 +1154,6 @@
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) {
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index e98f6f1..64a495f 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -712,6 +712,7 @@
enqueueStandardTest(info, testName, expectations);
} else if (TestUtils.isBrowserRuntime(configuration['runtime'])) {
bool isWrappingRequired = configuration['compiler'] != 'dart2js';
+
if (info.optionsFromFile['isMultiHtmlTest']) {
// A browser multi-test has multiple expectations for one test file.
// Find all the different sub-test expecations for one entire test file.
@@ -917,14 +918,25 @@
return url;
}
- void _createWrapperFile(String dartWrapperFilename, dartLibraryFilename) {
+ void _createWrapperFile(String dartWrapperFilename,
+ Path dartLibraryFilename,
+ {bool useUnittestWrapper: false}) {
File file = new File(dartWrapperFilename);
RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE);
var usePackageImport = dartLibraryFilename.segments().contains("pkg");
var libraryPathComponent = _createUrlPathFromFile(dartLibraryFilename);
- dartWrapper.writeStringSync(dartTestWrapper(usePackageImport,
- libraryPathComponent));
+ var generatedSource;
+ if (useUnittestWrapper) {
+ // FIXME(kustermann): This is broken, we can't do unittest-based wrapping
+ // of tests (e.g. async operations are not wrapped in expectAsync()).
+ generatedSource = dartUnittestWrapper(usePackageImport,
+ libraryPathComponent);
+ } else {
+ generatedSource = dartTestWrapper(libraryPathComponent);
+ }
+
+ dartWrapper.writeStringSync(generatedSource);
dartWrapper.closeSync();
}
@@ -987,7 +999,6 @@
// Use existing HTML document if available.
String htmlPath;
if (customHtml.existsSync()) {
-
// If necessary, run the Polymer deploy steps.
// TODO(jmesserly): this should be generalized for any tests that
// require Pub deploy, not just polymer.
@@ -1028,7 +1039,13 @@
htmlPath = '$tempDir/test.html';
if (isWrappingRequired && !isWebTest) {
// test.dart will import the dart test.
- _createWrapperFile(dartWrapperFilename, filePath);
+ if (configuration['use_browser_controller'] &&
+ configuration['runtime'] == 'dartium') {
+ _createWrapperFile(dartWrapperFilename, filePath);
+ } else {
+ _createWrapperFile(
+ dartWrapperFilename, filePath, useUnittestWrapper: true);
+ }
} else {
dartWrapperFilename = filename;
}
diff --git a/utils/peg/pegparser.dart b/utils/peg/pegparser.dart
index ba1526b..8666550 100644
--- a/utils/peg/pegparser.dart
+++ b/utils/peg/pegparser.dart
@@ -2,7 +2,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.
-library Peg Parser;
+library PegParser;
/*
* The following functions are combinators for building Rules.
@@ -62,7 +62,7 @@
// Find the range of character codes and construct an array of flags for codes
// within the range.
- List<int> codes = characters.codeUnits;
+ List<int> codes = characters.codeUnits.toList();
codes.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
int lo = codes[0];
int hi = codes[codes.length - 1];
@@ -165,7 +165,7 @@
* MANY is a value generating matcher. The value is a list of the matches of
* [rule]. The list may be empty if [:min == 0:].
*/
-_Rule MANY(rule, [separator = null, int min = 1]) {
+_Rule MANY(rule, {separator: null, int min: 1}) {
assert(0 <= min && min <= 1);
return new _RepeatRule(_compile(rule), _compileOptional(separator), min);
}
@@ -274,7 +274,7 @@
tokens.sort((a, b) =>
a.startsWith("'") == b.startsWith("'")
? a.compareTo(b)
- : a.startsWith("'") ? +1 : -1);
+ : a.startsWith("'") ? 1 : -1);
var expected = tokens.join(' or ');
var found = state.max_pos == state._end ? 'end of file'
: "'${state._text[state.max_pos]}'";
@@ -314,7 +314,7 @@
class _ParserState {
- _ParserState(this._text, [_Rule whitespace = null]) {
+ _ParserState(this._text, {_Rule whitespace}) {
_end = this._text.length;
whitespaceRule = whitespace;
max_rule = [];
diff --git a/utils/tests/peg/peg_test.dart b/utils/tests/peg/peg_test.dart
index 692dc15..b48453b 100644
--- a/utils/tests/peg/peg_test.dart
+++ b/utils/tests/peg/peg_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
library peg_tests;
+import 'dart:core' hide Symbol;
import '../../peg/pegparser.dart';
testParens() {
@@ -144,7 +145,7 @@
['(', expression, ')', (e) => e]
]);
- var postfixes = OR([['(', MANY(assignment_e, ',', 0), ')', binary('apply')],
+ var postfixes = OR([['(', MANY(assignment_e, separator: ',', min: 0), ')', binary('apply')],
['++', unary('postinc')],
['--', unary('postdec')],
['.', id, binary('field')],
@@ -295,7 +296,7 @@
if (exception is ParseError)
ast = exception;
else
- throw;
+ rethrow;
}
print('${printList(ast)}');
}
@@ -315,7 +316,13 @@
if (expected is String)
formatted = printList(ast);
- Expect.equals(expected, formatted, "parse: $input");
+ //Expect.equals(expected, formatted, "parse: $input");
+ if (expected != formatted) {
+ throw new ArgumentError(
+ "parse: $input"
+ "\n expected: $expected"
+ "\n found: $formatted");
+ }
}
// Prints the list in [1,2,3] notation, including nested lists.