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);
-